数据结构和算法(一)
--------------------------排序算法篇--------------------------
冒泡排序
时间复杂度O(n^2) 空间复杂度O(1)
li = [3, 5, 1, 4, 7, 6, 2]
def bubble_sort(li):
for i in range(len(li) - 1): #下标从0 - 6,没有任何含义只是为了遍历列表,具体的取值顺序看 for j in range(len(li) - 1 - i):
flag = False #检测li列表是否已经是排序过的列表(从小到大)
for j in range(len(li) - 1 - i): #每完成一次排序,排序后最大的数都不再参加 for 循环排序
if li[j] > li[j + 1]: #如果下面的数比上面的数大
li[j], li[j + 1] = li[j + 1], li[j] #交换位置。
flag = True #如果一次位置都没有交换,那么说明这个列表的排序是升序,无需再次排序。
if not flag:
print('already ordered')
return None
else: return li
li = bubble_sort(li)
选择排序
时间复杂度 O(n^2) 空间复杂度O(1)
li = [3, 5, 1, 4, 7, 6, 2]
def select_sort(li):
for i in range(len(li)-1):
minLoc = i #假设当前的i 是最小的序号
for j in range(i+1,len(li)):
if li[j] > li[minLoc]: #如果右边的值比minLoc所在位置的值大的话
li[j],li[minLoc] = li[minLoc],li[j] #交换位置
return li
li = select_sort(li)
print(li)
[7, 6, 5, 4, 3, 2, 1]
插入排序
解释:从 i = 1 的这张牌开始,和左边的牌从右到左(先比7再比5)依次比较进行比较,如果比左边大,就放在原来的位置上,否则把比i 坐在位置大的牌放到i的位置,然后i放到和i对比的数的位置,再对左边的牌进行比较。
li = [3, 5, 1, 4, 7, 6, 2]
def insert_sort(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 = j-1 #不成立时跳出while循环
li[j+1] = tmp #不成立时的最后一个位置+1 给拿出来的tmp
return li
li = insert_sort(li)
print(li)
快速排序(重点)
快速排序
def quick_sort(li, left, right):
if left < right:
mid = partition(li, left, right)
quick_sort(li, left, mid-1)
quick_sort(li, mid+1, right)
def partition(li, left, right):
tmp = li[left]
while left < right:
while left < right and li[right] >= tmp:
right -= 1
li[left] = li[right]
while left < right and li[left] <= tmp:
left += 1
li[right] = li[left]
li[left] = tmp
return left
quick_sort(li, 0, len(li)-1)
print(li)
归并算法
对比指针所对应的变量,哪个小就把哪个拿到下面的空列表里,然后移动指针,再对两个值进行对比。
## 时间复杂度: O(nlogn)
## 空间复杂度: O(n)
def merge(li, low, mid, high ):
i = low
j = mid + 1
ltmp = []
#取数主循环
while i <= mid and j <= high:
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 <= high:
ltmp.append(li[j])
j = j + 1
li[low:high+1] = ltmp
#合并数列
def merge_sort(li, low, high):
if low < high:
mid = (low + high) // 2
merge_sort(li, low, mid) #如果分到后来low=mid的话,那就
merge_sort(li, mid+1, high)
print("归并前: ",li[low:high+1])
merge(li, low, mid, high)
print("归并后: ",li[low:high + 1])
计数排序
def countsort(li):
count = [0 for i in range(11)] #最大数是 i 就要生成 i+1 此方法不是太适用于数据特别大的情况
for i in li:
# print(i)
count[i] += 1
li.clear()
for n, num in enumerate(count):
print(n, num)
for i in range(num):
li.append(n)
li = [10,4,6,3,8,2,5,2]
countsort(li)
print(li)