美文网首页
排序算法总结

排序算法总结

作者: 不学习不快乐 | 来源:发表于2019-12-26 21:57 被阅读0次

1. 排序算法

1.1. 排序算法比较


排序算法 平均时间复杂度 最差时间复杂度 空间复杂度 数据对象稳定性
冒泡排序 O(n2) O(n2) O(1) 稳定
选择排序 O(n2) O(n2) O(1) 数组不稳定,链表稳定
插入排序 O(n2) O(n2) O(1) 稳定
快速排序 O(nlog2n) O(n2) O(log2n) 不稳定
归并排序 O(nlog2n) O(nlog2n) O(n) 稳定
希尔排序 O(nlog2n) O(n2) O(1) 不稳定
堆排序 O(nlog2n) O(nlog2n) O(1)
计数排序 O(n+k) O(m+n) O(k) 稳定
桶排序 O(n+k) O(n) O(n+k) 稳定
基数排序 O(n*k) O(n2) O(n+k) 稳定
锦标赛排序

1.2. 排序算法详解

1.2.1. 起泡排序

insertionSort
  • 起泡排序思路:
    1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
    2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
    3. 针对所有的元素重复以上的步骤,除了最后一个。
    4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

<details><summary>实现</summary>

void swap(int & a, int & b) {
    int c = a;
    a = b;
    b = c;
}
int bubble(int *num, int m) {
    int flag = 0;
    for (int i = 1; i < m; i++) {
        if (num[i-1] > num[i]) {
            swap(num[i-1], num[i]);
            flag = i;
        }
    }
    return flag;
}
void bubbleSort(int *num, int n) {
    int fl = bubble(num, n);
    while (fl) {
        fl = bubble(num, fl);
    }
}

<span id = "SelectionSort"></span>

1.2.2. 选择排序

image
  • 选择排序思路:
    1. 在未排序序列中找到最小(大)元素,存放到排序序列的起始位置
    2. 从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾
    3. 以此类推,直到所有元素均排序完毕
void SelectionSort(vector<int>& v) {
    int min, len = v.size();
    for (int i = 0; i < len - 1; ++i) {
        min = i;
        for (int j = i + 1; j < len; ++j) {
            if (v[j] < v[min]) {    // 标记最小的
                min = j;
            }
        }
        if (i != min)  // 交换到前面
            swap(v[i], v[min]);
    }
}

// 模板实现
template<typename T> 
void Selection_Sort(std::vector<T>& arr) {
    int len = arr.size();
    for (int i = 0; i < len - 1; i++) {
        int min = i;
        for (int j = i + 1; j < len; j++)
            if (arr[j] < arr[min])
                min = j;
        if(i != min)
            std::swap(arr[i], arr[min]);
    }
}

<span id = "InsertSort"></span>

1.2.3. 插入排序

image
  • 插入排序思路:
    1. 从第一个元素开始,该元素可以认为已经被排序
    2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
    3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
    4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
    5. 将新元素插入到该位置后
    6. 重复步骤2~5
void InsertSort(vector<int>& v)
{
  int len = v.size();
    for (int i = 1; i < len - 1; ++i) {
        int temp = v[i];
        for(int j = i - 1; j >= 0; --j)
        {
            if(v[j] > temp)
            {
                v[j + 1] = v[j];
                v[j] = temp;
            }
            else
                break;
        }
    }
}

<span id = "QuickSort"></span>

1.2.4. 快速排序

image
  • 快速排序思路:
    1. 选取第一个数为基准
    2. 将比基准小的数交换到前面,比基准大的数交换到后面
    3. 对左右区间重复第二步,直到各区间只有一个数
int partition(vector<int> & num, int lo, int hi) {
    int pivot = num[lo];
    int temp = lo;
    while (lo < hi) {
        while ((lo < hi) && (pivot <= num[hi]))
            hi--;
        num[lo] = num[hi];
        while ((lo < hi) && (pivot >= num[lo]))
            lo++;
        num[hi] = num[lo];
        //std::swap(num[hi], num[lo]);
    }
    num[lo] = pivot;
    //std::swap(num[lo], num[temp]);
    //for (auto w : num)
    //  cout << w << "  ";
    //cout << endl;
    return lo;
}

void quickSo(vector<int> & num, int lo, int hi) {
    if (hi - lo < 2)
        return;
    int mi = partition(num, lo, hi - 1);
    quickSo(num,lo, mi);
    quickSo(num,mi + 1, hi);
}

void quickSort(vector<int> & num) {
    quickSo(num, 0, num.size());
}

迭代实现

// ----------------------------------------------------

// 模板实现快速排序(迭代)
struct Range {
    int start, end;
    Range(int s = 0, int e = 0) {
        start = s, end = e;
    }
};
template <typename T> // 整數或浮點數皆可使用,若要使用物件(class)時必須設定"小於"(<)、"大於"(>)、"不小於"(>=)的運算子功能
void quick_sort(T arr[], const int len) {
    if (len <= 0)
        return; // 避免len等於負值時宣告堆疊陣列當機
    // r[]模擬堆疊,p為數量,r[p++]為push,r[--p]為pop且取得元素
    Range r[len];
    int p = 0;
    r[p++] = Range(0, len - 1);
    while (p) {
        Range range = r[--p];
        if (range.start >= range.end)
            continue;
        T mid = arr[range.end];
        int left = range.start, right = range.end - 1;
        while (left < right) {
            while (arr[left] < mid && left < right) left++;
            while (arr[right] >= mid && left < right) right--;
            std::swap(arr[left], arr[right]);
        }
        if (arr[left] >= arr[range.end])
            std::swap(arr[left], arr[range.end]);
        else
            left++;
        r[p++] = Range(range.start, left - 1);
        r[p++] = Range(left + 1, range.end);
    }
}

<span id = "MergeSort"></span>

1.2.5. 归并排序

image
  • 核心思想:分而治之
  • 实现步骤:
void MergeSort(){
    递归条件
    分组1
    分组2
    归并
}

递归实现

template<typename T>
void merge(vector<T> &num, int lo, int mi, int hi) {
    int lb = mi - lo;
    int lc = hi - mi;
    T *pa = &num[lo];
    T *pb = new T[lb];
    T *pc = &num[mi];
    for (int i = 0; i < lb; i++) {
        pb[i] = pa[i];
    }
    for (int m = 0, n = 0, k = 0; (m < lb) || (n < lc);) {
        if ((m < lb) && ((n >= lc) || (pb[m] < pc[n])))
            pa[k++] = pb[m++];
        else
            pa[k++] = pc[n++];
    }
}
template <typename T>
void mergeSort(vector<T> & A,int lo, int hi) {
    if (hi - lo < 2)        //递归条件
        return;
    int mi = (hi + lo) >> 1;
    mergeSort(A,lo, mi);
    mergeSort(A,mi, hi);
    merge(A,lo, mi, hi);
}

迭代实现

template<typename T>
void merge_sort(T arr[], int len) {
    T* a = arr;
    T* b = new T[len];
    for (int seg = 1; seg < len; seg += seg) {
        for (int start = 0; start < len; start += seg + seg) {
            int low = start, mid = min(start + seg, len), high = min(start + seg + seg, len);
            int k = low;
            int start1 = low, end1 = mid;
            int start2 = mid, end2 = high;
            while (start1 < end1 && start2 < end2)
                b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
            while (start1 < end1)
                b[k++] = a[start1++];
            while (start2 < end2)
                b[k++] = a[start2++];
        }
        T* temp = a;
        a = b;
        b = temp;
    }
    if (a != arr) {
        for (int i = 0; i < len; i++)
            b[i] = a[i];
        b = a;
    }
    delete[] b;
}

<span id = "ShellSort"></span>

1.2.6. 希尔排序

算法思想
算法思想来源于插入排序,
先将n个待排序的序列分割成n/2组数据分别进行插入排序,
然后依次分割成n/4组,n/8组,
直至最后只能分成一组数据进行插入排序
算法演示

1940317-0f04f8b6aec097bb

算法实现:

//希尔排序
void shellSort(int *p, int n) {
    int temp = n;
    while (temp >>= 1) {
        for (int i = temp; i < n; i++) {
            for (int j = i; j > 0; j -= temp) {
                if (p[j] < p[j - temp]) {
                    Swap(p[j], p[j - temp]);
                    break;
                }
            }
        }
    }
}

<span id = "CountSort"></span>

1.2.7. 计数排序

算法思想
对值比较集中的数据进行排序先统计每个数据个数,再根据个数进行排序

算法图解

countingSort

算法实现

//计数排序
void countSort(int *p, int n) {
    int max = p[0];
    int min = p[0];
    for (int i = 0; i < n; i++) {       //找到最小与最大值
        if (max < p[i])
            max = p[i];
        if (min > p[i])
            min = p[i];
    }
    int space = max - min + 1;          
    int *num = new int[space]();        //申请辅助空间
    for (int i = 0; i < n; i++) {       //统计
        num[p[i] - min]++;
    }
    int j = 0;
    for (int i = 0; i < space; i++) {   //排序
        while (num[i]--) {
            p[j++] = i+min;
        }
    }
    delete[]num;
}

<span id = "BucketSort"></span>

1.2.8. 桶排序

<span id = "RadixSort"></span>

1.2.9. 基数排序

image

<span id = "HeatSort"></span>

1.2.10. 堆排序

image

相关文章

  • iOS算法总结-堆排序

    iOS算法总结-堆排序 iOS算法总结-堆排序

  • iOS算法总结-冒泡排序

    iOS算法总结-冒泡排序 iOS算法总结-冒泡排序

  • 算法学习(1)-排序算法

    八大排序算法九大排序算法再总结[经典排序算法][集锦][直观学习排序算法] 视觉直观感受若干常用排序算法 快速排序...

  • 面试常问的排序算法

    排序算法总结 排序是算法问题中的经典问题。为什么要总结排序算法呢?你懂的 : (假设所有的排序都是要求最终结果为:...

  • 浅谈排序算法

    排序算法有很多种,今天先谈谈一些简单的排序算法。包括桶排序、冒泡排序和快速排序算法。后期总结各种排序算法。 桶排序...

  • 排序算法

    一、排序算法总结 排序算法题目 排序算法快速排序堆排序归并排序 应用最小K个数(TopK问题)215.数组中的第K...

  • 一文搞定十大经典排序算法(Java实现)

    本文总结十大经典排序算法及变形,并提供Java实现。参考文章:十大经典排序算法总结(Java语言实现)快速排序算法...

  • Swift的十大经典排序算法总结

    Swift的十大经典排序算法总结 排序算法是《数据结构与算法》中最基本的算法之一。排序算法可以分为内部排序和外部排...

  • 算法-排序算法总结

    排序类型总结 1 排序算法基础实现 2 排序算法应用 2.1 基础排序 2.2 计数排序应用 2.3 快排应用 2...

  • 排序算法最强总结及其代码实现(Python/Java)

    前言 本文总结了常用的全部排序算法,内容包括: 排序算法的定义和思路 排序算法的代码实现:Python和Java,...

网友评论

      本文标题:排序算法总结

      本文链接:https://www.haomeiwen.com/subject/bqzloctx.html