1.归并排序:它先将要排序的数组递归地分成两半分别排序,然后再将结果归并起来。要做到这一点首先需要一种原地归并两半数组的方法,该方法的思想为先将所有数组复制到一个辅助数组aux[]中,然后再归并到a[]中,也就说将数组按下标i=lo~mid,j=mid+1~hi两部分进行大小比较然后依次返回原数组之中,在比较的时候需要添加一下判定条件
1.左半边用完,i>mid,则直接把右半边剩余数组依次放入原数组之中,j++
2.右半边用完,j>hi,则直接把左半边剩余数组依次放入原数组之中,i++
3.如果右边元素小于左边元素,则将右边元素放回原数组之中,j++
4.如果左边元素小于右边元素,则将左边元素放回原数组之中,i++
public void mergesort(int[] a)
{
public aux=new int[a.length];
sort(a,0,a.length-1);
}
public void sort(int[] a,int lo,int hi)
{
if(hi<=lo)
return;
int mid=lo+(hi-lo)/2;
sort(a,lo,mid);
sort(a,mid+1,hi);
merge(a,lo,mid,hi);
}
public void merge(int a[],int lo,int mid,int hi)
{
int i=lo;
int j=mid+1;
for(int k=lo;k<=hi;k++)
aux[k]=a[k];
for(int k=lo;k<=hi;k++)
{
if(i>mid) a[k]=aux[j++];
else if(j>hi) a[k]=aux[i++];
else if(less(aux[j],aux[i])) a[k]=a[j++];//less函数之前的初级排序里面有
else a[k]=a[i++];
}
}
2.快速排序:快速排序是一种分治的排序算法,它将通过一个切分值分成两个部分,一部分的值都不大于这个切分值,另一部分的值都大于这个切分值,分别对这个两个部分进行排序,当两个子数组由序的时候,整个数组就有序了。
public void quickSort(int[] a)
{
sort(a,0,a.length-1);
}
public void sort(int[] a,int lo,int hi)
{
if(lo>=hi)return;
int j=partition(a,lo,hi);
sort(a,lo,j);
sort(a,j+1,hi);
}
public int partition(int[] a,int lo,int hi)
{
int i=lo;
int j=hi;
int mid=(lo+hi)/2;
int v=a[mid];
while(true)
{
while(less(a[i++],v)) if(i>=hi)break;
while(less(v,a[j--]))if(j<=lo)break;
if(i>=j)break;//从左扫描找到大于切分值的数,之后从右向做扫描找到小于切分值的数
exch(a,i,j);
}
exch(a,mid,j);//将切分值放入正确的位置
return j;
}
3.堆排序:要使用堆排序,首先使用一个数组来表示一个完全二叉树的节点。将数组进行堆的下沉操作,使得整个堆有序,为一个最大值堆,顶点为最大的一个值。然后将顶点与数组最后一个值进行交换,然后对顶点进行下沉操作,让顶点为剩余数组中最大的,直到堆中还剩一个顶点时,排序完成
public void heapsort(int a)
{
int N=a.length;
for(int k=N/2;k>=1;k--)
sink(a,k,N);
while(N>1)
{
exch(a,1,N--);
sink(a,1,N);
}
public void sink(int[] a,int k,int N)
{
while(2*k<=N)
{
int j=2*k;
if(j<N&&less(a[j],a[j+1]))j++;
if(!less(a[k,a[j]]))break;
exch(a,k,j);
k=j;//这个操作是寻找当前节点的子节点比它大的值中的最大值进行交换
}
}