常用排序一览

来源:互联网 发布:文思海辉金信软件 编辑:程序博客网 时间:2024/06/07 07:05
#include <stdio.h>//定义一个返回值为int,参数为(int,int)的函数指针类型为cmptypedef int (*cmp)(int, int);void printA (int num[], int len){int i;for (i = 0;i < len; i++)printf ("%d ",num[i]);putchar ('\n');}//交换void swap (int a[], int i, int j){int tmp = a[i];a[i] = a[j];a[j] = tmp;}//升序判断int cmp_up (int a, int b)   {return (a - b);}//降序判断int cmp_down (int a, int  b){return (b - a);}/*  1、sort()函数中回调 cmp_down()和cmp_up()函数;2、函数通过cmp类型的函数指针func传入。*///冒泡排序void bubble_sort (int num[], int len, cmp func){ int i, j;for (i = 0; i < len-1; i++)     //N个数比较N-1轮{for (j = 0; j < len-i-1; j++)    //第i轮比较N-i-1次{//根据排序条件交换相邻两数if (func (num[j], num[j+1]) > 0)  {swap (num, j, j+1);}}}}//鸡尾酒排序void cocktail_sort (int num[], int len, cmp func){int i;int left  = 0;int right = len - 1;//从两端向中间查找最大和最小的元素 while (left < right){//向右查找最大的(小)元素放在最右边for (i = left;i < right; i++){if (func (num[i], num[i+1]) > 0)swap (num, i, i+1);}right--;  ////向左查找最小的(大)元素放在最左边for (i = right;i > left; i--){if (func (num[i], num[i-1]) < 0)swap (num, i, i-1);}left++;}}//选择排序void select_sort (int num[], int len, cmp func)   {int i, j;for (i = 0;i < len-1; i++)    //N个数比较N-1轮{int index = i;        //查找最小(大)元素及其下标for (j = i+1;j < len; j++)     {if (func (num[index], num[j]) > 0)//if (num[index] > num[j])index = j;}if (index != i)   //交换元素,将最小(大)元素换至当前最前面{swap (num, i, index);}}}//插入排序void insert_sort (int num[], int len, cmp func){int i, j, get;//默认第一个元素是排好序的,取后面的元素依次比较,//插入数列中第一个小于(大于)它的数的后面for (i = 1;i < len; i++){    get = num[i];    //记录取的数j = i-1;while (j >= 0 && (func(num[j],get) > 0)){num[j+1] = num[j];    //不满足条件的元素后移j--;}num[j+1] = get;    //插入元素}}//二分法插入排序void dic_sort (int num[], int len, cmp func){int left, right, mid, i, j, get;for (i = 1;i < len; i++){left  = 0;right = i;      //开始时左右边界分别为 0、iget   = num[i];while (left <= right){mid   = (left + right)/2;if ((func(num[mid], get)) > 0) //所取元素小于中间元素,插在中间元素前面{right = mid - 1;           //右边界改变}else                           //否则插在中间元素后面{left = mid + 1;            //左边界改变}}for (j = i-1;j >= left; j--)      {num[j+1] = num[j];            //插入位置后的元素后移}num[left] = get;                 //元素插入队列}}//希尔排序void shell_sort (int num[], int len, cmp func){    int i, j, get;    int gap = len;  //步长,即每组元素间的间隔//分组,对每组元素进行插入排序;//缩短步长,重新分组,直至步长为1,排序结束do{        gap = gap/3 + 1;for (i = gap;i < len; i++)    {    get = num[i];    //记录取的数    j = i-gap;while (j >= 0 && (func(num[j], get) > 0)){num[j+gap] = num[j];    //不满足条件的元素后移j -= gap;} num[j+gap] = get;}    //插入元素}while (gap > 1);}//堆调整//i 是需要调整的堆结点void heapify (int num[], int i, int len, cmp func){int left  = 2*i + 1;     //左结点int right = 2*i + 2;     //右结点int max = i;//找元素最大的结点if  (left < len && (func (num[left], num[max]) > 0)){max = left;}if (right < len && (func (num[right], num[max]) > 0)){max = right;}//最大结点与其根结点交换if (max != i){swap (num, max, i);heapify (num, max, len, func);    //调整交换的结点}}//堆排序void heap_sort (int num[], int len, cmp func){int i;for (i = (len/2 - 1); i >= 0; i--){heapify (num, i, len, func);     //建立堆}//根结点与最后一个结点交换,移除最后结点,调整堆for (i = len - 1;i > 0; i--){swap (num, i, 0);      len --;heapify (num, 0, len, func);}}//归并/*   用递归方式将数组分成两部分,排序后合并   tmp 用于存缓存数据*/void merge (int num[], int left, int right, int mid, int tmp[], cmp func){int i = left;int j = mid + 1;int k = 0;//合并两个有序的数列while (i <= mid && j <= right)    //左数组边界是mid,右数组边界是right{if (func (num[i], num[j]) > 0){tmp[k++] = num[j++];}else {tmp[k++] = num[i++];}}while (i <= mid){tmp[k++] = num[i++];}while (j <= right){tmp[k++] = num[j++];}k = 0;//将参数传给原数组for (i = left;i <= right; i++){num[i] = tmp[k++];}}//归并排序void merge_sort (int num[], int left, int right, int tmp[], cmp func){if (left >= right)  //递归退出条件return ;int mid = (left + right) / 2;merge_sort (num, left, mid, tmp, func);      //递归左数组merge_sort (num, mid + 1, right, tmp, func); //递归右数组merge (num, left, right, mid, tmp, func);    //合并左右数组}//分区int partition (int num[], int left, int right, cmp func){int pivot = num[right];  //选右边界的元素作为基准值int index = left;int i;for (i = left;i < right; i++){if (func (num[i], pivot) < 0) {swap (num, i, index);   //将小于基准值的元素移至数组前端index ++;}}swap (num, index, right);   //用基准值分割数组return index;      //返回基准值位置}//快速排序void quick_sort (int num[], int left, int right, cmp func){if (left < right){int pivot = partition (num, left, right, func);quick_sort (num, left, pivot-1, func);     //递归左右数组quick_sort (num, pivot+1, right, func);}}int main (){int num[10] = {4,7,1,3,5,0,9,2,8,6};int len = sizeof(num)/sizeof(num[0]);printf ("排序前 :");printA (num, len);/**/printf ("        冒泡排序\n");printf ("升序 :");bubble_sort (num, len, cmp_up); //cmp_down()函数当参数传入printA (num, len);printf ("降序 :");bubble_sort (num, len, cmp_down);printA (num, len);/***/printf ("        鸡尾酒排序\n");printf ("升序 :");cocktail_sort (num, len, cmp_up); printA (num, len);printf ("降序 :");cocktail_sort (num, len, cmp_down);printA (num, len);/**/printf ("        选择排序\n");printf ("升序 :");select_sort (num, len, cmp_up); printA (num, len);printf ("降序 :");select_sort (num, len, cmp_down);printA (num, len);/**/printf ("        插入排序\n");printf ("升序 :");insert_sort (num, len, cmp_up); printA (num, len);printf ("降序 :");insert_sort(num, len, cmp_down);printA (num, len);/**/printf ("        二分法插入排序\n");printf ("升序 :");dic_sort (num, len, cmp_up); printA (num, len);printf ("降序 :");dic_sort (num, len, cmp_down);printA (num, len);printf ("        希尔排序\n");printf ("升序 :");shell_sort (num, len, cmp_up); printA (num, len);printf ("降序 :");shell_sort(num, len, cmp_down);printA (num, len);/**/printf ("        堆排序\n");printf ("升序 :");heap_sort (num, len, cmp_up); printA (num, len);printf ("降序 :");heap_sort(num, len, cmp_down);printA (num, len);/**/int tmp[10];printf ("        归并排序\n");printf ("升序 :");merge_sort (num, 0, len-1, tmp, cmp_up); printA (num, len);printf ("降序 :");merge_sort (num, 0, len-1, tmp, cmp_down); printA (num, len);/**/printf ("        快速排序\n");printf ("升序 :");quick_sort (num, 0, len-1, cmp_up); printA (num, len);printf ("降序 :");quick_sort (num, 0, len-1, cmp_down); printA (num, len);return 0;}
谢谢,请多支持!
原创粉丝点击