几种比较常见的排序算法
第一种:
/*
函数功能:双向冒泡排序
2013.7.8
时间复杂度O(n^2)
*/
#include<stdio.h>
void mp(int *array,int n)
{
int bmin=0;
int bmax=n;
int mmax,mmin,i;
int a;
while(bmin<bmax)
{
mmin=0; mmax=0;
for(i=bmin;i<bmax;i++) //此次扫描使重气泡下沉
{
if(*(array+i)>*(array+i+1))
{
a=*(array+i);
*(array+i)=*(array+i+1);
*(array+i+1)=a;
mmax=i; // 记录组后一次下沉发生交换的位置
}
}
if(mmax==0) // 没有记录交换,扫描结束
break;
bmax=mmax;
for(i=bmax-1;i>bmin;i--) //此次扫描使轻气泡上浮
{
if(*(array+i)<*(array+i-1))
{
a=*(array+i);
*(array+i)=*(array+i-1);
*(array+i-1)=a;
mmin=i; // 记录最后一次上浮发生交换的位置
}
}
if(mmin==0) // 本次没有记录交换,扫描结束
break;
bmin=mmin;
}
}
int main()
{
int array[9]={4,3,5,6,8,1,2,9,7};
int i;
mp(array,9);
for(i=0;i<9;i++)
{
printf("%d ",*(array+i));
}
return 0;
}
第二种:
/*快速排序*/ O(n㏒2n)
#include<stdio.h>
#include<stdlib.h>
/*
函数功能:快速排序的分划算法;
函数返回值:划分元素的数组下标
*/
int x[50],n,*p;
int part(int *a,int i,int j)
{
int t=*(a+i);
while(i<j)
{
while(i<j&&*(a+j)>=t)
j--;
if(i<j)
{
*(a+i)=*(a+j);
i++;
}
while(i<j&&*(a+i)<=t)
i++;
if(i<j)
{
*(a+j)=*(a+i);
j--;
}
}
*(a+i)=t;
return i;
}
/*
函数功能:快速排序的递归算法;
函数参数:参数1:,待排序数组,参数2,数组左边界,参数3,数组右边界
*/
void quicksort(int *a,int low,int high)
{
int mid,i;
if(low<high)
{
mid=part(a,low,high); //对数组【low。。high】进行划分
quicksort(a,low,mid-1); //对左区间递归排序
quicksort(a,mid+1,high); //对右区间递归排序
}
for(i=0;i<n;i++)
printf("%d ",*(p+i));
printf("\n");
}
int main()
{
int i;
p=x;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",p+i);
quicksort(p,0,n-1);
for(i=0;i<n;i++)
printf("%d ",*(p+i));
return 0;
}
第三种:
/*
堆排序----树形结合 O(n㏒2n)
*/
#include<stdio.h>
int a[11]={0,25,3,69,1,60,12,50,13,45,18};
void Restore(int *array,int i,int n);
void heapsort(int *array,int n) // 堆排序算法
{
int i,j,t,k;
for(i=n/2;i>0;i--)
{
Restore(array,i,n); // 将第i个节点变为堆
}
for(i=n-1;i>0;i--)
{
//观察每次重新建堆后变成的序列
for(k=1;k<11;k++)
printf("%d ",*(a+k));
printf("\n\n");
//将堆顶的元素与序列中的最后一个数对调
t=*(array+i+1);
*(array+i+1)=*(array+1);
*(array+1)=t;
Restore(array,1,i); //重新生成堆序列
}
}
void Restore(int *array,int i,int n) //重建堆
{
int j,k,r;
int done=0;
k=r=*(array+i);
j=2*i;
while((j<=n)&&(done==0))
{
if(j<n)
{
if(*(array+j)<*(array+j+1))
j++;
}
if(k>=*(array+j))
done=1;
else
{
*(array+j/2)=*(array+j);
j*=2;
}
}
*(array+j/2)=r;
}
int main()
{
int i;
heapsort(a,10);
for(i=1;i<11;i++)
printf("%d ",*(a+i));
printf("\n");
}
第四种: n㏒2n
归并排序:归并排序是利用分治法来对序列进行排序的,该算法就是不断地将待排序的数组一分为二,当子数组的元素少于2个时这种分解的过程就会停止,
然后再将多个已排好序的子序列合并为一个新的有序序列。
#include<stdio.h>
/*参数1,待排数组,参数2,辅助数组,参数3,每个子序列的长度,参数4,待排数组长度
*/
void Mergepass(int *a,int *b,int t,int n)
{
int i,j,index;
int beg1,end1; //第一个子序列的起始和终止位置
int beg2,end2; //第二个子序列的起始和终止位置
beg1=0; index=0;
while(beg1+t<=n-1)
{
beg2=beg1+t;
end1=beg2-1;
if(beg2+t-1<=n-1)
end2=beg2+t-1;
else
end2=n-1;
i=beg1;
j=beg2;
while(i<=end1&&j<=end2)
{
if(*(a+i)<=*(a+j))
{
*(b+index)=*(a+i);
i++;
index++;
}
else
{
*(b+index)=*(a+j);
j++;
index++;
}
}
while(i<=end1)
{
*(b+index)=*(a+i);
index++;
i++;
}
while(j<=end2)
{
*(b+index)=*(a+j);
index++;
j++;
}
beg1=end2+1;
}
for(i=beg1;i<n;i++,index++)
*(b+index)=*(a+i);
}
/*
函数功能:对无序序列进行归并排序
函数参数:参数1,待排序数组;参数2,辅助数组;参数3,数组元素个数
*/
void Mergesort(int *a,int *b,int n)
{
int i,j;
j=1;
while(j<n)
{
Mergepass(a,b,j,n); //
for(i=0;i<n;i++)
*(a+i)=*(b+i);
for(i=0;i<5;i++)
printf("%d ",*(a+i));
printf("\n\n");
j*=2;
}
}
int main()
{
int a[5]={5,4,3,2,1};
int y[5];
int i;
printf("原数组为:");
for(i=0;i<5;i++)
printf("%d ",*(a+i));
printf("\n排序过程如下\n");
Mergesort(a,y,5);
for(i=0;i<5;i++)
printf("%d ",*(a+i));
printf("\n");
}
第一种:
/*
函数功能:双向冒泡排序
2013.7.8
时间复杂度O(n^2)
*/
#include<stdio.h>
void mp(int *array,int n)
{
int bmin=0;
int bmax=n;
int mmax,mmin,i;
int a;
while(bmin<bmax)
{
mmin=0; mmax=0;
for(i=bmin;i<bmax;i++) //此次扫描使重气泡下沉
{
if(*(array+i)>*(array+i+1))
{
a=*(array+i);
*(array+i)=*(array+i+1);
*(array+i+1)=a;
mmax=i; // 记录组后一次下沉发生交换的位置
}
}
if(mmax==0) // 没有记录交换,扫描结束
break;
bmax=mmax;
for(i=bmax-1;i>bmin;i--) //此次扫描使轻气泡上浮
{
if(*(array+i)<*(array+i-1))
{
a=*(array+i);
*(array+i)=*(array+i-1);
*(array+i-1)=a;
mmin=i; // 记录最后一次上浮发生交换的位置
}
}
if(mmin==0) // 本次没有记录交换,扫描结束
break;
bmin=mmin;
}
}
int main()
{
int array[9]={4,3,5,6,8,1,2,9,7};
int i;
mp(array,9);
for(i=0;i<9;i++)
{
printf("%d ",*(array+i));
}
return 0;
}
第二种:
/*快速排序*/ O(n㏒2n)
#include<stdio.h>
#include<stdlib.h>
/*
函数功能:快速排序的分划算法;
函数返回值:划分元素的数组下标
*/
int x[50],n,*p;
int part(int *a,int i,int j)
{
int t=*(a+i);
while(i<j)
{
while(i<j&&*(a+j)>=t)
j--;
if(i<j)
{
*(a+i)=*(a+j);
i++;
}
while(i<j&&*(a+i)<=t)
i++;
if(i<j)
{
*(a+j)=*(a+i);
j--;
}
}
*(a+i)=t;
return i;
}
/*
函数功能:快速排序的递归算法;
函数参数:参数1:,待排序数组,参数2,数组左边界,参数3,数组右边界
*/
void quicksort(int *a,int low,int high)
{
int mid,i;
if(low<high)
{
mid=part(a,low,high); //对数组【low。。high】进行划分
quicksort(a,low,mid-1); //对左区间递归排序
quicksort(a,mid+1,high); //对右区间递归排序
}
for(i=0;i<n;i++)
printf("%d ",*(p+i));
printf("\n");
}
int main()
{
int i;
p=x;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",p+i);
quicksort(p,0,n-1);
for(i=0;i<n;i++)
printf("%d ",*(p+i));
return 0;
}
第三种:
/*
堆排序----树形结合 O(n㏒2n)
*/
#include<stdio.h>
int a[11]={0,25,3,69,1,60,12,50,13,45,18};
void Restore(int *array,int i,int n);
void heapsort(int *array,int n) // 堆排序算法
{
int i,j,t,k;
for(i=n/2;i>0;i--)
{
Restore(array,i,n); // 将第i个节点变为堆
}
for(i=n-1;i>0;i--)
{
//观察每次重新建堆后变成的序列
for(k=1;k<11;k++)
printf("%d ",*(a+k));
printf("\n\n");
//将堆顶的元素与序列中的最后一个数对调
t=*(array+i+1);
*(array+i+1)=*(array+1);
*(array+1)=t;
Restore(array,1,i); //重新生成堆序列
}
}
void Restore(int *array,int i,int n) //重建堆
{
int j,k,r;
int done=0;
k=r=*(array+i);
j=2*i;
while((j<=n)&&(done==0))
{
if(j<n)
{
if(*(array+j)<*(array+j+1))
j++;
}
if(k>=*(array+j))
done=1;
else
{
*(array+j/2)=*(array+j);
j*=2;
}
}
*(array+j/2)=r;
}
int main()
{
int i;
heapsort(a,10);
for(i=1;i<11;i++)
printf("%d ",*(a+i));
printf("\n");
}
第四种: n㏒2n
归并排序:归并排序是利用分治法来对序列进行排序的,该算法就是不断地将待排序的数组一分为二,当子数组的元素少于2个时这种分解的过程就会停止,
然后再将多个已排好序的子序列合并为一个新的有序序列。
#include<stdio.h>
/*参数1,待排数组,参数2,辅助数组,参数3,每个子序列的长度,参数4,待排数组长度
*/
void Mergepass(int *a,int *b,int t,int n)
{
int i,j,index;
int beg1,end1; //第一个子序列的起始和终止位置
int beg2,end2; //第二个子序列的起始和终止位置
beg1=0; index=0;
while(beg1+t<=n-1)
{
beg2=beg1+t;
end1=beg2-1;
if(beg2+t-1<=n-1)
end2=beg2+t-1;
else
end2=n-1;
i=beg1;
j=beg2;
while(i<=end1&&j<=end2)
{
if(*(a+i)<=*(a+j))
{
*(b+index)=*(a+i);
i++;
index++;
}
else
{
*(b+index)=*(a+j);
j++;
index++;
}
}
while(i<=end1)
{
*(b+index)=*(a+i);
index++;
i++;
}
while(j<=end2)
{
*(b+index)=*(a+j);
index++;
j++;
}
beg1=end2+1;
}
for(i=beg1;i<n;i++,index++)
*(b+index)=*(a+i);
}
/*
函数功能:对无序序列进行归并排序
函数参数:参数1,待排序数组;参数2,辅助数组;参数3,数组元素个数
*/
void Mergesort(int *a,int *b,int n)
{
int i,j;
j=1;
while(j<n)
{
Mergepass(a,b,j,n); //
for(i=0;i<n;i++)
*(a+i)=*(b+i);
for(i=0;i<5;i++)
printf("%d ",*(a+i));
printf("\n\n");
j*=2;
}
}
int main()
{
int a[5]={5,4,3,2,1};
int y[5];
int i;
printf("原数组为:");
for(i=0;i<5;i++)
printf("%d ",*(a+i));
printf("\n排序过程如下\n");
Mergesort(a,y,5);
for(i=0;i<5;i++)
printf("%d ",*(a+i));
printf("\n");
}