数据结构和算法
算法: 解决问题的思想思路
输入项,输出项,确定性,可行性,有穷性
基本运算数量 描述 时间复杂度
基本类型的存储方式---数据结构 python内置数据结构如列表,字典,集合,元组
顺序表:(python中的list和tuple)
表头+数据区 -->表头有容量和元素数量
两种形式:
1:表头和数据区连续存储(一体式),
2:表头和数据区分开存储,表头多一个数据区存储地址
考虑动态数据的变化,通常使用分离式。
采用一体式时,当存储容量不够时,将开启新的内存空间,将表头和数据迁移;
采用分离式,将数据区迁移,然后将表头的数据区地址更改
数据区的扩充:固定容量扩充;翻倍扩充
基本类型连续存储在内存中,可以物理地址查询,例如一个整形存储需要4个字节,
第一个数据的物理地址为l,接下来的第n个数据的物理地址为l+n*4
顺序表基本布局:
将数据存储在内存中,但只能存储同样数据类型
顺序表元素外置:
将地址存储在内存中,可以存储不同的数据类型
链表:
将元素存放在通过链接构造起来的一系列存储块中;
有数据区和链接区,链接区保存下一个数据的地址;
单向链表的创建:
#节点的创建:
class Node(object):
def __init__(self,elem):
self.elem = elem
self.next = None
#链的创建:
class LinkList(object):
def __init__(self,node=None):
self.__head = node
def is_empty(self):
return self.__head == None
def length(self):
cur = self.__head
count = 0
while cur != None:
conut += 1
cur = cur.next
return count
def travel(self):
cur = self.__head
while cur != None:
print(cur.elem)
cur = cur.next
def add(self,item):
node = Node(elem)
node.next = self.__head
self.__head = node
def insert(self,pos,item):
if pos<=0:
self.add(item)
elif pos > (self.length()-1):
self.append(item)
else:
cur = self.__head
node = Node(elem)
conut = 0
while count < (pos-1):
cur = cur.next
conut += 1
node.next = cur.next
cur.next = node
def append(self,item):
node = Node(elem)
if self.is_empty():
self.__head = node
else:
cur = self.__head
while cur.next != None:
cur = cur.next
cur.next = node
def remove(self,item):
cur = self.__head
pre = None
while cur != None:
if cur.elem == item:
if cur == self.__head:
self.__head = cur.next
else:
pre.next = cur.next
break
else:
pre = cur
cur = cur.next
def search(item):
cur = self.__head
while cur != None:
if cur.elem == item:
return True
else:
cur = cur.next
return False
双向链表的创建:
#节点的创建:
class Node(object):
def __init__(self,elem):
self.elem = elem
self.next = None
self.prev = None
#链的创建:
class LinkList(object):
def __init__(self,node=None):
self.__head = node
def is_empty(self):
return self.__head is None
def length(self):
cur = self.__head
count = 0
while cur != None:
conut += 1
cur = cur.next
return count
def travel(self):
cur = self.__head
while cur != None:
print(cur.elem)
cur = cur.next
def add(self,item):
node = Node(elem)
if self.is_empty():
self.__head = node
else:
node.next = self.__head
self.__head.prev = node
self.__head = node
def insert(self,pos,item):
if pos<=0:
self.add(item)
elif pos > (self.length()-1):
self.append(item)
else:
cur = self.__head
node = Node(elem)
conut = 0
while count < (pos-1):
cur = cur.next
conut += 1
node.next = cur.next
node.prev = cur
cur.next.prev = node
cur.next = node
def append(self,item):
node = Node(elem)
if self.is_empty():
self.__head = node
else:
cur = self.__head
while cur.next != None:
cur = cur.next
cur.next = node
node.prev = cur
def remove(self,item):
cur = self.__head
while cur != None:
if cur.elem == item:
if cur == self.__head:
self.__head = cur.next
if cur.next:
cur.next.prev = None
else:
cur.next.prev = cur.prev
if cur.next:
cur.prev.next = cur.next
break
else:
cur = cur.next
def search(item):
cur = self.__head
while cur != None:
if cur.elem == item:
return True
else:
cur = cur.next
return False
单向循环链表的创建:
#节点的创建:
class Node(object):
def __init__(self,elem):
self.elem = elem
self.next = None
#链的创建:
class LinkList(object):
def __init__(self,node=None):
self.__head = node
def is_empty(self):
return self.__head is None
def length(self):
if self.is_empty():
return 0
else:
cur = self.__head
count = 1
while cur.next != self.__head:
conut += 1
cur = cur.next
return count
def travel(self):
if self.is_empty():
return
else:
cur = self.__head
while cur.next != self.__head:
print(cur.elem)
cur = cur.next
print(cur.item)
def add(self,item):
node = Node(elem)
if self.is_empty():
self.__head = node
node.next = node
else:
cur = self.__head
while cur.next != self.__head:
cur = cur.next
node.next = self.__head
self.__head = node
cur.next = node
node.next = self.__head
self.__head = node
def insert(self,pos,item):
if pos<=0:
self.add(item)
elif pos > (self.length()-1):
self.append(item)
else:
cur = self.__head
node = Node(elem)
conut = 0
while count < (pos-1):
cur = cur.next
conut += 1
node.next = cur.next
cur.next = node
def append(self,item):
node = Node(elem)
if self.is_empty():
self.__head = node
node.next = node
else:
cur = self.__head
while cur.next != None:
cur = cur.next
cur.next = node
node.next = self.__head
def remove(self,item):
if self.is_empty():
return
else:
cur = self.__head
pre = None
while cur.next != None:
if cur.elem == item:
if cur == self.__head:
r = self.__head
while r.next != self.__head:
r = r.next
self.__head = cur.next
r.next = self.__head
else:
pre.next = cur.next
break
else:
pre = cur
cur = cur.next
if cur.elem == item:
if cur == self.__head:
self.__head = None
else:
pre.next = self.__head
def search(item):
cur = self.__head
while cur.next != None:
if cur.elem == item:
return True
else:
cur = cur.next
if cur.elem == item:
return True
return False
栈:
#顺序表实现栈:
class Stack(object):
def __init__(self):
self.__list = []
def push(self,item):
self.__list.append(item)
def pop(self):
return self.__list.pop()
def is_empty(self):
return self.__list == []
def size(self):
return len(self.__list)
def peek(self):
return self.__list[-1]
#链表实现栈
class Node(object):
def __init__(self,item):
self.item = item
self.next = None
class SingleLink(object):
def __init__(self,node=None):
self.__head = node
def is_empty(self):
return self.__head == None
def length(self):
if self.is_empty():
return 0
else:
cur = self.__head
count = 0
while cur != None:
conut+= 1
cur = cur.next
return count
def append(self,item):
node = Node(item)
if self.is_empty():
self.__head = node
else:
cur = self.__head
while cur.next != None:
cur = cur.next
cur.next = node
def display(self):
cur = self.__head
pre = None
while cur != None:
pre = cur
cur = cur.next
return pre.item
def remove(self):
if self.is_empty():
return
else:
cur = self.__head
pre = None
while cur.next != None:
pre = cur
cur = cur.next
if cur == self.__head:
self.__head = None
return cur.item
else:
pre.next = None
return cur.item
class Stack(object):
def __init__(self):
self.__item = SingleLink()
def push(self,item):
self.__item.append(item)
def pop(self):
return self.__item.remove()
def is_empty(self):
return self.__item.is_empty()
def size(self):
return self.__item.length()
def peek(self):
return self.__item.display()
if __name__ == '__main__':
队列:
Quque
操作:
Queue() 创建一个空的队列
enqueue(item) 往队列中添加一个item元素
dequeue() 从队列头部删除一个元素
is_empty() 判断一个队列是否为空
size() 返回队列的大小
#顺序表实现
#链表实现
双端队列(deque,全名double-ended queue),是一种具有队列和栈的性质的数据结构。
双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。双端队列可以在队列任意一端入队和出队。
deque
操作:
Deque() 创建一个空的双端队列
add_front(item) 从队头加入一个item元素
add_rear(item) 从队尾加入一个item元素
remove_front() 从队头删除一个item元素
remove_rear() 从队尾删除一个item元素
is_empty() 判断双端队列是否为空
size() 返回队列的大小
排序算法
#采用顺序表
冒泡排序:
def bubble_sort(alist):
n = len(alist)
for j in range(n-1):
#count = 0 优化;表示遍历一次发现没有任何可以交换的元素,排序结束
for i in range(n-1-j):
if alist[i] > alist[i+1]:
alist[i],alist[i+1] = alist[i+1],alist[i]
count += 1
#if count == 0:
#return
选择排序:
def select_sort(alist):
n = len(alist)
for j in range(n-1):
min_index = j
for i in range(j+1,n):
if alist[min_index] > alist[i]:
min_index = i
alist[min_index],alist[j] = alist[j],alist[min_index]
插入排序:
def insert_sort(alist):
n = len(alist)
for j in range(1,n):
i = j
while i>0:
if alist[i] < alist[i-1]:
alist[i], alist[i-1] = alist[i-1], alist[i]
i-= 1
else:
break
希尔排序:
def shell_sort(alist):
n = len(alist)
gap = n//2
while gap>0:
for j in range(gap,n):
i = j
while i>0:
if alist[i] < alist[i-gap]:
alist[i], alist[i-gap] = alist[i-gap],alist[i]
i -= gap
else:
break
gap = gap//2
快速排序:
def quick_sort(alist,start,end):
if start>=end:
return
index = alist[start]
low = start
high = end
while low<high:
while low<high and alist[high]>index:
high-=1
alist[low] = alist[high]
while low<high and alist[low]<=index:
low+=1
alist[high] = alist[low]
alist[low] = index
quick_sort(alist,start,low-1)
quick_sort(alist,low+1,end)
归并排序:
*****
搜索:
二分查找:
1#递归版
def binary_search(alist,item):
n = len(alist)
if n > 0:
mid = n//2
if alist[mid] == item:
return True
elif alist[mid]>item:
return binary_search(alist[:mid],item)
else:
return binary_search(alist[mid+1:],item)
return False
2#非递归版
def binary_search(alist,item):
n = len(alist)
first = 0
last = n-1
mid = (first+last)//2
while first <= last:
if alist[mid] == item:
return True
elif alist[mid] > item:
last = mid-1
else:
first = mid+1
return False
二叉树:
插入:
class Node(object):
def __init__(self,item):
self.elem = item
self.lchild = None
self.rchild = None
class Tree(object):
def __init__(self):
self.root = None
def add(self,item):
node = Node(item)
if self.root = None:
self.root = node
return
queue = [self.root]
while queue:
cur_node = queue.pop(0)
if cur_node.lchild is None:
cur_node.lchild = node
return
else:
queue.append(cur_node.lchild)
if cur_node.rchild is None:
cur_node.rchild = node
return
else:
queue.append(cur_node.rchild)
def breadth_travel(self):
#广度遍历
if self.root is None:
return
queue = [self.root]
while queue:
cur_node = queue.pop(0)
print(cur_node.elem)
if not cur_node.lchild:
queue.append(cur_node.lchild)
if not cur_node.rchild:
queue.append(cur_node.rchild)
def preorder(self,node):
if node is None:
return
print(node.elem)
self.preorder(node.lchild)
self.preorder(node.rchild)
def inorder(self,node):
if node is None:
return
self.inorder(node.lchild)
print(node.elem)
self.inorder(node.rchild)
def postorder(self,node):
if node is None:
return
self.postorder(node.lchild)
self.postorder(node.rchild)
print(node.elem)