数据结构之七大排序

常见的排序算法分为四类:插入排序(直接插入,希尔),选择排序(选择,堆),交换排序(冒泡,快速),归并排序
1.直接插入排序:
**public static void insertsort(int[] nums){ for(int i=1; i<nums.length;i++){ int key=nums[i]; int j=i-1; for(;j>=0&&nums[j]>key;j--){ nums[j+1]=nums[j]; } nums[j+1]=key; } }
时间复杂度
| 最好 | 平均 | 空间复杂度 稳定
| O(n) | O(n^2)| O(1)
2.希尔排序
排序思想:先选定一个整数,把待排序文件中所有记录分成组,所有距离相同的记录分在同一组内,并对每一组内的记录进行排序。然后,重复上述分组和排序的工作。当到达n=1时,所有记录在统一组内排好序。

public static void shellsort(int[] nums){
    int gap=nums.length;
    while(gap>1){
        insertGap(nums,gap);
        gap=gap/3+1;
    }
    insertGap(nums,1);
}

private static void insertGap(int[] nums, int gap) {
    for(int i=1;i<nums.length;i++){
        int key=nums[i];
        int j=i-gap;
        for(;j>=0&&nums[j]>key;j-=gap){
            nums[j+gap]=nums[j];
        }
        nums[j+gap]=key;
    }
}

时间复杂度
| 最好 | 平均 |空间复杂度
|-O(n)-|-O(n^1.3)-|O(1)
稳定性:不稳定

3.选择排序
排序思想:每一次从无序区间选出最大(或最小)的一个元素,存放在无序区间的最后(或最前),直到全部待排序的数据元
素排完 。

public static void selectSort(int[] nums){
    for(int i=0;i<nums.length;i++){
        int min=i;
        for(int j=i+1;j<nums.length;j++){
            if(nums[min]>nums[j]){
                min=j;
            }
            swap(nums,min,i);
        }

    }
}

private static void swap(int[] nums, int min, int i) {
    int t=nums[min];
    nums[min]=nums[i];
    nums[i]=t;
}

时间复杂度O(n^2),空间复杂度:O(1),数据不稳定。
4.堆排序
排序思想:基本原理也是选择排序,只是不在使用遍历的方式查找无序区间的最大的数,而是通过堆来选择无序区间的最大的数。
注意: 排升序要建大堆;排降序要建小堆。

public static void heapSort(int[] nums){
    createheap(nums);
    for(int i=0;i<nums.length-1;i++){
        swap(nums,0,nums.length-i-1);
        shiftDown(nums,nums.length-1-i,0);
    }
}

private static void shiftDown(int[] nums, int size, int i) {
    int left=i*2+1;
    while (left < size) {
        int right=left+1;
        int max=left;
        if(right<size&&nums[left]<nums[right]){
            max=right;
        }
        if(nums[max]<nums[i]){
            break;
        }
        swap(nums,max,i);
        i=max;
        left=i*2+1;
    }

}

private static void createheap(int[] nums) {
    for(int i=(nums.length-1)/2;i>=0;i--){
        shiftDown(nums,nums.length,i);
    }
}

时间复杂度:O(n*logn) ,空间复杂度:O(1),数据不稳定。
5.冒泡排序
排序思想:在无序区间,通过相邻数的比较,将最大的数冒泡到无序区间的最后,持续这个过程,直到数组整体有序

public static void bubbleSort(int[] nums){
    for(int i=0;i<nums.length-1;i++){
        for(int j=0;j<nums.length-i-1;j++){
            if(nums[j+1]<nums[j]){
                swap(nums,j,j+1);
            }
        }
    }
}

时间复杂度:O(n^2),空间复杂度:O(1),数据稳定
6.快速排序
排序思想:

  1. 从待排序区间选择一个数,作为基准值(pivot);
  2. Partition: 遍历整个待排序区间,将比基准值小的(可以包含相等的)放到基准值的左边,将比基准值大的
    (可以包含相等的)放到基准值的右边;
  3. 采用分治思想,对左右两个小区间按照同样的方式处理,直到小区间的长度 ==1,代表已经有序,或者小区
    间的长度 == 0= 0,代表没有数据。
public static void QuickSort(int[] array){
    quickSortInter(array,0,array.length-1);
}

private static void quickSortInter(int[] array, int left, int right) {
    if(left>=right){
        return;
    }
    int pivotIndex=partition(array,left,right);
    quickSortInter(array,left,pivotIndex-1);
    quickSortInter(array,pivotIndex+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,left,i);
    return i;
}

时间复杂度:O(n*logn) 空间复杂度:O(logn),数据不稳定
7.归并排序
排序思想:归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and
Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使
子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

public static void mergeSort(int[] array){
    mergeSortIntel(array,0,array.length);
}

private static void mergeSortIntel(int[] array, int low, int high) {
    if(low>=high-1){
        return;
    }
    int mid=(low+high)/2;
    mergeSortIntel(array,low,mid);
    mergeSortIntel(array,mid,high);
    merge(array,low,mid,high);
}

private static void merge(int[] array, int low, int mid, int high) {
    int length=high-low;
    int[] a=new int[length];
    int left=low;
    int mid2=mid;
    int k=0;
    while(left<mid&&mid2<high){
        if(array[left]<=array[mid2]){
            a[k++]=array[left++];
        }
        else{
            a[k++]=array[mid2++];
        }
    }
    while(left<mid){
        a[k++]=array[left++];
    }
    while(mid2<high){
        a[k++]=array[mid2++];
    }
   for(int i=0;i<length;i++){
        array[low+i]=a[i];
   }
}

时间复杂度:O(n*logn),空间复杂度:O(n),数据稳定
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值