数据结构-排序

各种排序方法时间复杂度、空间复杂度对比

其中“稳定”是指相对次序不会发生改变

最好平均最坏空间
直接插入排序
折半插入排序
希尔排序
冒泡排序O(n)O(n^2)O(n^2)O(1)稳定
快速排序
简单选择排序
堆排序
归并排序O(nlogn)O(nlogn)O(nlogn)O(n)稳定

一、插入排序

1、直接插入排序

2、折半插入排序

3、希尔排序

二、交换排序

1、冒泡排序

代码

void sort(vector<int> &array){
	int n = array.size();
	for(int i=0; i<n-1; i++){
		bool flag = false;
		for(int j=n-1; j>i; j--){
			swap(array[j], array[j-1]);
			flag = true;
		}
		if(!flag) break; //一遍冒泡后没有元素交换位置,说明array已经是有序数组,直接退出
	}
}

2、快速排序

三、选择排序

1、简单选择排序

2、堆排序

四、归并排序

  • 概念:
    • 归并排序是多次将两个或两个以上的有序表合并成一个新的有序表。
    • 二路归并排序:直接将两个有序的子表合并成一个有序的表。
  • 基本思路: 将R[0…n-1]看成是n个长度为1的有序序列,然后进行两两归并,得到n/2向上取整个长度为2(最后一个有序序列的长度可能为2)的有序序列,再进行两两归并,得到n/4向上取整个长度为4(最后一个有序序列的长度可能小于4)的有序序列……,直到得到一个长度为n的有序序列
  • 归并排序每趟产生的有序区只是局部有序的,也就是说在会后一趟排序结束前所有元素并不一定归位了。
  • 时间复杂度:O(nlogn),二路归并logn向上取整趟,每趟归并时间为O(n)
  • 空间复杂度O(n)
    Merge()实现一次归并
void Merge(int low, int mid,int high, vector<int> &array){
    int i=low, j=mid+1;
    vector<int> tmp;
    while(i<=mid && j<=high){
        if(array[i] < array[j])
            tmp.push_back(array[i++]);
        else   
            tmp.push_back(array[j++]);
    }
    while(i<=mid)
        tmp.push_back(array[i++]);
    while(j<=high)
        tmp.push_back(array[j++]);
    for(int k=0, i=low; i<=high; i++, k++){
        array[i] = tmp[k];
    }
}

自底向上

//自底向上
void MergeSort(vector<int>& array){
    int n = array.size();
    for(int length=1; length<n; length*=2){ //进行ogn向上取整,趟归并
        //对整个排序序列进行一趟归并
        //在调用Merge()将相邻的一对子表进行归并时,
        //需要对表的个数可能是奇数以及最后一个子表的长度小于length这两种特殊情况进行特殊处理;
        //若子表个数为奇数,则最后一个子表无须和其他子表归并(本趟轮空);
        // 若子表个数为偶数,则要注意到最后一对子表中后一个子表的区间上界是n-1。 
        int i;
        for(i=0; i+2*length-1<n; i+=2*length){ //归并length长的两相邻子表
            Merge(i, i+length-1, i+2*length-1, array);
        }
        if(i+length-1 < n-1){   //偶数,余下两个子表,后者的长度小于length
            Merge(i, i+length-1, n-1, array); //归并这两个子表
        }
    }
}

自顶向下

//自顶向下
void MergeSort(int low, int high,vector<int> &array){
    if(low<high){
        int mid = low +((high-low)>>1);
        MergeSort(low, mid, array);
        MergeSort(mid+1, high, array);
        Merge(low, mid, high, array);
    }
}

例题

1、NC140 排序【字节跳动、百度、阿里巴巴、度小满】

题解:归并排序
时间复杂度:O(nlogn)。二路归并logn向上取整趟,每趟归并时间为O(n)
空间复杂度:O(n)
自底向上

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 将给定数组排序
     * @param arr int整型vector 待排序的数组
     * @return int整型vector
     */
    void merge(int low, int mid, int high, vector<int>  &arr){
        int i = low, j = mid+1;
        vector<int> tmp;
        while(i <= mid && j <= high){
            if(arr[i] <= arr[j]) tmp.push_back(arr[i++]);
            else tmp.push_back(arr[j++]);
        }
        while(i <= mid){
            tmp.push_back(arr[i++]);
        }
        while(j <= high){
            tmp.push_back(arr[j++]);
        }
        for(int k = 0, i = low; k<tmp.size(); k++, i++){
            arr[i] = tmp[k];
        }
    }
    vector<int> MySort(vector<int>& arr) {
        // write code here
        int n = arr.size();
        for(int length = 1; length < n; length *= 2){
            int i;
            for(i=0; i+2*length-1 < n; i+=2*length){
                merge(i, i+length-1, i+2*length-1, arr);
            }
            if(i<n){
                merge(i, i+length-1, n-1, arr);
            }
        }
        return arr;
    }
};

自顶向下

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 将给定数组排序
     * @param arr int整型vector 待排序的数组
     * @return int整型vector
     */
    void merge(int low, int mid, int high, vector<int>  &arr){
        int i = low, j = mid+1;
        vector<int> tmp;
        while(i <= mid && j <= high){
            if(arr[i] <= arr[j]) tmp.push_back(arr[i++]);
            else tmp.push_back(arr[j++]);
        }
        while(i <= mid){
            tmp.push_back(arr[i++]);
        }
        while(j <= high){
            tmp.push_back(arr[j++]);
        }
        for(int k = 0, i = low; k<tmp.size(); k++, i++){
            arr[i] = tmp[k];
        }
    }
    void sort(int low, int high, vector<int> &arr){
        if(low < high){
            int mid = low + ((high - low)>>1);
            sort(low, mid, arr);
            sort(mid+1, high, arr);
            merge(low, mid, high, arr);
        }
    }
    vector<int> MySort(vector<int>& arr) {
        // write code here
        sort(0, arr.size()-1, arr);
        return arr;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值