常見排序算法代碼

1.插入排序

穩定空間複雜度O(1) 時間複雜度O(n^2) 最差情況:反序,需要移動n*(n-1)/2個元素最好情況:正序,不需要移動元素

void insertsort(int a[], int n) {     int i, j;     int tmp;

    for (i = 1; i < n; i++)     {         tmp = a[i];         for (j = i - 1; j >= 0 && a[j] > tmp; j--)             a[j + 1] = a[j];         a[j + 1] = tmp;     } }

 

2.冒泡排序

穩定空間複雜度O(1) 時間複雜度O(n^2) 最差情況:反序,需要交換n*(n-1)/2個元素最好情況:正序,不需要交換元素

void bubblesort(int a[], int n) {     int i, j;     int tmp;

    for (i = n - 1; i > 0; i--)         for (j = 0; j < i; j++)         {             if (a[j] > a[j + 1])             {                 tmp = a[j];                 a[j] = a[j + 1];                 a[j + 1] = tmp;             }         } }

 

3.選擇排序

不穩定空間複雜度O(1) 時間複雜度O(n^2) 最差情況:第一個元素爲最大元素,其餘元素正序,需要交換n-1個元素(例如:4 3 2 1)最好情況:正序,不需要交換元素

void selectsort(int a[], int n) {     int i, j, k;     int tmp;

    for (i = 0; i < n - 1; i++)     {         k = i;         for (j = i + 1; j < n; j++)         {              if (a[j] < a[k])                  k = j;         }         if (k != i)         {             tmp = a[i];             a[i] = a[k];             a[k] = tmp;         }     } }

 

4.希爾排序(縮小增量排序)

不穩定空間複雜度O(1) 時間複雜度優於插入排序,最壞情況下O(n^2) 最差情況:有n=2^k個元素,偶數位置上有n/2個同爲最大的元素,奇數位置上有n/2個同爲最小的元素,此時最優最後一趟進行插入排序(例如:1 5 2 6 3 7 4 8)最好情況:正序,不需要移動元素

void shellsort(int a[], int n) {     int i, j, increment;     int tmp;     for (increment = n / 2; increment > 0; increment /= 2)     {         for (i = increment; i < n; i++)         {             tmp = a[i];             for (j = i - increment; j >= 0 && tmp < a[j]; j -= increment)             {                 a[j + increment] = a[j];             }             a[j + increment] = tmp;         }     } }

5.堆排序

不穩定空間複雜度O(1) 時間複雜度O(nlogn)

#define leftchild(i) (2 * (i) + 1)

void percdown(int a[], int i, int n) {     int child;     int tmp;

    for (tmp = a[i]; leftchild(i) < n; i = child)     {         child = leftchild(i);         if (child != n - 1 && a[child + 1] > a[child])             child++;         if (tmp < a[child])             a[i] = a[child];         else             break;     }     a[i] = tmp; }

void heapsort(int a[], int n) {     int i;     int tmp;

    for (i = n / 2; i >= 0; i--)     {         percdown(a, i, n);     }     for (i = n - 1; i > 0; i--)     {         tmp = a[0];         a[0] = a[i];         a[i] = tmp;         percdown(a, 0, i);     } }

6.歸併排序

穩定空間複雜度O(n) 時間複雜度O(nlogn)

void merge(int a[], int tmparray[], int lpos, int rpos, int rightend) {     int i, leftend, numelements, tmppos;

    leftend = rpos - 1;     tmppos = lpos;     numelements = rightend - lpos + 1;

    while (lpos <= leftend && rpos <= rightend)     {         if (a[lpos] <= a[rpos])             tmparray[tmppos++] = a[lpos++];         else             tmparray[tmppos++] = a[rpos++];     }

    while (lpos <= leftend)         tmparray[tmppos++] = a[lpos++];     while (rpos <= rightend)         tmparray[tmppos++] = a[rpos++];

    for (i = 0; i < numelements; i++, rightend--)         a[rightend] = tmparray[rightend]; }

void msort(int a[], int tmparray[], int left, int right) {     int center;

    if (left < right)     {         center = (left + right) / 2;         msort(a, tmparray, left, center);         msort(a, tmparray, center + 1, right);         merge(a, tmparray, left, center + 1, right);     } }

void mergesort(int a[], int n) {     int *tmparray;

    tmparray = (int*)malloc(n * sizeof(int));     if (tmparray != NULL)     {         msort(a, tmparray, 0, n - 1);         free(tmparray);     }     else         printf("No space for tmp array!!!/n"); }

7.快速排序(當小於4個元素時,用到插入排序)

不穩定空間複雜度O(1) 時間複雜度O(nlogn) 最差情況:要排序的數組基本有序,樞紐每次取最大(小)元素,退化爲冒泡算法最好情況:樞紐兩邊元素個數基本相同

#define cutoff (3)

void swap(int *a, int *b) {     int tmp;     tmp = *a;     *a = *b;     *b = tmp; }

int median3(int a[], int left, int right) {     int center = (left + right) / 2;

    if (a[left] > a[center])         swap(&a[left], &a[center]);     if (a[left] > a[right])         swap(&a[left], &a[right]);     if (a[center] > a[right])         swap(&a[center], &a[right]);

    swap(&a[center], &a[right - 1]);     return a[right - 1]; }

void qsort(int a[], int left, int right) {     int i, j;     int pivot;

    if (left + cutoff <= right)     {         pivot = median3(a, left, right);         i = left;         j = right - 1;         for ( ; ; )         {             while (a[++i] < pivot) {}             while (a[--j] > pivot) {}             if (i < j)                 swap(&a[i], &a[j]);             else                 break;         }         swap(&a[i], &a[right - 1]);

        qsort(a, left, i - 1);         qsort(a, i + 1, right);     }     else         insertsort(a + left, right - left + 1); }

void quicksort(int a[], int n) {     qsort(a, 0, n - 1); }

參考資料:

關於常見排序算法的穩定性分析和結論

排序算法歸總

《數據結構與算法分析—C語言描述》

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章