一:数据结构部分
1.大O表示法
(渐进函数)
2.时间复杂度
重点《
3.测算耗时
from timeit import timer
def test1():
li = [i for i in range(10000)]
timer1 = timer("test1","from __main__ import test2")
# 模拟次数
print("a",timer1.timeit(1000))
3.数据结构
抽象数据类型(ADT)(面向对象???)
32位:整型占4字节
1个char (字符 字母)占一个字节
顺序表基本布局 与 元素外置
4.顺序表
(存储空间必须连续
顺序表的构建需要预知数据大小申请存储空间,扩充时需要进行数据搬迁)
(1)表头信息+数据
分为两种 一体式结构和分离式结构
顺序表数据区扩充:(支持扩充的顺序表称为动态顺序表)
1.固定数目:节省空间, 扩充操作频繁,操作次数多。
2.扩充容量加倍:减少扩充执行次数,浪费空间资源
python list是根据顺序表实现的
注:8个元素存储区(整型4字节-元素外置:储存地址)
5.链表
节点:数据区+链接区
单链表:
class Node(object):
"""节点"""
def __init__(self, elem):
self.elem = elem
self.next = None
class SingleLinkList(object):
def __init__(self):
self.__head = None
def is_empty(self):
"""链表是否为空"""
return self.__head == None
def length(self):
"""链表长度"""
num = 0
cur = self.__head
while cur != None:
num += 1
cur = cur.next
return num
def travel(self):
"""遍历整个链表"""
cur = self.__head
while cur != None:
print(cur.elem)
cur = cur.next
def add(self, item):
"""链表头部添加元素,头插法"""
node = Node(item)
node.next = self.__head
self.__head = node
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 insert(self, pos, item):
"""指定位置添加元素:param pos 从0开始"""
num = 0
node = Node(item)
pre = self.__head
if pos <= 0:
self.add(item)
elif pos > (self.length()-1):
self.append(item)
else:
while num < (pos-1):
num += 1
pre = pre.next
cur = pre.next
node.next = cur
pre.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
else:
pre = cur
cur = cur.next
def search(self, item):
"""查找节点是否存在"""
cur = self.__head
while cur != None:
if cur.elem == item:
return True
else:
cur = cur.next
return False
还有 双向链表和单项循环链表 (不上代码了)
6.栈和队列
栈:(LIFO)
class Stack(object):
def __init__(self):
self.__list = []
def pop(self):
self.__list.pop()
def push(self, item):
self.__list.append(item)
def peek(self):
if self.__list:
return self.__list[-1]
else:
return None
def is_empty(self):
return not self.__list
def size(self):
return len(self.__list)
队列:(FIFO)
class Queue(object):
def __init__(self):
self.__list = []
def enqueue(self, item):
self.__list.append(item)
def dequeue(self):
self.__list.pop(0)
def is_emppty(self):
return not self.__list
def size(self):
return len(self.__list)
双向队列(懂得都懂)
7.树
二叉树数学性质
二叉树的构建、添加节点 、与遍历
class Node(object):
def __init__(self,item):
self.elem = item
self.l_child = None
self.r_child = None
class Tree(object):
def __init__(self):
self.root = None
def add(self,item):
node = Node(item)
if self.root is None:
self.root = node
return
queue = [self.root]
while queue:
cur_node = queue.pop(0)
if cur_node.l_child is None:
cur_node.l_child = node
return
else:
queue.append(cur_node.l_child)
if cur_node.r_child is None:
cur_node.r_child = node
return
else:
queue.append(cur_node.r_child)
def breadth_travel(self):
"""广度遍历"""
if self.root is None:
return
queue = [self.root]
while queue:
cur_node = queue.pop(0)
print(cur_node.elem, end=" ")
if cur_node.l_child is not None:
queue.append(cur_node.l_child)
if cur_node.r_child is not None:
queue.append(cur_node.r_child)
def preorder(self,node):
"""先序遍历,中左右"""
if node is None:
return
print(node.elem, end=" ")
self.preorder(node.l_child)
self.preorder(node.r_child)
def midorder(self,node):
"""中序遍历,左中右"""
if node is None:
return
self.midorder(node.l_child)
print(node.elem, end=" ")
self.midorder(node.r_child)
#self.midorder(0)
# self.midorder(0.l_child = 1)
# self.midorder(1.l_child = 3)
# self.midorder(3.l_child)
# print(3)
# self.midorder(3.r_child)
# print(1)
# self.midorder(1.r_child = 2)
# print(4)
# print(0)
# self.midorder(0.r_child = 2)
# self.midorder(2.l_child = 5)
# print(5)
# print(2)
# self.midorder(2.r_child = 6)
# print(6)
def postorder(self,node):
"""后序遍历,左右中"""
if node is None:
return
self.postorder(node.l_child)
self.postorder(node.r_child)
print(node.elem, end=" ")
二:算法部分
(一)排序
1.冒泡排序 时间复杂度【O(n^2)】
稳定
(自己敲的↓ 用的指针,while,for)
def bubble_sort(qlist):
a = 1
for x in range(len(qlist)-1):
cur = 1
pre = cur - 1
while cur != (len(qlist)-a):
if qlist[pre] > qlist[cur]:
qlist[pre], qlist[cur] = qlist[cur], qlist[pre]
else:
cur += 1
pre += 1
if qlist[cur] < qlist[pre]:
qlist[cur], qlist[pre] = qlist[pre], qlist[cur]
a += 1
return qlist
b = bubble_sort([5,6,4,3,2,1])
print(b)
(标准思路:for)
def bubble_sort(qlist):
for j in range(len(qlist)-1):
for i in range(len(qlist)-1-j):
if qlist[i] > qlist[i+1]:
qlist[i], qlist[i+1] = qlist[i+1], qlist[i]
return qlist
b = bubble_sort([4,3,2,1])
print(b)
2.选择排序 时间复杂度【O(n^2)】
不稳定
(自己敲 的 ↓)
# a→取几个
def sort(alist,a):
b = 0
min = b #注意放外面
for j in range(0,a):
for i in range(b+1,len(alist)):
if alist[min] > alist[i]:
min = i
alist[b], alist[min] = alist[min], alist[b]
b += 1
return alist
s = sort([2,3,4,5,1],2)
print(s)
# 全部排序
def sort(alist):
b = 0
for j in range(0,len(alist)-1):
min = b
for i in range(b+1,len(alist)):
if alist[min] > alist[i]:
min = i
alist[b], alist[min] = alist[min], alist[b]
b += 1
return alist
s = sort([6,2,3,4,5,1,8,99,77],)
print(s)
标准思路:
def sort(alist):
for j in range(0,len(alist)-1):
min = j
for i in range(j+1,len(alist)):
if alist[min] > alist[i]:
min = i
alist[j], alist[min] = alist[min], alist[j]
return alist
z = sort([2,3,4,5,1,99,88,77,66])
print(z)
3.插入排序:时间复杂度【O(n^2)】
稳定
1:(for)
def insert_sort(alist):
# 指针后移,插入元素
for i in range(1,len(alist)): #[12345] i=1234
# 后面元素与前面比较
for j in range(i,0,-1): #j=1 21 321 4321
if alist[j] < alist[j-1]:
alist[j-1], alist[j] = alist[j], alist[j-1]
return alist
b = insert_sort([6,5,4,3,2,1])
print(b)
2.(while) 最优O(n)
def insert_sort(alist):
# 插入数字
for j in range(1,len(alist)):
i = j
# 移动
while i > 0:
if alist[i] < alist[i-1]:
alist[i], alist[i-1] = alist[i-1], alist[i]
else:
break
i -= 1
return alist
b = insert_sort([6,5,4,3,2,1])
print(b)
4.希尔排序
def shell_sort(alist):
n = len(alist)
gap = n // 2
while gap > 0 :
for j in range(gap,n): # 1 2 3 4 5 6
for i in range(j,0,-gap):
if alist[i] < alist [i-gap]:
alist[i-gap], alist[i] = alist[i], alist[i-gap]
gap //= 2
return alist
s = shell_sort([6,5,4,3,2,1,88,77,99,123,6589])
print(s)
优化一点:(复杂度降低)
def shell_sort(alist):
n = len(alist)
gap = n // 2
while gap > 0 :
for j in range(gap,n): # 1 2 3 4 5 6
i = j
while i > 0:
if alist[i] < alist [i-gap]:
alist[i-gap], alist[i] = alist[i], alist[i-gap]
i -= gap
else:
break
gap //= 2
return alist
s = shell_sort([6,5,4,3,2,1,88,77,99,123,6589])
print(s)
快速排序:
def quick_sort(alist,start,end):
if start >= end:
return
mid_value = alist[start]
low = start
high = end
while low < high:
while low < high and alist[high] >= mid_value:
high -= 1
alist[low] = alist[high]
while low < high and alist[low] < mid_value:
low += 1
alist[high] = alist[low]
alist[low] = mid_value
quick_sort(alist,start,low-1)
quick_sort(alist,low+1,end)
return alist
归并排序:
def merge_sort(alist):
n = len(alist)
if n <= 1:
return alist
mid = n//2
left_pointer = 0
right_pointer = 0
# 拆分
left_li = merge_sort(alist[:mid])
right_li = merge_sort(alist[mid:])
result = []
# 重组
while left_pointer < len(left_li) and right_pointer < len(right_li):
if left_li[left_pointer] <= right_li[right_pointer]:
result.append(left_li[left_pointer])
left_pointer += 1
else:
result.append(right_li[right_pointer])
right_pointer += 1
result += left_li[left_pointer:]
result += right_li[right_pointer:]
return result
(二)搜索
1.二分查找
最优时间复杂度 O(1)
最劣时间复杂度 O(log2 n )
(自己敲出来的 emmm)
(好像只能查找 item在列表中的情况 如果不存在会无限递归。。。)
def find(alist, start, end, num):
"""start是列表起始下标, end是列表结束下标,num是查找的东西"""
left = start
right = end
mid = (left+right)//2
# 分开 查找 一次
if num > alist[mid]:
return find(alist,mid+1,end,num)
elif num < alist[mid]:
return find(alist,start,mid-1,num)
elif num == alist[mid]:
return True
else:
return False
(修改版)
def find(alist, start, end, num):
left = start
right = end
mid = (left+right)//2
# 分开 查找 一次
if left == right and alist[mid] != num:
return False
if num > alist[mid]:
return find(alist,mid+1,end,num)
elif num < alist[mid]:
return find(alist,start,mid-1,num)
elif num == alist[mid]:
return True
视频版:
1.递归版:
def binary_search(alist,item):
n = len(alist)
mid = n//2
if n > 0 :
if alist[mid] > item:
return binary_find(alist[:mid],item)
elif alist[mid] < item:
return binary_find(alist[mid+1:],item)
elif alist[mid] == item:
return True
return False
2.非递归版:
def binary_search(alist,item):
n = len(alist)
left = 0
right = n-1
while left <= right :
mid = (left + right)//2
if alist[mid] > item:
right = mid - 1
elif alist[mid] < item:
left = mid + 1
elif alist[mid] == item:
return True
return False