常用的三种排序算法
#快速排序
def QuickSort(arr,left,right): """ arr: the array needed to sort left: the start index right: the end index """ if(left>=right): return ; base = arr[left]; i = left; j = right; while(i<j and arr[j]>=base): j = j - 1; arr[i] = arr[j]; while(i<j and arr[i]<=base): i = i + 1; arr[j] = arr[i]; arr[i] = base; QuickSort(arr,i+1,right); QuickSort(arr,0,i-1); arr = [3,1,2,5,4,6]; QuickSort(arr,0,5) print(arr)
#归并排序
#将有序的start-mid ,mid-end 两个子数组组合成从小到大排列 def MemeryArray(arr,start,mid,end): j = mid+1; i = 0; k = 0; temp = [0 for i in range(end+1)]; while(i<=mid): if(arr[i]>arr[j] and j<= end): temp[k] = arr[j]; j = j + 1; else: temp[k] = arr[i]; i = i + 1; k = k + 1; while(k<=end): temp[k] = arr[j]; k = k + 1; j = j + 1; for i in range(end+1): arr[i] = temp[i]; def MergeSort(arr,start,end): """ arr:the array needed to sort start:the start index end:the end index """ if(len(arr)==0 or start>=end): return; mid = int((start+end)/2); MergeSort(arr,start,mid); MergeSort(arr,mid+1,end); MemeryArray(arr,start,mid,end); arr = [3,1,2,5,4,6]; MergeSort(arr,0,5) print(arr)
#堆排序
def HeapAdjust(arr,i,n): """ big heap i the current point n the lenght of the arr 每次调整都是当前节点与其子节点进行交换 """ j = 2*i + 1; #left child temp = arr[i]; while(j < n): if(j+1 < n and arr[j + 1] > arr[j]): #right bigger then left j = j + 1; if(arr[j] <= temp): break; arr[i] = arr[j]; i = j; j = 2*i + 1; arr[i] = temp; def BuildHeap(arr,n): i = int(n/2) - 1; while(i >= 0): HeapAdjust(arr,i,n); i = i - 1; def HeapSort(arr,n): i = n-1; BuildHeap(arr,n); print("the original heap is {0}".format(arr)); while(i>=1): arr[0],arr[i] = arr[i],arr[0]; HeapAdjust(arr,0,i); print("the {0} clycle is {1}".format(i,arr)); i = i - 1; arr = [3,1,2,5,4,6]; HeapSort(arr,6); print(arr) 上例堆排序使用的是大根堆,若要改为小根堆只需将: if(j+1 < n and arr[j + 1] > arr[j]): #right bigger then left ,改为 if(j+1 < n and arr[j + 1] < arr[j]): #right smaller then left; if(arr[j] <= temp): 改为 if(arr[j] >= temp): 即可
给出一个应用案例
从N个数种选出最大的前n个数
#使用小根堆 def SmallRootHeap(arr,i,n): """ big heap i the current point n the lenght of the arr 每次调整都是当前节点与其子节点进行交换 """ j = 2*i + 1; #left child temp = arr[i]; while(j < n): if(j+1 < n and arr[j + 1] < arr[j]): #right smaller then left j = j + 1; if(arr[j] >= temp): break; arr[i] = arr[j]; i = j; j = 2*i + 1; arr[i] = temp; #该问题只需要找出前n大的数,故不需要排序,只需要建立堆结构即可 def BuildSmallRootHeap(arr,n): i = int(n/2) - 1; while(i >= 0): SmallRootHeap(arr,i,n); i = i - 1; def FindTopK(arr,n): """find the largest n number from the arr""" candidate = arr[:n]; BuildSmallRootHeap(candidate,n); arr = arr[n:]; N = len(arr); for i in range(N): try: if(arr[i]>candidate[0]): candidate[0] = arr[i]; BuildSmallRootHeap(candidate,n); except: print(i,len(arr)) return candidate #从10000个数中找出最大的100个数 largest_arr = np.random.randint(0,20000,10000); candidate = FindTopK(largest_arr,100); largest_arr = sorted(largest_arr,reverse=True); largest_100 = largest_arr[:100]; candidate = sorted(candidate,reverse=True); print(candidate); print(largest_100);