一.数据结构与算法概述
数据结构与算法的定义
我们把现实中大量而且非常复杂的问题以特定的数据类型(个体)和特定的存储结构(个体的关系)保存到相应的主存储器(内存)中,以及在此基础上为实现某个功能而执行的相应操作,这个相应操作也叫做算法.
数据结构 = 个体 + 个体的关系
算法 = 对存储数据的操作
二.衡量算法的标准
时间复杂度 指的是大概程序执行的次数,并非程序执行的时间
空间复杂度 指的是程序执行过程中,大概所占有的最大内存
常用的查找
顺序查找
lowB for循环
时间复杂度 O(n)
def linerSearch(li,val): for i in range(len(li)): if li[i] == val: return i
二分查找
二分查询的列表必须有序!
时间复杂度 O(logn)
# 递归 def binarySearch(li,low,high,val): if low < high: mid = (low+high) // 2 if li[mid]==val: return mid elif li[mid]<val: binarySearch(li,mid+1,high,val) elif li[mid]>val: binarySearch(li,low,mid-1,val) else: return -1 # 循环 def binary_search(li,value): low = 0 high = len(li) while low <= high: mid = (low+high)//2 if li[mid] == value: return mid elif li[mid] > value: high = mid -1 else: low = mid +1
常用的几个排序
冒泡排序
时间复杂度:O(n2)
def BubbleSort(li): for i in range(len(li)): flag = False for j in range(len(li)-i-1): if li[j]>li[j+1]: li[j],li[j+1] = li[j+1],li[j] flag = True if not flag: return li
选择排序
时间复杂度:O(n2)
def selectSort(li): for i in range(len(li)): for j in range(i+1,len(li)): if li[i] > li[j]: li[i],li[j] = li[j],li[i] print(li)
插入排序
时间复杂度:O(n2)
def insertSort(li): for i in range(1,len(li)): tmp = li[i] j = i - 1 while j>=0 and li[j]>tmp: li[j+1] = li[j] j-=1 li[j+1]=tmp print(li)
快速排序
时间复杂度:O(nlogn)
# 一次调整 def partition(li,left,right): tmp = li[left] while left <right: while left < right and li[right]>=tmp: right=right - 1 li[left] = li[right] while left < right and li[left] <= tmp: left+=1 li[right] = li[left] li[left] = tmp return left # 快速排序 def quickSort(li,left,right): if left < right: mid = partition(li, left, right) ### O(n) quickSort(li, left, mid - 1) ### O(logn) quickSort(li, mid + 1, right)
归并排序
时间复杂度:O(nlogn)
# 一次归并 def merge(li,low,mid,right): i = low j = mid +1 ltmp = [] while i <= mid and j <=right: if li[i] <li[j]: ltmp.append(li[i]) i = i + 1 else: ltmp.append(li[j]) j = j + 1 while i <= mid: ltmp.append(li[i]) i = i + 1 while j <= right: ltmp.append(li[j]) j = j + 1 li[low:right + 1] =ltmp def mergeSort(li, low, high): if low < high: mid = (low + high) // 2 mergeSort(li, low, mid) mergeSort(li, mid + 1, high) print('归并之前:', li[low:high+1]) merge(li, low, mid, high) print('归并之后:', li[low:high + 1])
希尔排序
时间复杂度:O(nlogn)
def shell_sort(li): gap = len(li)//2 while gap > 0 : for i in range(gap,len(li)): tmp = li[i] j = i -gap while j>=0 and tmp <li[j]: li[j + gap ] = li[j] j -= gap li[j + gap] = tmp gap //= 2
计数排序
时间复杂度:O(nlogn)
def countSort(li): li_new=[] count = [0 for i in range(len(li))] for i in li: count[i]+=1 for index,val in enumerate(count): print(index,val) for i in range(val): li_new.append(index) print(li_new)
排序小结
排序方法 | 时间复杂度 | 稳定性 | 代码复杂度 | ||
最坏情况 | 平均情况 | 最好情况 | |||
冒泡排序 | O(n2) | O(n2) | O(n) | 稳定 | 简单 |
直接选择排序 | O(n2) | O(n2) | O(n2) | 不稳定 | 简单 |
直接插入排序 | O(n2) | O(n2) | O(n2) | 稳定 | 简单 |
快速排序 | O(n2) | O(nlogn) | O(nlogn) | 不稳定 | 较复杂 |
堆排序 | O(nlogn) | O(nlogn) | O(nlogn) | 不稳定 | 复杂 |
归并排序 | O(nlogn) | O(nlogn) | O(nlogn) | 稳定 | 较复杂 |
希尔排序 | O(1.3n) | 不稳定 | 较复杂 |
三.数组与链表