排序算法作為數據結構的重要部分,系統地學習一下是很有必要的。
十種常見排序算法可以分為兩大類:
比較類排序:通過比較來決定元素間的相對次序,由于其時間復雜度不能突破O(nlogn),因此也稱為非線性時間比較類排序。
非比較類排序:不通過比較來決定元素間的相對次序,它可以突破基于比較排序的時間下界,以線性時間運行,因此也稱為線性時間非比較類排序。
全部排序代碼整理:
鏈接:https://pan.baidu.com/s/1c02Nfm8PjXg0PQtFRv6F1A
提取碼:rjnq
1、冒泡排序
它重復地走訪過要排序的元素列,依次比較兩個相鄰的元素
void
2、選擇排序
選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工作原理是:第一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,然后再從剩余的未排序元素中尋找到最小(大)元素,然后放到已排序的序列的末尾。以此類推,直到全部待排序的數據元素的個數為零。
void SelectSort(int arr[], int n)
{for (int i = 0; i < n - 1; i++){for (int j = i + 1; j < n; j++){if (arr[i] > arr[j]){swap(arr, i, j); //交換arr數組arr[i]和arr[j]的值}}}
}
3、插入排序
插入排序的基本操作就是將一個數據插入到已經排好序的有序數據中,從而得到一個新的、個數加一的有序數據
void InsertSort(int arr[], int n)
{int tempVal;for (int i = 1, j; i < n; i++){tempVal = arr[i]; //保存要插入的值for (j = i - 1; tempVal < arr[j] && j >= 0; --j) //數據往后移動,給要插入的值騰位{arr[j + 1] = arr[j];}arr[j + 1] = tempVal; //插入數據}
}
4、快速排序
通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然后再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列
void Quicksort(int a[], int low, int high)
{if (low >= high){return;}int first = low;int last = high;int key = a[first];while (first<last){while (first < last && a[last] >= key) //從右往左找一個比arr[left]小的值{--last;}a[first] = a[last];while (first < last && a[first] <= key) //從左往右找一個比arr[left]要大的值{++first;}a[last] = a[first];}a[first] = key;Quicksort(a, low, first - 1); //排左邊Quicksort(a, last + 1, high); //排右邊
}
5、希爾排序
希爾排序,也稱遞減增量排序算法,是插入排序的一種更高效的改進版本。但希爾排序是非穩定排序算法。插入排序是將未排序的數字插入到已排序數列中,而希爾排序是將一個已排序的數列插入到另一個已排序的數列中。
void ShellSort(int arr[], int n)
{int tempVal, j;int jump = n >> 2; //步長值while (jump != 0){for (int i = jump; i < n; i++){tempVal = arr[i]; //保存待排序的第一個數,也就是待插入的數for (j = i - jump; j >= 0 && tempVal < arr[j]; j -= jump){arr[j + jump] = arr[j];}arr[j + jump] = tempVal;}jump = jump >> 1; //步長值減半}
}
6、歸并排序
將已有序的子序列合并,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合并成一個有序表
void MergeSort(int arr[], int left, int right)
{if (left >= right)//遞歸的終止條件,left == right證明這個區間只有一個元素,不需要再拆了return;int mid = ((right - left) >> 1) + left;//求中點MergeSort(arr, left, mid); //拆分左MergeSort(arr, mid + 1, right); //拆分右//并操作_merge_in_arr(arr, left, mid, right);
}void _merge_in_arr(int arr[], int left, int mid, int right)
{int length = right - left + 1; //定義一個輔助的空間的長度int *pData = (int*)malloc(sizeof(int)*length);//分配一個動態內存來調整元素的位置memset(pData, 0, sizeof(int)* length);//合并int low = left; //左邊區間的起始下標int hig = mid + 1; //右邊區間的起始下標int index = 0; //輔助數組的下標while (hig <= right)//右區間沒有合并完{while (low <= mid && arr[low] <= arr[hig])//證明左區間沒有合并完,且左區間的值小于右區間的值{pData[index] = arr[low]; //把左邊的值放進輔助數組low++; //左邊往高位移,下一次需要判斷左邊的新下標index++; //下一次放進輔助數組的新下標}if (low > mid) //證明左區間已經放完break;while (hig <= right && arr[low] > arr[hig])//證明右區間沒有合并完,且左區間的值大于右區間的值{pData[index] = arr[hig]; //把右邊的值放進輔助數組hig++; //右邊往高位移,下一次需要判斷右邊的新下標index++; //下一次放進輔助數組的新下標}}//到這一步,證明起碼有一個區間已經合并完成if (hig <= right) //證明右邊沒有完成memmove(&pData[index], &arr[hig], sizeof(int)* (right - hig + 1));if (low <= mid) //證明左邊沒有完成memmove(&pData[index], &arr[low], sizeof(int)* (mid - low + 1));//把所有區間都合并到了輔助區間memmove(&arr[left], pData, sizeof(int)* length);free(pData); //釋放空間
}
7、桶(基數)排序
桶排序是典型的空間換時間,在對整數排序中,沒有什么算法能比它還快,但是在空間浪費上,它是祖宗。
void radix_sort(int arr[], size_t len)
{int**temp = (int **)malloc(sizeof(int) * 10); //10行//申請動態內存 輔助數組temp[10][];for (int i = 0; i < 10; i++){temp[i] = (int *)malloc(sizeof(int)*len);}for (int i = 1; i <= 100; i *= 10)//循環數值可能有的位數{for (int x = 0; x < 10; ++x)//輔助數組行循環{for (int y = 0; y < len; ++y)//輔助數組列循環{temp[x][y] = -1;//輔助數組的初始化賦值,-1表示在arr里面不可能出現的數值 }}//arr數組中的元素放入輔助數組for (int m = 0; m < len; ++m){int index = (arr[m] / i) % 10;temp[index][m] = arr[m];}//把輔助數組的內容放回待排序數組int k = 0;//待排序的下標for (int x = 0; x < 10; x++){for (int y = 0; y < len; ++y){if (temp[x][y] != -1)arr[k++] = temp[x][y];}}}//釋放內存for (int i = 0; i < 10; i++){free(temp[i]);}free(temp);
}
在這里我列舉了7中常見的排序算法并用C語言實現,你們可能就要問了,不是十種嗎?怎么還能缺斤短兩,不是我不會寫啊,是寫起來麻煩,你們也用不到后面那幾種,跟別說去研究了,能看懂常見的七種排序算法你就能在學校里橫著走了。
編輯:夢凡
微信公眾號:編程學習基地
總結
以上是生活随笔為你收集整理的c语言sort_C语言十大排序算法,让老师对你刮目相看的技巧的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。