各种排序算法及实现

各种排序算法

1.快速排序

  • 1.i = L; j = R; 将基准数挖出形成第一个坑 a[i]。
  • 2.j-- 由后向前找比它小的数,找到后挖出此数填前一个坑 a[i] 中。
  • 3.i++ 由前向后找比它大的数,找到后也挖出此数填到前一个坑 a[j] 中。
  • 4.再重复执行 2,3 二步,直到 i==j,将基准数填入 a[i] 中。
  public static  int partition(int[] arr,int left,int right) {
      int prov = arr[left];
      while (left<right) {
          while(arr[right] >= prov && left<right) {
              right--;
          }
          //右边元素小于prov
          if(left<right) {
              arr[left] = arr[right];
              left++;
          }


          while (arr[left] <= prov && left<right){
              left++;
          }
          //左边元素大于prov
          if(left<right){
              arr[right] = arr[left];
              right--;
          }

      }
      //将prov放入最终位置
      arr[left] = prov;
      return left;
  }

  public static void quickSorted(int[] arr,int left,int right) {
      if(arr == null || left>=right || arr.length <= 1){
          return;
      }
      int mid = partition(arr,left,right);
      quickSorted(arr,left,mid);
      quickSorted(arr,mid+1,right);

  }
  • 时间复杂度:O(N log N),这里 N 是数组的长度;
  • 空间复杂度:O(log N),这里占用的空间主要来自递归函数的栈空间。

2.归并排序

归并排序是建立在归并操作上的一种有效的排序算法,
该算法是采用分治法的一个非常典型的应用。即先使每个子序列有序,
再将已有序的子序列合并,得到完全有序的序列。
public int[] sortArray(int[] nums) {
        sortArray1(nums,0,nums.length-1);
        return nums;
    }

    //递归函数
    public void sortArray1(int[] nums,int left, int right) {
        //递归终止条件
        if(nums == null || left == right) {
            return;
        }
        int mid = left + (right-left)/2;
        sortArray1(nums, left,mid);
        sortArray1(nums, mid+1,right);
        merge(nums,left,right,mid);
    }

    //合并两个有序数组
    public void merge(int[] nums, int left,int right, int mid) {
        int[] arr = new int[right-left+1];
        int lpoint = left;
        int rpoint = mid+1;
        int index = 0;

        while(lpoint <= mid && rpoint <= right){
            if(nums[lpoint] <= nums[rpoint]) {
                arr[index++] = nums[lpoint++];
            }else{
                arr[index++] = nums[rpoint++];
            }
        }

        //左边还有剩余
        while(lpoint <= mid) {
            arr[index++] = nums[lpoint++];
        }

        //右边还有剩余
        while(rpoint <= right){
            arr[index++] = nums[rpoint++];
        }

        //将辅助数组中的元素填充回原数组
        for(int i = 0;i<arr.length;i++) {
            nums[left+i] = arr[i];
        }
    }
  • 间复杂度为O(nlogn)。此外在最坏、最佳、平均情况下归并排序时间复杂度均为O(nlogn)。
  • 空间复杂度分析:在排序过程中使用了一个与原数组等长的辅助数组,估空间复杂度为O(n)。
  • 稳定性分析:由排序过程可以知道,归并排序是一种稳定排序。
  • 是否原地排序:排序过程中用到了辅助数组,所以是非原地排序。

3.插入排序

思路:每次将一个数字插入一个有序的数组里,
成为一个长度更长的有序数组,有限次操作以后,数组整体有序。
    public int[] sortArray(int[] nums) {
            
            for(int i=1;i<nums.length;i++) {
                int temp = nums[i];
                int j=i;
                while(j>0 && nums[j-1] > temp) {
                    nums[j] = nums[j-1];
                    j--;
                }
                nums[j] = temp;
            }
    
            return nums;
        }
  • 时间复杂度: O(N2)
  • 空间复杂度:O(1),使用到常数个临时变量。
posted @ 2021-05-07 19:39  优雅永不过时丿  阅读(142)  评论(0)    收藏  举报