程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 算法基礎——經典八大排序算法的Java及Python實現

算法基礎——經典八大排序算法的Java及Python實現

編輯:JAVA綜合教程

算法基礎——經典八大排序算法的Java及Python實現


概述

八大排序算法不用多說了,程序員算法基礎必須要掌握的,現在總結一下加深記憶。下圖是這八大排序算法的分類、名稱、時間空間復雜度,以及穩定性。\  

代碼

以下是經典八大排序算法的Java及Python代碼,都是基於經典算法書籍《算法導論》裡的偽代碼實現的,我在關鍵語句部分附上了注釋。 按照上圖中的順序分別介紹八大排序算法的實現(升序),前面是Java,後面是Python。Java的排序函數寫在了一個類裡,Python的排序函數則直接寫出來了。

直接插入排序

public class InsertSort {
	//插入排序,最好情況O(n),最壞情況O(n^2),穩定原址排序
	public int[] Sort(int[] arr){

		for(int i=0;i=0 && arr[j]>key;j--)
				arr[j+1] = arr[j];//注意!這裡不是交換,而是把比key大的都往後挪
			arr[j+1] = key;//key再插入合適的位置
		}
		return arr;
	}
}
def insertSort(arr):
    #插入排序,最壞為O(n^2),最好為O(n)
    #升序排列一個數組,降序排列將while語句中改為arr[i]=0 and arr[i]>key):
            #從後往前比較待插入的數和當前數,將arr[j-1]、arr[j-2]...向右移動直到找到arr[j]的適當位置
            arr[i+1] = arr[i]
            i -= 1
        arr[i+1] = key#遍歷完將arr[j]插入到該位置
    return arr

希爾排序

public class ShellSort {
	// 希爾排序,最好情況O(n),最壞情況O(n^2),平均情況比直接插入排序要好,平均情況為O(n^1.3)
	//不穩定,原址排序
	public int[] Sort(int[] arr) {
		int n = arr.length;
		for (int gap = n; gap > 0; gap/=2) {
			
			for (int i = gap;i < n;i++){
				if (arr[i] < arr[i-gap]){//如果比前面的元素小,則以步長為gap進行插入排序
					int key = arr[i];
					int j = i-gap;
					while (j>=0 && arr[j] > key){
						arr[j+gap] = arr[j];
						j -= gap;
					}
					arr[j+gap] = key;
				}
			}
		}
		return arr;
	}
}
def shellSort(arr):
    #改進版的插入排序-希爾排序,最壞為O(n^2),最好為O(n),平均為O(n^1.3)
    gap = len(arr)/2
    while gap > 0:
        
        for i in range(gap,len(arr)):
            if arr[i] < arr[i-gap]:#後面的元素比前面的小,以gap為步長進行插入排序
                key = arr[i]
                j = i - gap
                while j>=0 and arr[j]>key:
                    arr[j+gap] = arr[j]
                    j -= gap
                arr[j+gap] = key
        #步長減一半     
        gap /= 2

    return arr

直接選擇排序

public class SelectSort {
	//選擇排序,最壞和最好都為O(n^2),不穩定,原址排序
	public int[] Sort(int[] arr) {
		int n = arr.length;
		if (n<2)
			return arr;
		
		for(int i=0;i
def selectSort(arr):
    #選擇排序,最壞為O(n^2)
    #升序排列一個數組,降序排列將while語句中改為arr[i]

堆排序

public class HeapSort {
	//維護一個最大堆,使其以i節點的元素為根
	public void maxHeapify(int[] arr,int i,int heap_size){
		int l = 2*i+1;//左孩子節點
		int r = l+1;
		
		int largest = i;
		if(larr[largest])
			largest = l;
		if(rarr[largest])
			largest = r;
		
		if(largest != i){
			//保證i節點為最大,並維護以largest節點為根的最大堆
			int tmp = arr[i];
			arr[i] = arr[largest];
			arr[largest] = tmp;
			maxHeapify(arr,largest,heap_size);
		}
	}
	
	public void buildMaxHeap(int[] arr){
		int heap_size = arr.length;
		int mid = (heap_size-1)/2;
		//從中間節點開始把arr建為最大堆(只需遍歷數組的一半),最後使得arr[0]為最大堆的根
		for(int i=mid;i>=0;i--)
			maxHeapify(arr,i,heap_size);
	}
	
	public int[] Sort(int[] arr){
		//先把數組建造為最大堆
		buildMaxHeap(arr);
		
		//從後往前遍歷,根據最大堆的性質arr[0]最大
		for(int i = arr.length-1;i>=0;i--){
			int tmp = arr[0];
			arr[0] = arr[i];
			arr[i] = tmp;
			int heap_size = i;
			maxHeapify(arr,0,heap_size);
		}
		
		return arr;
	}
}
def maxHeapify(arr,i,heap_size):
    #維護一個最大堆,讓arr[i]的值在最大堆中逐級下降,使得以i為根節點的子樹是最大堆,O(lgn)
    l = 2*i+1#下標i從0開始,因此左孩子節點的下標是2*i+1
    r = l + 1#右孩子節點

    largest = i

    if larr[largest]:#注意heap_size初始化為len(arr),這裡判斷應為larr[largest]:
        largest = r
                
    if largest != i:#i不是最大堆的根節點,就交換值,並且讓largest為根節點的子樹保持最大堆
        arr[largest],arr[i] = arr[i],arr[largest]
        maxHeapify(arr,largest,heap_size)

            
def buildMaxHeap(arr):
    #自頂向上,將arr轉換為最大堆
    heap_size = len(arr)
    mid = int((heap_size-1)/2)
    for i in range(mid,-1,-1):
        maxHeapify(arr,i,heap_size)
        

def heapSort(arr):
    
    buildMaxHeap(arr)#時間復雜度O(n)
    size = len(arr)    
    
    #n-1次調用maxHeapify,時間復雜度O(nlgn)
    for i in range(size-1,-1,-1):
        
        arr[i],arr[0] = arr[0],arr[i]#從後往前存儲,根據最大堆性質,arr[0]是當前最大堆的最大值
        heap_size = i
        maxHeapify(arr,0,heap_size)


冒泡排序

public class PopSort {
	public int[] Sort(int[] arr) {
		int n = arr.length;
		if(n<2)
			return arr;
		
		for(int i=0;ii;j--){
				if(arr[j-1]>arr[j]){
					int tmp = arr[j];
					arr[j] = arr[j-1];
					arr[j-1] = tmp;
				}
			}
		
		return arr;
	}
}
def popSort(arr):
    n = len(arr)
    if n < 2:
        return arr
    
    for i in range(n):
        for j in range(n-1,i,-1):
            if arr[j-1] > arr[j]:
                arr[j-1],arr[j] = arr[j],arr[j-1]

    return arr

快速排序

public class QuickSort {
	
	public int getPartition(int[] arr,int low,int high){

		int tmp;
		int index = low - 1;		
		for(int i = low;i
def quickSort(arr,low,high):
    #隨機選擇基准元素的快速排序,達到期望時間復雜度O(nlgn)
    #注意high是最大下標
    if low < high:
        mid = getPartition(arr,low,high)
        #對基准元素兩邊的數組快排
        quickSort(arr,low,mid-1)
        quickSort(arr,mid+1,high)
        
def getPartition(arr,low,high):
    #隨機選擇一個數並與arr[high]交換,防止最壞情況
    #將arr[high]作為基准進行排序
    rand = random.randint(low,high)
    arr[high],arr[rand] = arr[rand],arr[high]
    
    index = low - 1
    for i in range(low,high):
        if arr[i] <= arr[high]:#保證index前面的數都比key小
            index += 1
            arr[index],arr[i] = arr[i],arr[index]
    arr[index+1],arr[high] = arr[high],arr[index+1]
    
    return index+1

歸並排序

public class MergeSort {
	
	public void Sort(int[] arr,int low,int high){
		if(low
def mergeSort(arr,p,r):
    #p17,歸並排序,O(nlgn).注意r是數組的最大下標
    if p

基數排序

這個用Java寫太麻煩了,各種麻煩的ArrayList操作~~所以只貼Python版
def cntDigit(arr,radix):
    #獲取數組元素的最大位數
    maxnum = arr[0]
    for x in arr:
        if x > maxnum:
            maxnum = x
    
    cnt = 0
    while(maxnum != 0):
        maxnum /= radix
        cnt += 1
    return cnt

def radixSort(arr,radix=10):
    k = cntDigit(arr,radix)#獲取最大位數
    bucket = [[] for i in range(radix)]
    for i in range(1,k+1):
        for j in arr:
            #bucket[x]存儲從低到高第i位為x的數,如數組中的543,i=1時存在bucket[3]裡
            bucket[j/(radix**(i-1)) % (radix)].append(j)
        del arr[:]#先初始化arr
        #print(bucket)
        for z in bucket:#當前位數的數組按順序放入arr中
            arr += z
            del z[:]
    return arr

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved