经典排序算法C++全实现:插入、选择、冒泡、快排、归并、基数,堆排、希尔...

以下代码是个人学习排序算法的一些实践,实现了大部分排序算法的升序版本,并且对每一种算法进行了简要的介绍和复杂度分析。涉及的算法如下:插入排序:直接插入排序、折半插入排序、希尔排序交换排序:冒泡排序、快速排序选择排序:简单选择排序、堆排序其他类型:归并排序、基数排序#include <iostream>#include <string>#include &...
摘要由CSDN通过智能技术生成

以下代码是个人学习排序算法的一些实践,实现了大部分排序算法的升序版本,并且对每一种算法进行了简要的介绍和复杂度分析。

涉及的算法如下:

  1. 插入排序:直接插入排序、折半插入排序、希尔排序
  2. 交换排序:冒泡排序、快速排序
  3. 选择排序:简单选择排序、堆排序
  4. 其他类型:归并排序、基数排序
#include <iostream>
#include <string>
#include <vector>
using namespace std;


// 以下排序均为升序算法
void printArray(vector<int> A){
   
    for(int i = 0; i < A.size(); i++){
   
        cout << A[i] << " ";
    }
    cout << endl << endl;
}

/************************************

        插入排序

        1. 直接插入排序
        2. 折半插入排序
        3. 希尔排序(shell)

*************************************/

vector<int> simpleInsertSort(vector<int> A){
   
    /**
    -- 简单插入排序的思想
    从数组的第二个元素开始,将其选为目标待排序
    认定元素左边的序列为有序,而右边的序列为无序
    将目标元素和左边序列从后向前进行比较,找到插入有序的位置t之后,
    先将该位置之后的元素往后移动1位,然后将目标元素插入到位置t

    空间效率:O(1)
    时间效率:O(n^2)
    最好情况 顺序,O(n)
    最坏情况:逆序,比较次数达到最大,移动次数达到最大
    稳定的排序算法:不会改变相同关键字元素的相对位置。

    适用于顺序存储和链式存储的线性表,适合基本有序和数据量不大的情况
    **/
    if(A.size() <= 1) return A;
    for(int i = 1; i < A.size(); i++){
   
        if(A[i] < A[i - 1]){
   
            int tmp = A[i];
            int j = 0;
            for(j = i - 1; j >= 0 && tmp < A[j]; j--)
                A[j + 1] = A[j];
            A[j + 1] = tmp;
        }
    }
    return A;
}

vector<int> binaryInsertSort(vector<int> A){
   
    /**
    折半插入在简单插入排序的基础上进行了改进
    在向前查找插入位置时使用了二分查找的方法,减少了比较的次数
    折半插入减少了比较的次数,约为 O(nlog2), 元素移动次数没有发生改变O(n^2)
    **/
    int i, j, low, high, mid;
    for(i = 1; i < A.size(); i++){
   
        int tmp = A[i];
        low = 0;
        high = i - 1;
        while(low <= high){
   
            mid = (low + high) / 2;
            if(A[mid] > tmp) high = mid-1;
            else low = mid + 1;
        }
        for(j = i - 1; j >= high + 1; j--)
            A[j + 1] = A[j];
        A[high + 1] = tmp;
    }
    return A;
}

vector<int> shellSort(vector<int> A){
   
    /****
    希尔排序,又称缩小增量排序,由于简单插入排序很适合基本有序的序列,
    那么可以对一些较乱的序列进行处理,使之变为基本有序的序列,
    然后在进行一次直接插入排序。
    思想如下:
    先将数组分割成若干子数组,如[i, i+d, i+2d, i+kd]。
    d为步长,小于,数组长度。这样整个数组就可以分成d个子数组。
    分别对这d个子数组进行直接插入排序。
    进行下一轮,取更小的步长e,重复上述动作,知道步长等于1,在进行一次直接插入排序完成。

    希尔排序是不稳定的,仅适用于顺序存储的线性表
    时间复杂度为O(n^2),空间复杂度为O(1)
    *****/
    for(int d = A.size() / 2; d > 0; d /= 2){
   
        for(int i = d; i < A.size(); i++){
   
            int tmp = A[i];
            int j = 0;
            for(j = i; j >= d && A[j - d] > tmp; j -= d)
                A[j] = A[j-d];
            A[j] = tmp
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值