链表和数组的排序---持续更新

链表的排序

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);
    }

我说一下比较难以理解的几个点。

  1. 把 left = l ,right = r这样做的目的,就是为了保证下标不变,也就是最开始的数组左界和有界
  2. pivot 选择为数组的第一个元素,也就是左边界
  3. 什么时候开始递归,当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;
        }
        
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值