日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

十种经典排序算法精粹(c语言版本)

發(fā)布時(shí)間:2023/11/27 生活经验 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 十种经典排序算法精粹(c语言版本) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

下面給出這段時(shí)間我苦心研究驗(yàn)證過的十種經(jīng)典排序算法的C語言版本,即下面的排序算法:

插入排序,shell排序,冒泡排序,快速排序,選擇排序,堆排序,歸并排序,桶排序,基數(shù)排序和計(jì)數(shù)排序。整理出來以作備忘,不足之處,歡迎大家批評(píng)指正!其中計(jì)數(shù)排序分別給出了不穩(wěn)定和穩(wěn)定兩種排序算法,測(cè)試時(shí),使用隨機(jī)生成大數(shù)組和隨機(jī)手動(dòng)輸入的方法來測(cè)試。

//description: 這里給出了c語言版本的10種排序算法
//refer: 參考自Weiss的教材及網(wǎng)上資料
//compile: gcc -g sort_demo.c -o sort_demo
//author: tao_627@aliyun.com
//date: 2019-03-12#include <stdio.h>
#include <stdlib.h>
#include <string.h>void swap(int arr[], int a, int b){int tmp = arr[a];arr[a] = arr[b];arr[b] = tmp;
}void insert_sort(int arr[], int n){int i,j,t;//遍歷未排序集,默認(rèn)第一個(gè)元素(i=0)是有序集內(nèi)的for(i=1; i<n; i++){t=arr[i];//在有序集內(nèi)從后往前逐個(gè)比較,將大的元素逐個(gè)后移一位for(j=i; j>0 && t<arr[j-1]; j--)arr[j]=arr[j-1];arr[j]=t;}
}void shell_sort(int arr[], int n){int i,j,t,gap;for(gap=n/2; gap>0; gap/=2){for(i=gap; i<n; i++){t=arr[i];for(j=i; j>=gap && t<arr[j-gap]; j-=gap)arr[j] = arr[j-gap];arr[j]=t;}}
}void bubble_sort(int arr[], int n){int i,j,t;for(i=0; i<n-1; i++){for(j=0; j<n-1-i; j++){if(arr[j]>arr[j+1])swap(arr, j, j+1);}}
}void quick_sort(int arr[], int left, int right){int i,j,pivot;if(left>right)return;pivot=arr[left];i=left;j=right;while(i!=j){while(arr[j]>=pivot && i<j)j--;while(arr[i]<=pivot && i<j)i++;if(i<j)swap(arr, i, j);}swap(arr, left, i);quick_sort(arr, left, i-1);quick_sort(arr, i+1, right);
}void select_sort(int arr[], int n){int i,j,min;for(i=0; i<n-1; i++){min=i;for(j=i+1; j<n; j++){if(arr[min]>arr[j])min=j;}if(min!=i)swap(arr, min, i);}
}#define LeftChild(i) (2*(i) + 1)//構(gòu)建以arr[i]為根的最大堆
void heap_adjust(int arr[], int i, int n){int child,t;for(t=arr[i]; LeftChild(i)<n; i=child){child=LeftChild(i);//如果存在右子節(jié)點(diǎn)且右子節(jié)點(diǎn)值更大,選右子節(jié)點(diǎn)if(child!=n-1 && arr[child+1]>arr[child])child++;if(t<arr[child])arr[i]=arr[child];//如果子節(jié)點(diǎn)值更大,賦給父節(jié)點(diǎn)elsebreak;}//當(dāng)前的i值一直在變化arr[i]=t;
}void heap_sort(int arr[], int n){int i;//構(gòu)建n個(gè)元素組成的最大堆for(i=n/2; i>=0; i--)heap_adjust(arr, i, n);for(i=n-1; i>0; i--){swap(arr, 0, i);heap_adjust(arr, 0, i);}
}//lb=start of left half, le=end of left half;
//rb=start of right half, re=end of right half;
void merge(int arr[], int tmp_arr[], int lb, int rb, int re){int i, le, total, tmp;le=rb-1;tmp=lb;total=re-lb+1;while(lb<=le && rb<=re){if(arr[lb]<=arr[rb])tmp_arr[tmp++]=arr[lb++];elsetmp_arr[tmp++]=arr[rb++];}while(lb<=le)tmp_arr[tmp++]=arr[lb++];while(rb<=re)tmp_arr[tmp++]=arr[rb++];//copy tmp_array backfor(i=0; i<total; i++, re--)arr[re]=tmp_arr[re];
}void msort(int arr[], int tarr[], int left, int right){int center;if(left<right){center=(left+right)/2;msort(arr, tarr, left, center);msort(arr, tarr, center+1, right);merge(arr, tarr, left, center+1, right);}
}void merge_sort(int arr[], int n){int* tmp_arr = malloc(n * sizeof(int));if(tmp_arr != NULL){msort(arr, tmp_arr, 0, n-1);free(tmp_arr);}else{printf("No enough memory space for temp array!!!");exit(-1);}
}#define BUCKET_DEPTH (10)typedef struct bucket {int node[BUCKET_DEPTH]; //假設(shè)每個(gè)桶最多裝10個(gè)相同元素int count; //該桶中當(dāng)前元素個(gè)數(shù)
} bucket;void bucket_sort(int arr[], int n){int max, min, num, pos;int i,j,idx;//統(tǒng)計(jì)待排序數(shù)組的最大值和最小值max=min=arr[0];for(i=1; i<n; i++){if(max<arr[i])max=arr[i];if(min>arr[i])min=arr[i];}//計(jì)算桶的個(gè)數(shù),每個(gè)桶至多10個(gè)元素num=(max-min+1)/BUCKET_DEPTH+1;bucket* pb=(bucket*)malloc(sizeof(bucket)*num);if(pb==NULL){printf("No enough memory space for allocate bucket array!!!");exit(-1);}memset(pb, 0, sizeof(bucket)*num);//將數(shù)組中的數(shù)據(jù)放入所屬的桶內(nèi)for(i=0; i<n; i++){//計(jì)算該元素所在的桶索引idx=(arr[i]-min+1)/BUCKET_DEPTH;//判斷是否有足夠的位置if(pb[idx].count>BUCKET_DEPTH){printf("FATAL: bucket [%d] has no enough space to store item!!!", pb[idx].count);exit(-1);}//放元素進(jìn)桶內(nèi)pb[idx].node[pb[idx].count++]=arr[i];}pos=0;//按順序逐個(gè)輸出桶內(nèi)的元素,桶內(nèi)元素采用快速排序for(i=0; i<num; i++){//僅對(duì)非空的桶執(zhí)行快速排序if(pb[i].count>0)quick_sort(pb[i].node, 0, pb[i].count-1);for(j=0; j<pb[i].count; j++){arr[pos++]=pb[i].node[j];}}free(pb);
}//判斷一個(gè)整數(shù)是幾位數(shù)
int get_num_digit(int num){int count=0;while(num!=0){num /= 10;count++;}return count;
}//提取指定整數(shù)位上的數(shù)字
int get_pos_digit(int num, int pos){int multiple=1, i;for(i=0; i<pos-1; i++){multiple *= 10;}return (num/multiple)%10;
}#define RDX_WIDTH 10
#define MAX_NUM_LEN 32void radix_sort(int arr[], int n){//分別為0-9的序列空間int* rdx_arr[RDX_WIDTH];int i, k, pos;for(i=0; i<RDX_WIDTH; i++){//每個(gè)桶最多順序存放n個(gè)數(shù)(注意數(shù)組是有順序的)rdx_arr[i]=(int*)malloc(sizeof(int) * (n+1));//索引為0處記錄這個(gè)數(shù)組的個(gè)數(shù)rdx_arr[i][0]=0;}//找到這個(gè)數(shù)組的最大數(shù)及其位數(shù)int max=arr[0];for(i=0; i<n; i++){if(max<arr[i])max=arr[i];}int max_dig_num=MAX_NUM_LEN;int dig_num=get_num_digit(max);//確定當(dāng)前最多需要幾位數(shù)的循環(huán)if(dig_num<max_dig_num)max_dig_num=dig_num;//printf("max number:%d, max digit number of max number:%d\n", max, max_dig_num);//從最低有效位開始遍歷,一直到第高有效位for(pos=1; pos<=max_dig_num; pos++){//printf("digit position [%d]:\n", pos);//分配到不同的桶里int digit, idx=0;for(i=0; i<n; i++){//數(shù)位從1開始digit = get_pos_digit(arr[i], pos);rdx_arr[digit][0]++;idx = rdx_arr[digit][0];rdx_arr[digit][idx]=arr[i];//printf("%d, pos %d, digit %d, entry index %d, number in radix bucket %d\n", arr[i], pos, digit, idx, rdx_arr[digit][idx]);}//收集并重新排序數(shù)組同時(shí)清空每個(gè)桶內(nèi)數(shù)組int j=0;for(i=0; i<RDX_WIDTH; i++){//跳過那些空桶if(rdx_arr[i][0]==0)continue;//printf("bucket [%d], entry number:%d\n", i, rdx_arr[i][0]);//輸出每個(gè)桶內(nèi)的數(shù)據(jù)for(k=1; k<=rdx_arr[i][0]; k++){arr[j++]=rdx_arr[i][k];//打印出該位數(shù)對(duì)應(yīng)的桶內(nèi)的數(shù)字//printf("%d ", rdx_arr[i][k]);}//printf("\n");//讓桶內(nèi)數(shù)據(jù)清空,以免影響下個(gè)數(shù)位的排序for(k=0; k<=n; k++)rdx_arr[i][k]=0;}/*printf("\n");//打印出本次排序的數(shù)組for(i=0; i<n; i++)printf("%d ", arr[i]);printf("\n-------------------\n");*/}//釋放內(nèi)存for(i=0; i<RDX_WIDTH; i++)free(rdx_arr[i]);
}//非穩(wěn)定計(jì)數(shù)排序算法
void count_sort(int arr[], int n){int max, min, range, i;//統(tǒng)計(jì)該數(shù)組的最大值和最小值max=min=arr[0];for(i=1; i<n; i++){if(max<arr[i])max=arr[i];if(min>arr[i])min=arr[i];}//申請(qǐng)輔助計(jì)數(shù)數(shù)組,并初始化range=max-min+1;int* parr=(int*)malloc(sizeof(int) * range);if(parr==NULL){printf("FATAL: no enough memory space to allocate counting array!!!");exit(-1);}memset(parr, 0, sizeof(int) * range);//統(tǒng)計(jì)數(shù)組中每個(gè)元素出現(xiàn)的次數(shù)for(i=0; i<n; i++)parr[arr[i]-min]++;//輸出排序數(shù)組int idx=0;for(i=0; i<range; i++)while(parr[i]--){arr[idx++]=i+min;}//釋放資源free(parr);
}//穩(wěn)定性計(jì)數(shù)排序算法
void count_sort_v2(int arr[], int n){int max, min, range, i;//統(tǒng)計(jì)該數(shù)組的最大值和最小值max=min=arr[0];for(i=1; i<n; i++){if(max<arr[i])max=arr[i];if(min>arr[i])min=arr[i];}//申請(qǐng)輔助計(jì)數(shù)數(shù)組,并初始化range=max-min+1;//printf("max:%d, min:%d, range:%d\n", max, min, range);int* parr=(int*)malloc(sizeof(int) * (range+1));if(parr==NULL){printf("FATAL: no enough memory space to allocate counting array!!!");exit(-1);}memset(parr, 0, sizeof(int) * (range+1));//動(dòng)態(tài)分配一個(gè)臨時(shí)數(shù)據(jù)用來存放排序后的數(shù)組數(shù)據(jù)int *tmp;if((tmp=(int*)malloc(sizeof(int) * (n+1))) == NULL){printf("FATAL: no enough memory space to store sorted array!!!");exit(-1);}memset(tmp, 0, sizeof(int)*(n+1));//統(tǒng)計(jì)數(shù)組中每個(gè)元素出現(xiàn)的次數(shù)for(i=0; i<n; i++){parr[arr[i]-min]++;}
/*for(i=0; i<range; i++)printf("%d ", parr[i]);printf("\n");
*///調(diào)整計(jì)數(shù)數(shù)組的值以反映它前面的數(shù)組偏移for(i=1; i<range; i++)parr[i] += parr[i-1];
/*for(i=0; i<range; i++)printf("%d ", parr[i]);printf("\n");
*///用計(jì)數(shù)去定位它所在的每個(gè)元素(逆序)//現(xiàn)在parr包含每個(gè)元素在有序數(shù)組中的偏移量for(i=n-1; i>=0; i--){//arr[i]在有序數(shù)組中的偏移是parr[arr[i]-min]-1tmp[parr[arr[i]-min] - 1] = arr[i];parr[arr[i]-min]--;}
/*for(i=0; i<n; i++)printf("%d ", tmp[i]);printf("\n");
*///復(fù)制排序數(shù)組到原來的數(shù)組中memcpy(arr, tmp, sizeof(int) * n);
/*for(i=0; i<n; i++)printf("%d ", arr[i]);printf("\n");
*///釋放資源free(parr);free(tmp);
}//------------------- test framework------------------------//生成指定大小的隨機(jī)數(shù)組
void generate_array(int arr[], int n){int i;for(i=0; i<n; i++)arr[i] = i;for(i=0; i<n; i++){int j=rand()%(i+1);if(i != j)swap(arr, i, j);}//將最后排序的數(shù)組打印出來/*for(i=0; i<n; i++)printf("%d ", i);printf("\n"); */
}//檢查排序之后的數(shù)組
void check_sorted_array(int arr[], int n){int i, fail=0;for(i=0; i<n; i++)if(arr[i] != i){fail++;printf("sort fails: idx:%d, arr[idx]:%d\n", i, arr[i]);}printf("check sorted array completed, fail total:%d\n", fail);
}//復(fù)制指定大小的數(shù)組內(nèi)容
void copy_array(int lhs[], const int rhs[], int n){int i;for(i=0; i<n; i++)lhs[i] = rhs[i];
}#define MaxSize 7000
int Arr1[ MaxSize ] = {};
int Arr2[ MaxSize ] = {};int main(){int i;//連續(xù)進(jìn)行10次各種排序算法的測(cè)試for(i=0; i<10; i++){generate_array(Arr2, MaxSize);copy_array(Arr1, Arr2, MaxSize);insert_sort(Arr1, MaxSize);check_sorted_array(Arr1, MaxSize);printf("----------insert sort ok--------\n");copy_array(Arr1, Arr2, MaxSize);shell_sort(Arr1, MaxSize);check_sorted_array(Arr1, MaxSize);printf("----------shell sort ok--------\n");copy_array(Arr1, Arr2, MaxSize);bubble_sort(Arr1, MaxSize);check_sorted_array(Arr1, MaxSize);printf("----------bubble sort ok--------\n");copy_array(Arr1, Arr2, MaxSize);quick_sort(Arr1, 0, MaxSize-1);check_sorted_array(Arr1, MaxSize);printf("----------quick sort ok--------\n");copy_array(Arr1, Arr2, MaxSize);select_sort(Arr1, MaxSize);check_sorted_array(Arr1, MaxSize);printf("----------select sort ok--------\n");copy_array(Arr1, Arr2, MaxSize);heap_sort(Arr1, MaxSize);check_sorted_array(Arr1, MaxSize);printf("----------heap sort ok--------\n");copy_array(Arr1, Arr2, MaxSize);merge_sort(Arr1, MaxSize);check_sorted_array(Arr1, MaxSize);printf("----------merge sort ok--------\n");copy_array(Arr1, Arr2, MaxSize);bucket_sort(Arr1, MaxSize);check_sorted_array(Arr1, MaxSize);printf("----------bucket sort ok--------\n");copy_array(Arr1, Arr2, MaxSize);radix_sort(Arr1, MaxSize);check_sorted_array(Arr1, MaxSize);printf("----------radix sort ok--------\n");copy_array(Arr1, Arr2, MaxSize);count_sort(Arr1, MaxSize);check_sorted_array(Arr1, MaxSize);printf("----------count sort ok--------\n");copy_array(Arr1, Arr2, MaxSize);count_sort_v2(Arr1, MaxSize);check_sorted_array(Arr1, MaxSize);printf("----------count sort2 ok--------\n");}return 0;
}//--------------------------------------------------/*
int main(){int i,j,t;int a[50], n;//讀入數(shù)據(jù)printf("please input array size(<=50):\n");scanf("%d\n", &n);for(i=0; i<n; i++)scanf("%d", &a[i]);//使用各種算法排序//insert_sort(a, n);//shell_sort(a, n);//bubble_sort(a, n);//quick_sort(a, 0, n-1);//select_sort(a, n);//heap_sort(a, n);//merge_sort(a,n);//bucket_sort(a, n);//radix_sort(a, n);//count_sort(a, n);//count_sort_v2(a, n);//輸出排序之后的結(jié)果for(i=0; i<n; i++)printf("%d ", a[i]);printf("\n");//暫停退出,等待用戶輸入getchar();return 0;
}
*/

下面是快速排序的運(yùn)行截圖:

?

參考文獻(xiàn)

[1].Weiss《數(shù)據(jù)結(jié)構(gòu)與算法分析:c語言描述》(第二版)第七章

[2].Kyle Loudon著,肖翔,陳舸譯《算法精解--c語言描述》(中文版)p.255

總結(jié)

以上是生活随笔為你收集整理的十种经典排序算法精粹(c语言版本)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。