C语言排序算法
1.冒泡排序
void BubbleSort(int a[],int n)
{
int i,j,t,flag=0;//flag用来标记是否发生交换
for(i=0;i<n;i++)
{
for(j=n-1;j>i;j--)
{
if(a[j-1]>a[j])//交换数据
{
t=a[j-1];
a[j-1]=a[j];
a[j]=t;
flag=1;//有数据交换,设置标志变量
}
}
if(flag==0)//没发生交换,直接跳出循环
break;
else
flag=0;
}
}
2.选择排序
void SelectSort(int a[],int n)
{
int i,j,flag,t;
for(i=0;i<n-1;i++)
{
flag=i;//记录需和第flag个元素交换
for(j=i+1;j<n;j++)//查找最小数据,保存其序号在flag中
if(a[flag]>a[j])
flag=j;
if(flag!=i)//交换最小数据在前面
{
t=a[i];
a[i]=a[flag];
a[flag]=t;
}
}
}
3.插入排序
void InsertSort(int a[],int n)
{
int i,j,t;
for(i=1;i<n;i++)
{
t=a[i];//取出一个未排序的数据
for(j=i-1;j>=0&&t<a[j];--j)//在排序序列中查找位置
a[j+1]=a[j];//向后移动数据
a[j+1]=t;//插入数据到序列
}
}
4.快速排序
void QuickSort(int a[],int start,int end)
{
int low =start;
int high =end;
if(low>=high)
return;
//默认第一个为key,挖出来,左边留一个坑。
int key=a[low];
while(low<high)
{
//从右向左,找比key小的值
while(low<high && a[high]>=key)
high--;
//找到了,先把大的放在左边 ,右边留下了一个坑
if(low<high)
a[low++]=a[high];
//再从右往左,找到比key大的值
while(low<high && a[low]<=key)
low++;
//找到了,填到刚才右边的坑里 ,左边留一个坑
if(low<high)
a[high--]=a[low];
}
//最后所有的坑都要填上
a[low]=key;
QuickSort(a,start,low-1);
QuickSort(a,low+1,end);
}
5.希尔排序
void ShellSort(int a[],int n)
{
int d,i,j,x;
d=n/2;//计算第一次的增量
while(d>=1)//循环至增量为1时结束
{
for(i=d;i<n;i++)
{
x=a[i];//获取序列中的下一个数据
j=i-d;//序列中前一个数据的序号
while(j>=0&&a[j]>x)//下一个数大于前一个数
{
a[j+d]=a[j];//将后一个数向前移动
j=j-d;//修改序号,继续向前比较
}
a[j+d]=x;//保存数据
}
d/=2;//缩小增量
}
}
6.堆排序
void HeapAdjust(int a[],int s,int n)//构成堆
{
int j,t;
while(2*s+1<n) //第s个结点有右子树
{
j=2*s+1 ;
if((j+1)<n)
{
if(a[j]<a[j+1])//左子树小于右子树,则需要比较右子树
j++; //序号增加1,指向右子树
}
if(a[s]<a[j])//比较s与j为序号的数据
{
t=a[s]; //交换数据
a[s]=a[j];
a[j]=t;
s=j ;//堆被破坏,需要重新调整
}
else //比较左右孩子均大则堆未破坏,不再需要调整
break; //退出循环
}
}
void HeapSort(int a[],int n)//堆排序
{
int t,i;
int j;
for(i=n/2-1;i>=0;i--) //将a[0,n-1]建成大根堆
HeapAdjust(a, i, n);
for(i=n-1;i>0;i--) //取根节点与末节点交换
{
t=a[0];//与第i个记录交换
a[0] =a[i];
a[i] =t;
HeapAdjust(a,0,i); //将a[0]至a[i]重新调整为堆
}
}
7.归并排序
void MergeStep(int a[],int r[],int s,int m,int n) //相邻有序段合并
{
int i,j,k;
k=s;
i=s;
j=m+1;
while(i<=m && j<=n) //当两个有序表都未结束时,循环比较
{
if(a[i]<=a[j]) //当较小的元素复制到R中
r[k++]=a[i++];
else
r[k++]=a[j++];
}
while(i<=m) //将未合并的部分复制到R中
r[k++]=a[i++];
while(j<=n)
r[k++]=a[j++]; //将未合并的部分复制到R中
}
void MergePass(int a[],int r[],int n,int len) //完成一遍合并的函数
{
int s,e;
s=0; //第1个序列的起始序号
while(s+len<n) //至少有两个有序段
{
e=s+2*len-1; //第1个序列的结束序号
if(e>=n) //最后一段可能少于len个结点
e=n-1; //重新计算结束序号
MergeStep(a,r,s,s+len-1,e); //相邻有序段合并
s=e+1; //下一对有序段中左段的开始下标
}
if(s<n) //还剩一个有序段,将其从A中复制到R中
for(;s<n;s++)
r[s]=a[s];
}
void MergeSort(int a[],int n) //合并排序
{
int *p;
int len=1; //有序序列的长度
int f=0; //变量f作标志
if(!(p=(int *)malloc(sizeof(int)*n))) //分配内存空间,保存临时数据
{
printf("分配临时内存失败!\n");
exit(0);
}
while(len<n)
{
if(f) //交替地在A和P之间来回合并
MergePass(p,a,n,len); //调用MergePass,对p合并到a
else
MergePass(a,p,n,len); //调用MergePass,对a合并到p
len*=2; //增加有序序列长度
f=1-f; //使f值在0和1之间切换
}
if(f) //若进行了排序
for(f=0;f<n;f++) //将数组p中的数据复制到数组a
a[f]=p[f];
free(p); //释放分配的内存
}