C语言排序算法 选择排序 插入排序 快速排序 qsort实现快排 堆排序
常見排序算法
選擇排序
選擇排序(Selection sort)是一種簡單直觀的排序算法。 它的工作原理如下。 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再從剩余未排序元素中繼續尋找最小(大)元素,然后放到已排序序列的末尾。 以此類推,直到所有元素均排序完畢。
插入排序
插入排序(英語:Insertion Sort)是一種簡單直觀的排序算法。 它的工作原理是通過構建有序序列,對于未排序數據,在已排序序列中從后向前掃描,找到相應位置并插入。
快速排序
快速排序使用分治法(Divide and conquer)策略來把一個序列(list)分為兩個子序列(sub-lists)。
除了以下代碼的實現外,可以用C語言提供的qsort函數進行快排。
步驟為:
1、從數列中挑出一個元素,稱為“基準”(pivot),
2、重新排序數列,所有比基準值小的元素擺放在基準前面,所有比基準值大的元素擺在基準后面(相同的數可以到任何一邊)。在這個分割結束之后,該基準就處于數列的中間位置。這個稱為分割(partition)操作。
3、遞歸地(recursively)把小于基準值元素的子數列和大于基準值元素的子數列排序。
4、遞歸到最底部時,數列的大小是零或一,也就是已經排序好了。這個算法一定會結束,因為在每次的迭代(iteration)中,它至少會把一個元素擺到它最后的位置去。
堆排序
堆排序(英語:Heapsort)是指利用堆這種數據結構所設計的一種排序算法。堆是一個近似完全二叉樹的結構,并同時滿足堆積的性質:即子結點的鍵值或索引總是小于(或者大于)它的父節點。
輸出
第一行為排序前
第二行為排序后
代碼(均為數組操作)
1、思路:先生成隨機數,然后對生成的隨機數進行排序。
以下分別是:選擇排序 插入排序 快速排序 qsort實現快排 的函數(都經過測試,可以調用)
2、關于宏定義
#define SWAP(a,b) {int tmp;tmp=a;a=b;b=tmp;}采用宏定義的方法實現的交換,因為該交換的使用頻次過高,調用函數反而會因函數的壓棧、彈棧增加了算法的執行時間,所以這里不用函數
#include<stdio.h> #include<stdlib.h> #include<time.h> #define N 10000 #define SWAP(a,b) {int tmp;tmp=a;a=b;b=tmp;} //打印 void arr_print(int *arr) {int i;for (i = 0; i < N; i++){printf("%d ", arr[i]);}printf("\n"); } //選擇排序 void arr_select(int *arr) {int i, j, max_pos;for (i = N; i > 0; i--)//最大的數放在最右邊{max_pos = 0;for (j = 1; j < i; j++)//找出左邊剩余的i個數中最大的數{if (arr[max_pos] < arr[j]){max_pos = j;}}SWAP(arr[max_pos], arr[i - 1]);//最大的數交換到右邊} } //插入排序 void arr_insert(int *arr) {int i, j, k, insert_val;for (i = 1; i < N; i++)//外層控制對哪個數進行插入(從arr[0]到arr[i-1]是有序的){for (j = 0; j < i; j++)//內層控制尋找插入位置{if (arr[i] < arr[j])//發現插入位置{insert_val = arr[i];for (k = i - 1; k >= j; k--)//從插入點開始的數全部向右移{arr[k + 1] = arr[k];}arr[j] = insert_val;break;}}} } //快速排序 int partition(int *arr, int left, int right) {int i, k;k = left;//k是游標,k=left用來表示比末尾數小的起始位置,注意不能寫成k=0for (i = left; i < right; i++)//遞歸用left和right控制邊界{if (arr[right] > arr[i]){SWAP(arr[k], arr[i]);k++;}}SWAP(arr[k], arr[right]);//把分界線換到中間return k; } void arr_quick(int *arr, int left, int right) {int pivot;//分割if (left < right){pivot = partition(arr, left, right);//遞歸,返回值為分界線arr_quick(arr, left, pivot - 1);//排左邊arr_quick(arr, pivot + 1, right);//排右邊} } //用qsort實現快排 int compare(const int *left, const int *right)//要有自己寫的排序規則 {if (*left > *right){return 1;}else if (*left == *right){return 0;}else return -1; } //堆排序:運用二叉樹的思想(將數的大小分層級)對一位數組進行排序 void heap_max(int *arr, int start, int end)//end控制邊界,防止son訪問越界 {int dad = start;int son = 2 * dad + 1;while (son < end)//控制邊界,防止son訪問越界{if (son + 1 < end&&arr[son] < arr[son + 1]){son++;}if (arr[dad] > arr[son]){return;}else{SWAP(arr[dad], arr[son]);dad = son;//交換之后,考慮下一級別的大小關系是否因為本次交換而發生了改變son = 2 * dad + 1;}} } void arr_heap(int *arr) {int i;for (i = N / 2 - 1; i >= 0; i--)//變成大頂堆(把最大的元素放到根部),2/N-1是最后一個父節點所在的位置{heap_max(arr, i, N);}SWAP(arr[0], arr[N - 1]);//根元素放到數組最后一個元素for (i = N - 1; i > 0; i--)//把后N-1個元素分別用大頂堆的方式排好{heap_max(arr, 0, i);//重新調為大頂堆(把最大的元素放到根部),只需要將根部元素a[0]進行heap_max操作,就能重新讓根部元素成為最大元素,因為節點是分層級的SWAP(arr[0], arr[i - 1]);//根元素放到數組最后一個元素} } int main() {// int a[N];int *a = (int*)calloc(N, sizeof(int));//動態申請,防止數組需要的空間超過1M爆棧int i;srand(time(NULL));for (i = 0; i < N; i++)//生成隨機數{a[i] = rand() % 1000;}arr_print(a);//排序前 // arr_select(a);//選擇排序 // arr_insert(a);//插入排序 // arr_quick(a, 0, N - 1);//快速排序 // qsort(a, N, sizeof(int), compare);//數組名,元素個數,元素大小,自己寫的排序規則arr_heap(a);arr_print(a);//排序后system("pause"); } 超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的C语言排序算法 选择排序 插入排序 快速排序 qsort实现快排 堆排序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言 数据结构 二叉树实现、二叉树的三
- 下一篇: C语言 记录程序运行时间(以秒为单位)