# 平均时间复杂度为O(nlogn)的排序算法

1.快速排序

2.归并排序

3.堆排序

1.快速排序

```public void partition(int[] a,int start,int end){
if(start>=end)
return ;
int low=start;
int high=end;
int index = a[low];//选定基数
while(low<high){
while(a[high]>index && high>low)//找到右边比基数小的数字
high--;
if(low<high)
a[low++] = a[high];
while(a[low]<index && high>low)//找到左边比基数大的数字
low++;
if(low<high)
a[high--] = a[low];
}
a[low] = index;
partition(a,start,low-1);
partition(a,low+1,end);
}```

```public void partition1(int[] a,int start,int end){
if(start>=end)
return ;
int index = start;
swap(a[index],a[end]);
int small=start-1;
for(index = start;index<end;index++){
if(a[index]<a[end]){//若比选定基数小，则与前面比大于基数的数字进行交换
small ++ ;
if(small!=index){
swap(a[small],a[index]);
}
}
}
small++;
swap(a[small],a[end]);
partition1(a,start,small-1);
partition1(a,small+1,end);
}```

```public void quickSort(int[] a){
partition1(a,0,a.length-1);
}```

2.归并排序

```public void Merge(int[] a,int start,int mid,int end){
int length1,length2; //新数组的大小
int i,j,k;
length1 = mid - start + 1;
length2 = end - mid;
int[] L = new int[length1];
int[] R = new int[length2];
for(i=0,k=start;i<length1;i++,k++)//将前半部分数组存入L中
L[i] = a[k];
for(i=0,k=mid+1;i<length2;i++,k++)//将后半部分数组存入R中
R[i] = a[k];
for(k=start,i=0,j=0;i<length1&&j<length2;k++){//分别从两个数组中读取数据，取较小的放入员数组中
if(L[i]<R[j]){
a[k] = L[i];
i++;
}
else{
a[k] = R[j];
j++;
}
}
if(i<length1)//将L中还有的剩余数字存入原数组
for(j=i;j<length1;j++,k++)
a[k] = L[j];
if(j<length2)//将R中还有的剩余数字存入元素族
for(i=j;i<length2;i++,k++)
a[k] = R[i];
}```

```public void MergeSort(int[] a,int start,int end){
if(start<end && a.length>1){
int mid = (start+end)/2;
MergeSort(a,start,mid);
MergeSort(a,mid+1,end);
Merge(a,start,mid,end);
}
}```

3.堆排序

```public void adjustHeap(int[] a,int pos,int len){
int temp;
int child;
for(temp = a[pos];2 * pos+1<=len;pos=child){
child = 2 * pos+1;//得到子节点的下标
if(child<len&&a[child]<a[child+1])//得到子节点中较大的节点
child++;
if(a[child] > temp)//将子节点和父节点进行交换
a[pos] = a[child];
else
break;
}
a[pos] = temp;
}
//堆排序
public void HeapSort(int[] a){
for(int i=a.length/2-1;i>=0;i--)//构建堆
for(int i=a.length-1;i>=0;i--){
//把第一个数字和最后一个数字交换
int temp = a[0];
a[0] = a[i];
a[i] = temp;
//调整堆保证第一个数字是最大的