美文网首页
排序技术

排序技术

作者: BlueFishMan | 来源:发表于2020-06-23 10:22 被阅读0次
排序算法 平均时间复杂度 最好 最差 空间复杂度 稳定性
直接插入排序 O(n2) O(n) O(n2) O(1) 稳定
冒泡排序 O(n2) O(n) O(n2) O(1) 稳定
快速排序 O(n*log2n) O(n*log2n) O(n2) O(log2n) 不稳定
简单选择排序 O(n2) O(n2) O(n2) O(1) 不稳定
堆排序 O(n*log2n) O(n*log2n) O(n*log2n) O(1) 不稳定
归并排序 O(n*log2n) O(n*log2n) O(n*log2n) O(n) 稳定

插入排序

直接插入排序(straight insertion sert)

交换排序

冒泡排序(bubble sort)

void bubbleSort(vector<int> &a) {
    int exchange = a.size() - 1;// 第一趟冒泡排序的区间是[0,n-1]
    while (exchange > 0) {// 当上一趟排序有记录交换时
        int bound = exchange;
        exchange = 0;
        for (int i = 0; i < bound; i++) {// 一趟冒泡排序,排序区间是[0,bound-1]
            if (a[i] > a[i + 1]) {
                swap(a[i], a[i + 1]);
                exchange = i;// 记载每一次记录交换的位置
            }
        }
    }
}

快速排序(quick sort)

int partition(vector<int> &a, int front, int end) {
    while (front < end) {
        while (front < end && a[front] <= a[end]) {// 右侧扫描
            end--;
        }
        if (front < end) {
            swap(a[front], a[end]);// 将较小记录交换到前面
            front++;
        }
        while (front < end && a[front] <= a[end]) {// 左侧扫描
            front++;
        }
        if (front < end) {
            swap(a[front], a[end]);// 将较大记录交换到后面
            end--;
        }
    }
    return front;// 轴值记录的最终位置
}

void quickSort(vector<int> &a, int front, int end) {
    if (front < end) {// 区间长度大于1,执行一次划分,否则递归结束
        int pivot = partition(a, front, end);// 一次划分
        quickSort(a, front, pivot - 1);// 递归地对左侧子序列进行快速排序
        quickSort(a, pivot + 1, end);// 递归地对右侧子序列进行快速排序
    }
}

选择排序

简单选择排序(simple selction sort)

void selectSort(vector<int> &a) {
    for (int i = 0; i < a.size() - 1; i++) {// 对n个记录进行n-1躺简单选择排序
        int index = i;
        for (int j = i + 1; j < a.size(); j++) {// 在无序区中选取最小记录
            if (a[index] > a[j]) {
                index = j;
            }
        }
        if (index != i) {
            swap(a[i], a[index]);
        }
    }
}

堆排序(heap sort)

堆(heap) 完全二叉树(数组)

  • 小根堆(结点<=左结点 && 结点<=右结点)
  • 大根堆(结点>=左结点 && 结点>=右结点)
void sift(vector<int> &a, int front, int end) {
    int i = front, j = 2 * i + 1;// i指向被筛选结点,j指向结点i的左孩子
    while (j <= end) {// 筛选还没有进行到叶子
        if (j + 1 <= end && a[j + 1] > a[j]) {// 比较i的左右孩子,j指向较大者
            j++;
        }
        if (a[i] >= a[j]) {// 根结点已经大于左右孩子中的较大者
            break;
        } else {
            swap(a[i], a[j]);// 将根结点与结点j交换
            i = j; // 被筛结点位于原来结点j的位置
            j = 2 * i + 1;
        }
    }
}

void heapSort(vector<int> &a) {
    for (int i = a.size() / 2 - 1; i >= 0; i--) {// 初始建堆,从最后一个分支结点至根结点
        sift(a, i, a.size() - 1);
    }

    for (int i = 0; i < a.size(); i++) {// 重复执行移走堆顶及重建堆的操作
        swap(a[0], a[a.size() - 1 - i]);
        sift(a, 0, a.size() - 1 - i - 1);
    }
}

归并排序

二路归并排序

void merge(vector<int> &a, int front, int middle, int end) {
    int i = front, j = middle + 1;
    vector<int> b(end - front + 1);
    int k = 0;

    while (i <= middle && j <= end) {// 取a[i]和a[j]中的较小者放入b[k]
        if (a[i] <= a[j]) {
            b[k++] = a[i++];
        } else {
            b[k++] = a[j++];
        }
    }
    while (i <= middle) {// 若第一个子序列没处理完,则进行收尾处理
        b[k++] = a[i++];
    }
    while (j <= end) {// 若第二个子序列没处理完,则进行收尾处理
        b[k++] = a[j++];
    }

    for (int m = 0; m < k; m++) {
        a[front + m] = b[m];
    }
}

void mergeSort(vector<int> &a, int front, int end) {
    if (front < end) {
        int middle = (front + end) / 2;
        mergeSort(a, front, middle);// 归并排序前半个子序列
        mergeSort(a, middle + 1, end);// 归并排序后半个子序列
        merge(a, front, middle, end);// 将两个已排序的子序列归并
    }
}

排序

sort

对区间进行排序

bool cmp(int a, int b) {
    return a > b;
}

sort(a.begin(), a.end());
sort(a.begin(), a.end(), cmp);
sort(a.begin(), a.end(), less<>());
sort(a.begin(), a.end(), less_equal<>());
sort(a.begin(), a.end(), greater<>());
sort(a.begin(), a.end(), greater_equal<>());

stable_sort

对区间进行排序,并保留相同元素的相对顺序

  • 归并排序

partial_sort

对区间进行部分排序,提供完整排序的前n个元素

  • 堆排序
partial_sort(a.begin(), a.begin() + 5, a.end());

相关文章

  • 算法与数据结构知识汇总(八、常见的八大排序算法)

    排序技术有:插入排序(直接插入排序、希尔排序)、选择排序(简单选择排序、堆排序)、交换排序(冒泡排序、快速排序)、...

  • 排序技术

    排序算法平均时间复杂度最好最差空间复杂度稳定性直接插入排序O(n2)O(n)O(n2)O(1)稳定冒泡排序O(n2...

  • 11.18-11.24周复盘

    一、技术 1.算法学习(冒泡排序、选择排序、插入排序、希尔排序、归并排序),待学:堆排序、桶排序 2.搭建第一个s...

  • 排序【日期排序 or 字符串排序】

    微信搜索【Miles】发送 【技术点】获取公众号 日期排序 字符串排序

  • Java基础(冒泡排序与选择排序)

    冒泡排序 冒泡排序算法运行起来非常慢,但在概念上它是排序算法中最简单的,因此冒泡排序算法在刚开始研究排序技术时是一...

  • C语言中排序方法的使用

    C语言中排序方法 学习目的 今天我们学习了三种排序方法:冒泡排序法、选择排序法、插入排序法。 相关技术,及其实用 ...

  • 排序算法总结

    排序算法总结 分类编程技术 排序算法平均时间复杂度 冒泡排序O(n2) 选择排序O(n2) 插入排序O(n2) 希...

  • 复习排序技术

    彼岸焦点分享第71天(2018.9.8) 排序技术无论在咨询中,或是个人生活学习中,是很实用的。 人在...

  • 算法-快速排序算法

    青峰科技19小时前快速排序算法是分治算法技术的一个实例,也称为分区交换排序。快速排序采用递归调用对元素进行排序,是...

  • 简单排序--冒泡排序(一)

    冒泡排序算法运行起来非常缓慢,但在概念上它是排序算法中最简单的,因此冒泡排序算法在刚开始研究排序技术时是一个非常好...

网友评论

      本文标题:排序技术

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