排序算法合集(C++實現)


摘要

排序操作在程序設計中是非常基礎和常見的,也是算法的基礎部分,我對幾種常見的比較排序算法進行了整理。

選擇排序

思想:遍歷數組,每次遍歷都在未排序的部分找到最小元素的下標,在此次遍歷結束后將最小元素放到遍歷開始的位置。

性能:時間復雜度為O(n2),算法比較次數與初始序列狀態無關,性能在所有排序算法中最差。

 

void Violence_Sort(int* A, int len){
        for(int i=0;i<len;i++)
        {
                int k = i;
                for(int j=i;j<len;j++)
                        if(A[j]<A[k])
                                k = j;
                if(k != i){
                        int t = A[i];
                        A[i] = A[k];
                        A[k] = t;
                }
        }
}

 

插入排序(insert sort)

思想: 將當前元素與它前面已排好序的元素依次進行比較,最后放置在合適的位置,初始時可從第二個元素開始,認為第一個元素已排好序。

性能:算法時間復雜度為O(n2),在序列規模較小時,性能比較好,且元素比較次數與初始序列雜亂程度相關,最優復雜度為O(n)。

 

void Insert_Sort(int* A, int len){
        for(int i=1;i<len;i++)
        {
                int key = A[i];
                int j = i - 1;
                while(j >= 0 && key  < A[j]){
                        A[j+1] = A[j];
                        j--;
                }
                A[j+1] = key;
        }
}

 

希爾排序(shell sort)

思想:利用插入排序的思想,考慮到插入排序在序列基本有序且數量較少時性能較高,因此先對序列進行邏輯上的分組然后插入排序,如:設定初始增量為x,則0,0+x,0+x+x ...為一組,1,1+x,1+x+x ...為第二組,共有x組,分別進行排序。那個隨后減少增量,增加分組,直到增量為1。

性能:算法時間復雜度為O(n1.3) -O(n2),性能取決於增量序列。

void shellSort(int A[], int len){
    for(int gap = len/2; gap > 0; gap /= 2){
        for(int i = gap; i < len; i++){
            int key = A[i];
            int j;
            for(j = i-gap; j>=0 && A[j] > key; j-= gap)
                A[j+gap] = A[j];
            A[j+gap] = key;
        }
    }
}

 

 

冒泡排序(bubble sort) 

思想:從左往右遍歷,比較相鄰兩個元素的大小,將大的一個放在后面,每遍歷一趟,可找到一個最大值放置在最后,經過n-1趟遍歷即可。

性能:時間復雜度為O(n2),元素比較次數與初始狀態無關,性能略低於插入排序。

 

void Bubble_Sort(int* A,int len){
        for(int i=1;i<len;i++)
                for(int j=0;j<len-i;j++)
                {
                        if(A[j]>A[j+1]){
                                int t = A[j+1];
                                A[j+1] = A[j];
                                A[j] = t;
                        }
                }
}

 

歸並排序(merge sort)

思想:使用分治思想,將原始序列分為兩部分分別排序,然后合並,重點在於合並過程。

性能:時間復雜度為O(nlgn),不過合並過程會使用額外的存儲空間,占用內存。

 

void Merge(int A[], int low, int mid, int high){
        int cp[high-low+1];
        for(int i = low; i <= high; i++)
            cp[i-low] = A[i];
        int l = low, r = mid+1;
        for(int i = low; i <= high; i++){
            if(l > mid) {A[i] = cp[r - low]; r++;}
            else if(r > high) {A[i] = cp[l - low]; l++;}
            else if(cp[l-low] <= cp[r-low]) {A[i] = cp[l -low]; l++;} 
            else {A[i] = cp[r -low]; r++;}
        }
}    

void Merge_Sort(int A[], int low, int high){
        if(high > low){
                int mid = (low+high)/2;
                Merge_Sort(A, low, mid);
                Merge_Sort(A, mid+1, high);
                Merge(A, low, mid, high);
        }
}

 

 

 

 

快速排序(quick sort)

思想:與歸並排序類似,也使用分治思想,選擇一個元素值(一般選擇最后一個元素),將比它小的放在左邊部分,比它大的放在右邊,然后對兩部分分別進行上述操作知道遞歸結束,關鍵步驟在於元素的分類,且只占用O(1)的額外存儲空間。

性能:時間復雜度為O(nlgn),與歸並排序不同,該算法占用常數級額外存儲,在大規模序列排序應用中性能較好。

 

int patition(int* p, int left, int right){
    int key = p[left];
    while(left < right){
        while(left<right && key <= p[right]) right--;
        if(left<right) p[left++] = p[right];
        while(left<right && key >= p[left]) left++;
        if(left<right) p[right--] = p[left];
    }
    p[left] = key;
    return left;
}

void quick_sort(int* p, int left, int right){
    if(left >= right) return;
    int mid = patition(p, left, right);
    quick_sort(p, left, mid-1);
    quick_sort(p, mid+1, right);
}

 

 

 

堆排序(heap sort)

思想:使用堆數據結構進行排序,堆是一種用數組存儲的二叉樹,根據父節點和子節點的大小關系分為最大堆和最小堆,這里使用最大堆進行排序。

性能:時間復雜度為O(nlgn),在實際使用中,堆排序的排序性能通常遜與快速排序。

void Max_Heapify(int* A, int i,int size){
        int l = 2*i;
        int r = 2*i + 1;
        int large = i;
        if(l <= size && A[l] > A[i])
                large = l;
        else
                large = i;
        if(r <= size && A[r] > A[large])
                large = r;
        if(large != i){
        int t = A[large];
        A[large] = A[i];
        A[i] = t;
        Max_Heapify(A, large, size);
        }
}

void Build_Max_Heap(int* A, int size){
        for(int i=size/2;i>0;i--)
                Max_Heapify(A,i,size);
}
  
void Heap_Sort(int* A, int len){
        Build_Max_Heap(A, len);
        while(len-1){
                int t = A[1];
                A[1] = A[i];
                A[i] = t;
                len--;
                Max_Heapify(A,1,len);
        }
}

  

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM