插入排序
已经有一个排好的序列,要将新元素放到序列合适的位置。
int *InsertSortA(int *R,n) {
int i,j; for(j=1;j<n;j++) { i=j-1; tmp=R[j]; while(i>=0&&R[i]<tmp) { R[i+1]=R[i]; i--; } R[i+1]=tmp; }
return R; }
上述算法中每次都要判断i是否小于0,可以让数组第一个元素是一个很小的值,使得R[0]<min{Ri},i为1到n,整个数组长度为n+1.在判断R[i]<tmp时,一定会结束,因为R[0]一定小于R[i].
int *InsertSortB(int *R,n) { int i,j; for(j=2;j++;j<=n) { i=j-1; tmp=R[j]; while(R[i]<tmp) {R[i+1]=R[i]; i--; } R[i+1]=tmp; }
return R; }
Shell排序
Shell的大意是:把元素按下标的一定增量分组,对每组使用直接插入排序。随着增量逐渐减少,每组包含的记录越来越多。当增量值减至1时,整个文件恰好被分成一个组,算法便终止。
堆排序
首先根据数组构建最小堆,结点i的左右结点为2*i+1,2*i+2,结点i的父节点为i-1/2,然后交换第一个与最后一个元素,即删除最小的值,重建堆,重复进行直到只剩一个元素。
#include <iostream>
using namespace std;
void MinHeapFixdown(int a[],int i,int n)//从i开始恢复堆,共n个结点
{
int j;
int temp=a[i];
j=2*i+1;
while(j<n)
{
if(j+1<n&&a[j+1]<a[j])
j++;
if(a[j]>=temp)
break;
a[i]=a[j];
i=j;
j=2*i+1;
}
a[i]=temp;
}
void MinHeapCon(int a[],int n)
{
int i;
for(i=n/2-1;i>=0;i--)
{
MinHeapFixdown(a,i,n);
}
}
void MinHeapSort(int a[],int n)//n个元素,排序
{
int i;
for(i=n-1;i>0;i--)
{
swap(a[i],a[0]);
MinHeapFixdown(a,0,i);
}
}
int main()
{
int a[10]={9,12,17,30,50,20,60,65,4,49};
MinHeapCon(a,10);
MinHeapSort(a,10);
for(int i=0;i<10;i++)
cout<<a[i]<<' ';
}
归并排序
可以将A,B组各自再分成二组。依次类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了。这样通过先递归分解数组,然后在合并排序。
#include <iostream> using namespace std; void mergeArray(int a[],int first,int mid,int last,int temp[])//将first-mid与mid+1-last合并 { int i,j,k; i=first; j=mid+1; k=0; int m=mid,n=last; while(i<=m&&j<=n) { if(a[i]<=a[j]) temp[k++]=a[i++]; else temp[k++]=a[j++]; } while(i<=m)//最后有剩余 temp[k++]=a[i++]; while(j<=n) temp[k++]=a[j++]; for(i=0;i<k;i++) a[first+i]=temp[i]; } void mergeSort(int a[],int first,int last,int temp[]) { if(first<last)//直到每个数组只有一个元素 { int m=(first+last)/2; mergeSort(a,first,m,temp); mergeSort(a,m+1,last,temp); mergeArray(a,first,m,last,temp); } } int main() { int a[10]={9,12,17,30,50,20,60,65,4,49}; int *tmp=new int[10]; mergeSort(a,0,9,tmp); for(int i=0;i<10;i++) cout<<a[i]<<' '; delete[] tmp; }