2021-04-06数据结构
文章目录
时间复杂度
1.时间复杂度的计算规则
1、基本操作,认为其时间复杂度为O(1)
sum = 100 + 200
sum = 2002+1002
2、顺序结构,时间复杂度按加法进行计算
第一步:a = 100
第二步:b = 200
第三步:c = a + b
O(1)
3、循环结构,时间复杂度按乘法进行计算
for j in range(0,2):
for i in range(0,n):
print(i)
O(n)
分支结构,时间复杂度去最大值
判断一个算法的效率是,往往只需要关注操作数量的最高次项,其他次要项和常数项可以忽略
没有特殊说明时,我们分析的算法时间复杂度都是指最坏时间复杂度
线性结构
1.线性结构存储方式的分类
线性结构的实际存储方式,分为两种实现模型:
·顺序表
·链表
2.顺序表
顺序表存储数据的两种情况:
·一体式结构
·分离式结构
3.顺序表的结构
顺序表的完整信息包括两部分:数据区、信息区
4.链表的代码实现
结点代码实现
class SingleNode(object):
def __init__(self, item):
self.item = item
self.next = None
class SinleLinkList(object):
def __init__(self, node=None):
self.head = node
def is_empty(self):
if self.head is None:
return True
else:
return False
def length(self):
cur = self.head
num = 0
while cur is not None:
cur = cur.next
num = num + 1
return num
#头部增加节点
def add(self,item):
node = SingleNode(item)
node.next = self.head
self.head = node
# 尾部增加结点
def append(self,item):
node = SingleNode(item)
# 判断是否为空链表,特殊情况
if self.is_empty():
self.head = node
cur = self.head
while cur.next is not None:
cur = cur.next
cur.next = node
def insert(self,pos,item):
if pos == 0:
self.add(item)
elif pos >= self.length():
self.append(item)
else:
node = SingleNode(item)
cur = self.head
count = 0
while count < pos:
cur = cur.next
count = count + 1
node.next = cur.next
cur.next = node
def remove(self,item):
cur = self.head
pre = None
while cur is not None:
if cur.item == item:
if cur == self.head:
self.head=cur.next
else:
pre.next = cur.next
return
else:
pre = cur
cur = cur.next
栈
class Stack(object):
def __init__(self):
self.__items = []
def push(self,item):
self.__items.append(item)
def pop(self):
self.__items.pop()
队列
class Queue(object):
def __init__(self):
self.items = []
def enqueue(self,item):
self.items.append(item)
def dequeue(self):
self.items.pop(0)
def is_empty(self):
return self.items == []
def size(self):
return len(self.items)
# 双端队列
class Dequen(object):
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def size(self):
return len(self.items)
def add_front(self, item):
"""头部添加数据"""
self.items.append(0, item)
def add_rear(self,item):
"""尾部添加数据"""
self.items.append(item)
def remove_front(self):
self.items.pop(0)
def remove_rear(self):
self.items.pop()
排序
排序算法的稳定性
不稳定的排序算法:选择排序,快速排序,希尔排序,堆排序
稳定的排序算法:冒泡排序,插入排序,归并排序,基数排序
冒泡排序
def bubble_sort(alist):
n = len(alist)
count = 0
for j in range(0, n-1):
for i in range(0, n-j-1):
if alist[i] > alist[i+1]:
alist[i], alist[i+1] = alist[i+1], alist[i]
count = count+1
if count == 0:
break
return alist
选择排序
def select_sort(alist):
n = len(alist)
for j in range(0,n-1):
min_index = j
for i in range(j+1,n):
if alist[i] < alist[min_index]:
min_index = i
if j != min_index:
alist[j], alist[min_index] = alist[min_index], alist[j]
return alist
插入排序
def insert_sort(alist):
n = len(alist)
for i in range(1,n):
for j in range(i,0,-1):
if alist[j] < alist[j-1]:
alist[j], alist[j-1] = alist[j-1], alist[j]
else:
break
return alist
快速排序
def quick_sort(alist,start,end):
if start >= end:
return
mid = alist[start]
left = start
right = end
while left < right:
while alist[right] >= mid and left < right:
right -= 1
alist[left] = alist[right]
while alist[left] < mid and left < right:
left += 1
alist[right] = alist[left]
alist[left] = mid
quick_sort(alist,start,left-1)
quick_sort(alist,right+1,end)
二分查找
递归
def binary_search(alist, item):
n = len(alist)
if n == 0:
return False
mid = n//2
if item == alist[mid]:
return True
elif item > alist[mid]:
return binary_search(alist[mid+1:],item)
elif item < alist[mid]:
return binary_search(alist[0:mid],item)
非递归
def binary_search(alist, item):
n = len(alist)
start = 0
end = n-1
while start <= end:
mid = (start + end)//2
if alist[mid] == item:
return mid
elif alist[mid] < item:
start = mid + 1
elif alist[mid] > item:
end = mid - 1
return False
二叉树
二叉树的性质
性质1:在二叉树的第i层上至多有2i-1个结点(i>0)
性质2:深度为k的二叉树至多又2k-1个结点(k>0)
性质3:对于任意一颗二叉树,如果其叶节点数为N0,而度数为2的节点总数为N2,则N0=N2+1
性质4:最多有n个结点的完全二叉树的深度必为log2(n+1)
性质5:对完全二叉树,若从上至下、从左至右编号,则编号为i的结点,其左孩子编号必为2i,其右孩子编号必为2i+1,其父节点的编号必为i//2(i=1时为根,除外)
二叉树实现
class Node(object):
"""节点类"""
def __init__(self, item):
self.item = item
self.lchild = None
self.rchild = None
class BinaryTree(object):
"""完全二叉树"""
def __init__(self, node=None):
self.root = node
def add(self, item):
if self.root == Node:
self.root = Node(item)
return
queue = []
queue.append(self.root)
while True:
node = queue.pop(0)
if node.lchild == None:
node.lchild = Node(item)
return
else:
queue.append(node.lchild)
if node.rchild == None:
node.rchild = Node(item)
return
else:
queue.append(node.rchild)
def preorder_travel(self, root):
"""先序遍历"""
if root is not None:
print(root.item,end="")
self.preorder_travel(root.lchild)
self.preorder_travel(root.rchild)
def inorder_travel(self, root):
"""中序遍历"""
if root is not None:
self.preorder_travel(root.lchild)
print(root.item,end="")
self.preorder_travel(root.rchild)
def postorder_travel(self, root):
"""后序遍历"""
if root is not None:
self.preorder_travel(root.lchild)
self.preorder_travel(root.rchild)
print(root.item,end="")