常用的三种排序算法
#快速排序
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);
浙公网安备 33010602011771号