一、排序算法分类
二、算法实现
归并算法思想:
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];
else
break;
}
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 ;
会出现错误:
这实际上是数组越界了...