代码如下: 快排
'''
几乎是我们学习排序入门算法了,两次遍历,时间复杂度较高n*n,稳定排序
'''
def bubbleSort(tmpList):
for i in range(len(tmpList)-1):
for j in range(len(tmpList)-1,i,-1):
if tmpList[j-1] > tmpList[j]:
tmpList[j-1],tmpList[j] = tmpList[j],tmpList[j-1]
print(tmpList)
bubbleSort([9,8,7,6,5,4,3,2,1])
'''
选择排序:思想就是 当当前数跟后面所以对比,然后找到最小的。这两个点进行交换。
331 -> 133 不稳定排序 时间复杂度n*n
'''
def selectSort(tmpList):
for i in range(len(tmpList) - 1):
minIndex = i
for j in range(i+1,len(tmpList)):
if tmpList[j] < tmpList[i]:
minIndex = j
if minIndex != i:
tmpList[i],tmpList[minIndex] = tmpList[minIndex],tmpList[i]
print(tmpList)
selectSort([9,8,7,6,5,4,3,2,1])
'''
插入排序:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
时间复杂度 n*n 稳定。
'''
def InsertSort(tmpList):
for i in range(1,len(tmpList)):
key = tmpList[i]
a = i
while key < tmpList[a-1]:
tmpList[a] = tmpList[a-1]
a = a-1
if a - 1 < 0:
break
tmpList[a] = key
print(tmpList)
InsertSort([9,8,7,6,5,4,3,2,1])
'''
希尔排序: 每次将相同间隔的数组成一个小数组,然后用插入排序实现, 时间复杂度为 nlgn 不稳定
'''
def ShellSort(tmpList):
step = len(tmpList)//2
while step > 0:
for i in range(step):
j = i + step
while j < len(tmpList):
a = j
key = tmpList[j]
while key < tmpList[a - step]:
tmpList[a] = tmpList[a - step]
a = a - step
if a - step < 0:
break
tmpList[a] = key
j += step
step = step//2
print(tmpList)
ShellSort([9,8,7,6,5,4,3,2,1])
'''
堆排:思想来自于二叉树,还是完全二叉树,有大根堆(从小到大),小根堆(从大到小)。
先建立完全二叉树,建立的思路就是 大根堆或者小根堆的定义。
建好后,每次将当前最大数 挪到根节点,然后将根节点跟最后节点数据实现互换,如此循环执行即可。
'''
def adjustHeap(tmpList,i,size):
left = 2*i+1
right = 2*i+2
max = i
if i < size//2:
if left < size and tmpList[left] > tmpList[max]:
max = left
if right < size and tmpList[right] > tmpList[max]:
max = right
if max != i:
tmpList[max],tmpList[i] = tmpList[i],tmpList[max]
adjustHeap(tmpList,max,size) # 数据互换后要考虑 i 下面根节点的影响。
def buildHeap(tmpList,size): # 建立一个 大根堆
for i in range((size)//2,0,-1):
adjustHeap(tmpList,i,size)
def heapSort(tmpList):
size = len(tmpList)
buildHeap(tmpList,size)
for i in range(0,size)[::-1]:
tmpList[i],tmpList[0] = tmpList[0],tmpList[i]
adjustHeap(tmpList,0,i)
print(tmpList)
heapSort([9,8,7,6,5,4,3,2,1])
'''
归并排序: 分治的思想,将数据分成若干小的组合,然后组合与组合两两排序,排序后的组合再两两排序,
深度遍历的思想 DFS, 这样的函数通常都包含递归调用的思想 不稳定
'''
def merge(left,right):
ans = []
i = 0
j = 0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
ans.append(left[i])
i += 1
else:
ans.append(right[j])
j += 1
ans += left[i:] + right[j:]
return ans
def mergeSort(tmpList):
size = len(tmpList)
if size < 2:
return tmpList
mid = size // 2
left = mergeSort(tmpList[:mid])
right = mergeSort(tmpList[mid:])
return merge(left,right)
print(mergeSort([9,8,7,6,5,4,3,2,1]))
'''
快排:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列,不稳定
'''
def subSort(tmpList,left,right):
key = tmpList[left]
while left < right:
while left < right and tmpList[right] >= key:
right -= 1
tmpList[left] = tmpList[right] # 理解下 减少不必要的数据交换
while left < right and tmpList[left] <= key:
left += 1
tmpList[right] = tmpList[left] # 理解下 减少不必要的数据交换
tmpList[left] = key
return left # 返回中间数的索引
def quickSort(tmpList,left,right):
if left < right:
keyIndex = subSort(tmpList,left,right)
quickSort(tmpList,left,keyIndex)
quickSort(tmpList,keyIndex+1,right)
tmpList = [5,1,9,3,7,4,8,6,2]
quickSort(tmpList,0,len(tmpList)-1)
print(tmpList)
'''
!!! 计数排序、基数排序、桶排序则属于非比较排序,算法时间复杂度O(n),优于比较排序。但是也有弊端,会多占用一些空间,有特定的数据要求,不能是负数,不能是小数,相当于是用空间换时间。
'''
'''
桶排:通排序非常浪费空间, 比如需要排序的范围在0~2000之间, 需要排序的数是[3,9,4,2000], 同样需要2001个空间
注意: 通排序不能排序小数
'''
def bucketSort(tmpList): # 待排序数组, 最大的筒子,数组的长度
max_num = max(tmpList) # 选择一个最大数
bucket = [0]*(max_num+1) # 创建一个元素全为0的列表当桶
for i in tmpList: # 把所有元素放入桶中,计算该数出现次数
bucket[i] += 1
ans = []
for i in range(len(bucket)):
if bucket[i] != 0: # 如果该数出现的次数大于0
for j in range(bucket[i]): # 出现多少次都将数放入桶中
ans.append(i)
return ans
tmpList = [5,6,3,2,1,65,2,0,8,0]
print(bucketSort(tmpList))
'''
计数排序:基本思想是:对每一个输入的元素a[i],确定小于 a[i] 的元素个数。所以可以直接把 a[i] 放到它输出数组中的位置上。假设有5个数小于 a[i],所以 a[i] 应该放在数组的第6个位置上。
'''
def countSort(tmpList,maxNum): # 呆排序数组,最大值
ans = [0]*len(tmpList)
c = [0]*(maxNum+1)
for i in tmpList:
c[i] += 1
for i in range(1,maxNum+1):
c[i] += c[i-1] #统计每个数字所在的idx
for j in tmpList:
ans[c[j]-1] = j
c[j] = c[j] - 1
return ans
tmpList = [5,6,3,2,1,65,2,0,8,0]
print(countSort(tmpList,max(tmpList)))
def radixSort(tmpList):
n = 1 # 计算数最多多少位
maxNum = max(tmpList)
while maxNum//(10**n) > 0:
n +=1
for i in range(n): # n轮排序
s = [[] for i in range(10)] # 因为没一位数字都是0~9 ,故建立10个桶
# 对于数组中的元素,首先按照最低有效数字进行排序,然后由低位向高位进行
for j in tmpList:
'''对于3个元素的数组[977, 87, 960],第一轮排序首先按照个位数字相同的
放在一个桶s[7]=[977],s[7]=[977,87],s[0]=[960]
执行后list=[960,977,87].第二轮按照十位数,s[6]=[960],s[7]=[977]
s[8]=[87],执行后list=[960,977,87].第三轮按照百位,s[9]=[960]
s[9]=[960,977],s[0]=87,执行后list=[87,960,977],结束。'''
s[j//(10**i)%10].append(j)
tmpList = [j for i in s for j in i]
return tmpList
tmpList = [5,6,3,2,1,65,2,0,8,0]
print(radixSort(tmpList))