1、快排
- 复杂度
O(nlogn)
- 不稳定
- 思路是通过一趟排序将数组分为两部分,其中一部分的所有数比另一部分的所有数都小,再递归对这两部分进行排序,达到全部排序的目的
- 一趟排序具体过程是从待排序列中任意选取一个记录(通常选取第一个记录)作为基准值,然后将比它小的值都放在它的位置之前,将比它大的都放在它的位置之后。这样,以该基准值为分界线,将待排序列分成的两个子序列
- 一趟排序的具体做法:设置两个指针low和high分别指向待排序列的开始和结尾,记录下基准值baseval(待排序列的第一个记录),然后先从high所指的位置向前搜索直到找到一个小于baseval的记录并互相交换,接着从low所指向的位置向后搜索直到找到一个大于baseval的记录并互相交换,重复这两个步骤直到low=high为止
public void quick(int[] nums, int start, int end){
if (start >= end) return;
int i = start;
int j = end;
int val = nums[start];
while (i < j){
while (j > i && nums[j] > val){
j--;
}
if (j > i){
nums[i] = nums[j];
i++;
}
while (i < j && nums[i] < val){
i++;
}
if(i < j){
nums[j] = nums[i];
j--;
}
}
nums[i] = val;
quick(nums, start, i-1);
quick(nums, i+1, end);
}
2、堆排序
- 复杂度
O(nlogn)
- 不稳定
- 思路:大顶堆是任一节点大于它的左右子节点,小顶堆是任一节点小于它的左右子节点。将待排序列构造成一个大顶堆(或小顶堆),整个序列的最大值(或最小值)就是堆顶的根结点,将根节点的值和堆数组的末尾元素交换,此时末尾元素就是最大值(或最小值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次大值(或次小值),如此反复执行,最终得到一个有序序列
public void heap(int[] nums){
int length = nums.length;
for (int i = length / 2 - 1; i >= 0; i--)
{
HeapAdjust(nums, i, length);
}
for (int i = length - 1; i >= 0; i--){
int temp;
temp = nums[i];
nums[i] = nums[0];
nums[0] = temp;
HeapAdjust(nums, 0, i);
}
}
void HeapAdjust(int nums[], int i, int length)
{
int max = i;
int lchild = i * 2 + 1;
int rchild = i * 2 + 2;
if (lchild < length && nums[lchild] > nums[max])
{
max = lchild;
}
if (rchild < length && nums[rchild] > nums[max])
{
max = rchild;
}
if (max != i){
int temp;
temp = nums[i];
nums[i] = nums[max];
nums[max] = temp;
HeapAdjust(nums, max, length);
}
}