链表的排序
1.对链表使用插入排序:
第一步: 判断链表是否为空,如果为空,不需要进行排序,直接返回。
第二步:
数组的排序:
1. 快速排序
第一步: 选定中心轴(pivot)
第二步: 小于中心轴的放左边
第三步: 大于中心轴的放右边
第四步: 递归调用
public int[] sortArray(int[] nums) {
// 1. 快速排序
randomizedQuicksort(nums, 0, nums.length - 1);
return nums;
}
public void randomizedQuicksort(int[] nums, int l, int r){
if(l>=r){
return;
}
int left = l , right = r;
int pivot = nums[left];
while(left < right){
while(left< right && nums[right] >= pivot){
right--;
}
if(left < right){
nums[left] = nums[right];
}
while(left<right && nums[left] <= pivot){
left++;
}
if(left<right){
nums[right] = nums[left];
}
if(left >= right){
nums[left] = pivot;
}
}
randomizedQuicksort(nums,l,left-1); // left == right ,所以选择left-1 或者right -1都可以
randomizedQuicksort(nums,left+1,r);
}
我说一下比较难以理解的几个点。
- 把 left = l ,right = r这样做的目的,就是为了保证下标不变,也就是最开始的数组左界和有界
- pivot 选择为数组的第一个元素,也就是左边界
- 什么时候开始递归,当left>=right的时候就要开始,也就是最大的while循环结束的时候。
2. 堆排序
堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。
第一步: 构造堆排序的主程序
第二步: 构造大顶堆程序
第三步:写出返回左子树的程序
第四步:交换程序
public void Heap(int nums[]){
// 将待排序的序列够成一个大顶堆
for(int i = nums.length/2;i>=0;i--){
heapAdjust(nums,i,nums.length);
}
// 将每个最大值的根节点和末尾元素交换,并且再次调整二叉树,使得他成为大顶堆
for (int i = nums.length - 1; i > 0; i--) {
swap(nums,0,i);
heapAdjust(nums, 0, i);
}
}
//构建堆
public void heapAdjust(int[] nums,int i ,int n){
int child;
int father;
for(father = nums[i]; leftChild(i)<n; i=child){
child = leftChild(i);
if(child != n-1 && nums[child] < nums[child+1]){
child++; // 左子树 < 右子树
}
if(father < nums[child]){
nums[i] = nums[child];
}else{
break;
}
}
nums[i] = father;
}
//获取左孩子节点
public int leftChild(int i){
return 2*i+1;
}
//交换元素位置
public void swap(int[] arr ,int index1, int index2){
int tmp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = tmp;
}