C语言9种常用排序法1.冒泡排序2.选择排序3.插入排序4.快速排序5.希尔排序6.归并排序7.堆排序8.带哨兵的直接插入排序9.基数排序例子:乱序输入n个数,输出从小到大排序后的结果1.冒泡排序#include<stdio.h>int main(){int i, j, n, a[100], temp;while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%d",&a[i]);for(i=0;i<n-1;i++) //总共需冒泡n-1次{for(j=0;j<n-i-1;j++) //第i趟冒泡{if(a[j]>a[j+1]) //比较a[j]与a[j+1],使a[j+1]大于a[j] {temp = a[j+1];a[j+1] = a[j];a[j] = temp;}}}for(i=0;i<n;i++) //打印printf("%d ",a[i]);printf("\n");}return 0;}2.选择排序#include<stdio.h>int main(){int i, j, n, a[100], t, temp;while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%d",&a[i]);for(i=0;i<n-1;i++) //总共排序n-1趟{t = i;for(j=i+1;j<n;j++) //第i趟从a[i+1]~a[n-1]中选最小的数与a[i]交换 {if(a[t]>a[j])t = j;}temp = a[i];a[i] = a[t];a[t] = temp;}for(i=0;i<n;i++)printf("%d ",a[i]);printf("\n");}return 0;}3.快速排序/*1.假设数组为a[n];2.第一次排序过程如下:取x = 0 ( a[0]为中轴 );i=0 (第一个元素下标), j=n-1(最后一个元素下标);重复下面过程:(直到i>=j){从a[j]起,向前找小于a[x]的元素,同时j--,找到后,a[j]与a[x]交换,x=j;从a[i]起,向后找大于a[x]的元素,同时i++,找到后,a[i]与a[x]交换,x=i; }3.注意快排函数是迭代函数,必须要有结束条件 (因为忽略结束条件,调试了很久......)4.再对a[low]~a[x-1]、a[x+1]~a[high]分别调用快排函数*/#include<stdio.h>void quicksort(int a[],int low,int high);int main(){int i, n, a[100];while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%d",&a[i]);quicksort(a,0,n-1);for(i=0;i<n;i++)printf("%d ",a[i]);printf("\n");}return 0;}void quicksort(int a[],int low,int high){if(low>=high) return; //坑爹的结束条件,return后面不能跟数值 int i=low, j= high, x=i, temp;while(i<j){for(;a[j]>=a[x]&&i<j;j--);if(i<j){temp = a[j];a[j] = a[i];a[i] = temp;x = j;i++;}elsebreak; //i>=j即可跳出本次while循环for(;a[i]<=a[x]&&i<j;i++);if(i<j){temp = a[i];a[j] = temp;x = i;j--;}elsebreak; //跳出本次while循环 }quicksort(a,low,x-1);quicksort(a,x+1,high);}4.插入排序法#include<stdio.h>void show(int a[],int n) //输出数组{int i;for(i=0;i<n;i++)printf("%d ",a[i]);printf("\n");}void insertsort(int a[],int n);int main(){while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%d",&a[i]);insertsort(a,n);show(a,n);}return 0;}void insertsort(int a[],int n){int i ,j ,k ,temp;for(i=1;i<n;i++) //插入a[i]{j=i-1;for(;a[i]<a[j]&&j>=0;j--); //寻找插入点j++;if(j==i) //该数有序,不需要前插continue;else{temp=a[i];for(k=i-1;k>=j;k--) //将插入点后面的数依次后移一位 {a[k+1]=a[k];}}}}5.shell排序法#include<stdio.h>void show(int a[],int n) //输出数组{int i;for(i=0;i<n;i++)printf("%d ",a[i]);printf("\n");}void shellsort(int a[],int n);int main(){int i, n, a[100];while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%d",&a[i]);shellsort(a,n);show(a,n);}return 0;}void shellsort(int a[],int n){int k ,i ,j ,l ,temp;k = n/2;while(k>=1){for(i=k;i<n;i++){if(a[i]>=a[i-k]) //已经有序,不需要移动continue;else{for(j=i-k;a[j]>=a[i]&&j>=0;j=j-k); j+=k; //寻找插入点a[j] temp = a[i]; // 保存a[i]for(l=i-k;l>=j;l-=k) //依次向后移动k个位置{a[l+k] = a[l];}a[j]=temp; //插入}}k = k/2;}}6.归并排序归并排序是一种很容易进行并行化的算法,因为归并的各个数据区间都是独立的,没有依赖关系。
并且归并排序是一种速度比较快的排序,且是一种稳定的排序算法,排序速度与关键词初始排列无关。
串行归并排序的算法大体的可以描述为:首先将要排序的表分成两个节点个数基本相等的子表,然后对每个子表进行排序,最后将排好序的两个子表合并成一个子表。
在对子表进行排序时可以将子表再分解成两个节点数量基本相同的子表,当子表足够小时,也可以采用其他排序方法对子表进行排序,然后再对排好序的子表进行归并操作,最后将整个表排好序算法流程图:/*伪代码:mergesort(int a[],int low,int high);if(high-low+1>2)执行如下几步:(3个及以上)mid = (0+n)/2;mergesort(a,low,mid-1);mergesort(a,mid,high);进行本轮二路归并;bsort(int low,int mid,int high);i=low,j=mid;while(i<mid&&j<=high){先归并入other[];}将剩下的归并入数组other[];将other[low~high],复制到a[low~high];else: (3个以下)if(a[low]>=a[high]) 交换a[low],a[high]; */#include<stdio.h>int other[100];void exchange(int *a,int *b){int t=*a;*a=*b;*b=t;}void show(int a[],int n) //输出数组{int i;for(i=0;i<n;i++)printf("%d ",a[i]);printf("\n");}void mergesort(int a[],int low,int high);int main(){int i, n, a[100];while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%d",&a[i]);mergesort(a,0,n-1);show(a,n);}return 0;}void mergesort(int a[],int low,int high) {if((high-low+1)>2) //含3个以上 {int mid = (high+low)/2;mergesort(a,low,mid);mergesort(a,mid+1,high);int i=low, j=mid+1, k=low;while(i<=mid&&j<=high){if(a[i]<=a[j]){other[k++]=a[i++]; }if(a[i]>a[j]){other[k++]=a[j++]; }}while(i<=mid){other[k++]=a[i++];}while(j<=high){other[k++]=a[j++];}for(i=low;i<=high;i++)a[i]=other[i];}else //含2及个以下{if(a[low]>a[high]){exchange(a+low,a+high); }}}7.堆排序//堆排序/*(堆是一个完全二叉树,根结点值最大(小))1.heapadjust(int a[],int i,int sizea) 功能:以a[i]为根,形成一个堆buildheap(int a[],int sizea) 功能:调用heapadjust(),使a[]形成一个堆 heapsort(int a[],int sizea) 功能:do{建堆,输出堆顶}while(堆不空) */#include<stdio.h>void show(int a[],int n) //输出数组{int i;for(i=0;i<n;i++)printf("%d ",a[i]);printf("\n");}void exchange(int *a,int *b){int t=*a;*a=*b;*b=t;}void heapadjust(int a[],int i,int sizea){int maxi=i;int l=2*i+1;int r=2*i+2;if(i<(sizea/2)) //a[i]为叶结点,则不需要调整{if(l<=(sizea-1)&&a[l]>a[i]) //左孩子比a[i]大的,取左孩子下标{maxi=l;}if(r<=(sizea-1)&&a[r]>a[maxi]) //右孩子最大,取右孩子下标{maxi=r;}if(maxi!=i) //取比根大的孩子,与根调换{exchange(&a[maxi],&a[i]);heapadjust(a,maxi,sizea); //跌倒,以a[maxi]为根,向下调整为大根堆。