排序小结 (上)

来源:互联网 发布:.top域名谁在管理 编辑:程序博客网 时间:2024/06/15 10:15

排序小结(C语言实现)

 

排序算法大致可分为内部排序和外部排序,如果整个排序过程不需借助外部存储器(如磁盘等),所有排序操作都在内存中完成,称为内部排序;如果参与排序的元素很多,数据量极大,需借助外部存储器进行排序操作,则称为外部排序。

本篇主讲内部排序,欢迎各位提出意见或改进算法。

 

一.交换排序:

1.冒泡排序:

(假设有len个元素,存在数组a[0~len-1]中)遍历n-1趟,每次从小到大交换相邻数据,一趟下来得到最大值存于数组尾

void BubbleSort(int *a,int len){printf("冒泡排序:\n");int i,j;int temp;bool Changed;    //Changed记录是否已经有序for(i=0;i<len-1;i++){Changed=false;for(j=0;j<len-1-i;j++){if(a[j]>a[j+1]){temp=a[j];a[j]=a[j+1];a[j+1]=temp;Changed=true;}}if(Changed==0)    break;    //若Changed==0,说明遍历时a[j]<=a[j+1]恒                      //成立,即已有序}ShowSort(a,len);    //辅助函数:打印输出}

2.快速排序:

(递归实现)将元素a[begin]插入到a[begin+1~end]的合适位置

void QuickSort(int *a,int len,int begin,int end){if(begin<end){int i=begin+1;int j=end;int temp;while(i<j){if(a[i]>a[begin]){temp=a[j];a[j]=a[i];a[i]=temp;j--;}else{i++;}}        //结束循环条件:i==j,判断a[i]及a[begin]的大小if(a[i]>a[begin]){i--;}temp=a[i];a[i]=a[begin];a[begin]=temp;QuickSort(a,len,begin,i-1);QuickSort(a,len,i+1,end);}}

二.选择排序:

1.直接选择:

直接选择排序和冒泡排序的过程相似,区别在于一趟下来选择最小元素的数组下标,将元素加入到前端有序区

void SelectSort(int *a,int len){printf("直接选择排序:\n");int i,j;int temp;int min;    //记录最小元素下标for(i=0;i<len-1;i++){min=i;    //每次以无序区头元素为假定最小for(j=i;j<len;j++){if(a[j]<a[min])min=j;}temp=a[i];a[i]=a[min];a[min]=temp;}ShowSort(a,len);}


2.堆排序:

堆排序过程中涉及到一些对堆的操作,包括建堆、堆的调整等

void Heapify(int *a,int i,int len){int ichild;int temp;    //二叉树根节点标号为0,左孩子记2i+1,右孩子记2i+2for(temp=a[i];(2*i+1)<=(len-1);i=ichild){ichild=2*i+1;if(ichild!=(len-1)&&a[ichild+1]>a[ichild])ichild++;    //是否有右孩子,若有,取较大的一个if(a[i]<a[ichild]){a[i]=a[ichild];a[ichild]=temp;}else{break;}}}void HeapSort(int *a,int len){printf("堆排序:\n");int i;int temp;for(i=len/2-1;i>=0;i--){Heapify(a,i,len);}    //建立完全二叉树,i从最后一个非叶子节点开始for(i=len-1;i>0;i--){temp=a[i];a[i]=a[0];a[0]=temp;Heapify(a,0,i);}ShowSort(a,len);}


补充:

辅助函数:打印输出

void ShowSort(int *a,int len){for(int i=0;i<len;i++)printf("%5d",a[i]);printf("\n");}

0 0
原创粉丝点击