排序算法实现

来源:互联网 发布:冰镇西瓜 知乎 编辑:程序博客网 时间:2024/05/01 08:52

一、排序算法分类



二、算法实现

归并算法思想:

void mergesort(int a[],int b[],int left, int right)

{

if(left>=right)

return ;

int mid=(left+right)/2;

mergesort(a,b,left,mid);

mergesort(a,b,mid+1,right);


merge(a,b,left,mid,right);//合并到数组b中

copy(a,b,left,right)//复制回数组a中

}


#include <stdio.h>#define leftchild(i) (2*(i)+1)  //用于堆排序int a[9]={9,8,7,6,5,4,3,2,1};int b[9]={0};//排序//插入排序//1)直接插入排序//直接插入排序由N-1趟排序组成。对于P=1趟到P=N-1趟,插入排序保证了位置0~P上的元素为已排序状态。
//插入排序利用这样的事实:位置0~位置P-1上的元素是已排序过的。void insert_sort(int v[],int n){int i;int j;int temp;for(i=1;i<n;i++){temp=v[i];for(j=i-1;j>=0&&v[j]>temp;j--)v[j+1]=v[j];v[j+1]=temp;}
}//插入排序//1)shell排序
//希尔排序又叫缩小增量排序,个趟比较所用的距离随算法的进行而减小,直到之比较相邻元素的最后一趟为止。
//void shell_sort(int v[],int n){int i,j,increment;int temp;for(increment=n/2;increment>0;increment /=2){for(i=increment;i<n;i++){temp=v[i];for(j=i;j>=increment&&v[j-increment]>temp;j-=increment)v[j]=v[j-increment];v[j]=temp;}}}//交换排序//1)冒泡排序//算法要进行P趟(P最大为N-1)排序,每趟排序将把v[0]~v[P]中最大的元素送到(通过相邻二个元素的交换)v[P]的位置
//如果某趟排序没有进行元素交换,则break;该排序已经完成。void bubble_sort(int v[],int n){int i,j;int temp;int flag;for(i=n-1;i>=0;i--){flag=0;for(j=0;j<i;j++){if(v[j]>v[j+1]){temp=v[j+1];v[j+1]=v[j];v[j]=temp;flag=1;}}if(flag==0)break;}}//交换排序//2)快速排序//快速排序是是一种分治的递归算法。所谓分治算法就是分(递归解决较小的问题)与治(然后,从子问题的解 构建原问题的解)。
//思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小(两个不相交集),
//然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。void swap(int *x,int *y){int temp;temp=*y;*y=*x;*x=temp;}void  qicsort(int v[],int l,int r){int temp;int left=l;int right=r;int mid=(left+right)/2;if(left>=right)return ;swap(&v[left],&v[mid]);temp=v[left];while(left<right){while(v[right]>temp&&left<right)right--;v[left]=v[right];while(v[left]<temp&&left<right)left++;v[right]=v[left];}if(left==right)v[left]=temp;qicsort(v,l,left-1);qicsort(v,left+1,r);
/*如果上面两行代买写成qicsort(v,l,mid-1);qicsort(v,mid+1,r)??
*/}//选择排序//1)简单选择排序//每一趟从待排序的数据元素中选出最小或最大的一个,顺序放在已排序好数列的最后,知道全部有待排序的数据元素排序完。void select_sort(int v[],int n){int i,j;int min;int temp;for(i=0;i<n;i++){min=i;for(j=i+1;j<n;j++){if(v[j]<v[min])min=j;}temp=v[min];v[min]=v[i];v[i]=temp;}}//选择排序//2)堆排序
//堆排序第一步已线性的时间建立一个堆(大头堆),然后通过将堆中的最后元素与第一个元素交换,缩减堆的大小并进行shift,来执行N-1次将末尾元素与堆顶元素的交换。///当算法终止时,数组则以所排的顺序包含这些元素。void shift(int v[],int i,int n){int child;int temp;for(temp=v[i];leftchild(i)<n;i=child){child=leftchild(i);if(child!=n-1&&v[child+1]>v[child])child++;if(v[child]>temp)v[i]=v[child];elsebreak;}v[i]=temp;}void heap_sort(int v[],int n){int i,j;for(i=n/2;i>=0;i--)shift(v,i,n);for(j=n-1;j>0;j--){swap(&v[0],&v[j]);shift(v,0,j);}}//归并排序//归并排序是将两个有序表合并成一个新的有序表,即把待排序序列分为若干个有序的子序列,再把有序的子序列合并为整体有序序列。//归并排序也是一种分治思想的算法。void merge(int v[],int w[],int left,int mid,int right){int i,num;int flag,flag1,flag2;flag1=left;flag2=mid+1;flag=flag1;num=right-left+1;while(flag1<=mid&&flag2<=right){if(v[flag1]<=v[flag2]){w[flag++]=v[flag1++];}else{w[flag++]=v[flag2++];}}while(flag1<=mid)w[flag++]=v[flag1++];while(flag2<=right)w[flag++]=v[flag2++];for(i=0;i<num;i++,right--)a[right]=b[right];}void merge_sort(int v[],int w[],int left,int right){int mid;if(left<right){mid=(left+right)/2;merge_sort(v,w,left,mid);merge_sort(v,w,mid+1,right);merge(v,w,left,mid,right);}}void init(int v[],int n){int i;for(i=0;i<n;i++)v[i]=n-i;}void print(int v[],int n){int i;for(i=0;i<n;i++)printf("%d%c",v[i],i==n-1?'\n':' ');}main(){printf("初始序列为:\n-----------------------\n");print(a,9);printf("直接插入排序:\n----------------------\n");init(a,9);insert_sort(a,9);print(a,9);printf("shell排序:\n----------------------\n");init(a,9);shell_sort(a,9);print(a,9);printf("冒泡排序:\n----------------------\n");init(a,9);bubble_sort(a,9);print(a,9);printf("快速排序:\n----------------------\n");init(a,9);qicsort(a,0,8);print(a,9);printf("直接选择排序:\n----------------------\n");init(a,9);select_sort(a,9);print(a,9);printf("堆排序:\n----------------------\n");init(a,9);heap_sort(a,9);print(a,9);printf("归并排序:\n----------------------\n");init(a,9);merge_sort(a,b,0,8);print(a,9);return 0;}



注:

在快速排序代码中如果注释两行代码

//if(left>=right)
  //return ;

会出现错误:



这实际上是数组越界了...


0 0
原创粉丝点击