常见的排序算法(插入 希尔 选择 堆 冒泡 快排 归并排序),时间复杂度Java(二)

 6.快速排序

 

下面写一个伪代码

Hoare版

// 假设按照升序对array数组中[left, right)区间中的元素进行排序
void QuickSort(int[] array, int left, int right){
  if(right - left <= 0) 
  return;
// 按照基准值对array数组的 [left, right)区间中的元素进行划分
int div = partition(array, left, right);
// 划分成功后以div为边界形成了左右两部分 [left, div) 和 [div+1, right)
// 递归排[left, div)
QuickSort(array, left, div);
// 递归排[div+1, right)
QuickSort(array, div+1, right);
}
private static int partition(int[] array, int left, int right) {
   int i = left;
   int j = right;
   int pivot = array[left];
  while (i < j) {
   while (i < j && array[j] >= pivot) {
    j--;
   }
   while (i < j && array[i] <= pivot) {
   i++;
   }
   swap(array, i, j);
  }
  swap(array, i, left);
  return i;
}

 挖坑版

// 假设按照升序对array数组中[left, right)区间中的元素进行排序
void QuickSort(int[] array, int left, int right)
{
if(right - left <= 0)
return;
// 按照基准值对array数组的 [left, right)区间中的元素进行划分
int div = partition(array, left, right);
// 划分成功后以div为边界形成了左右两部分 [left, div) 和 [div+1, right)
// 递归排[left, div)
QuickSort(array, left, div);
// 递归排[div+1, right)
QuickSort(array, div+1, right);
}
private static int partition(inr[] array,int left,int right){
 int i = left;
  int j = right;
  int pivot = array[left];
 
  while(i<j){
   while(i<j && array[j] >=pivot){
   j--;
   }
   array[i] = array[j];
   while(i<j&&array[i]<=pivot){
   i++;
   }
   array[j] = array[i];
 }
array[i]=pivot;
return i;
}

时间 复杂度:O(N*logN)

空间复杂度:O(logN)

稳定性:不稳定

最核心的是partition

7.归并排序

归并排序( MERGE-SORT )是建立在归并操作上的一种有效的排序算法 , 该算法是采用分治法( Divide and Conquer )的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使 子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并排序核心步骤:

public static void mergeSortNor(int[] array){
 int gap =1;
  while(gap<array.length){
   for(int i = 0;i<array.length;i+=2*gap){
     int left = i;
     int mid = left+gap-1;
     int right = mid+gap;
//修正mid
     if(mid>=array.length){
      mid = array.length - 1;
   }
   int right = mid+gap;
//修正right
 if(right>=array.length){
     right = array.length -1;
  }
 merge(array,left,mid,right);
 }
 gap*=2;
}
//********合并********
private static void merge(int[] array,int low,int mid,int high){
   int s1 = low;
   int e1 = mid;
   int s2 =  mid+1;
   int e2 = high;
   
   int[] tmpArr = new int[high-low+1];
   int k = 0;
 //证明两个段都有数据
   while(s1<=e1 && s2<=e2){
     if(array[s1] <= array[s2]){
         tmpArr[k++] = array[s1++];
     }else{
          tmpArr[k++] = array[s2++];
     }
   }//剩余元素,全部挪过来
    while(s1<=e1){
      tmpArr[k++]=array[s1++];
    }
     //剩余元素全部挪过来
    while(s2<=e2){
       tmpArr[k++] = array[s2++];
     }
     for(int i = 0;i<tmpArr.length;i++){
        array[i+low] = tmpArr[i];
     }
}

时间复杂度:log₂n

空间复杂度:n

稳定性:稳定(稳定的有 插入,冒泡,归并)

最核心的地方是merge

下面是递归的归并排序

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 直接插入排序:将待排序的数列分为有序区和无序区,从无序区中取出一个元素,插入到有序区中的正确位置,直到无序区为空。时间复杂度为O(n^2)。 2. 希尔排序:将待排序的数列分成若干个子序列,对每个子序列进行插入排序,缩小增量,直到增量为1,最后对整个数列进行一次插入排序。时间复杂度为O(nlogn)。 3. 冒泡排序:比较相邻的两个元素,如果前者大于后者,则交换它们的位置,一次冒泡可以把一个元素排到正确的位置,重复进行n-1次,直到排序完成。时间复杂度为O(n^2)。 4. 快速排序:选定一个基准值,将数列分为左右两个部分,左边的元素都小于基准值,右边的元素都大于基准值,递归地对左右两个部分进行快速排序。时间复杂度为O(nlogn)。 5. 简单选择排序:从待排序的数列中选择最小的元素,放置到已排序数列的末尾,重复该过程,直到待排序数列为空。时间复杂度为O(n^2)。 6. 排序:先将待排序的数列构建成一个最大,然后将顶的元素与末尾元素交换位置,并重新构建最大,重复该过程,直到排序完成。时间复杂度为O(nlogn)。 7. 归并排序:将待排序的数列分成两个部分,对每个部分进行归并排序,然后将两个有序的部分合并成一个有序的数列,递归地进行该过程,直到排序完成。时间复杂度为O(nlogn)。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值