IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> C++实现十大排序算法 -> 正文阅读

[数据结构与算法]C++实现十大排序算法

目录

0 概述

1 冒泡排序

2 选择排序

3 插入排序

4 希尔排序

5 归并排序

6 堆排序

7 快速排序

8 计数排序

9 桶排序

10 基数排序


?本文为C++实现的十大排序算法及基于排序算法解决的一些常见问题,每一种算法均实际运行,确保正确无误。文中内容为自己的一些理解,如有错误,请大家指正。

0 概述

在十种排序算法中,前七种是比较类排序,后三种是非比较类排序,每种算法的最好、最坏、平均时间复杂度,空间复杂度以及稳定性如下表所示。稳定性是指排序前后相等的元素相对位置保持不变。

排序算法平均时间复杂度最好情况最坏情况空间复杂度稳定性
冒泡排序O(n2)O(n)O(n2)O(1)稳定
选择排序O(n2)O(n2)O(n2)O(1)不稳定
插入排序O(n2)O(n)O(n2)O(1)稳定
希尔排序O(nlogn)O(n^{1.3})O(n2)O(1)不稳定
归并排序O(nlogn)O(nlogn)O(nlogn)O(n + logn)稳定
堆排序O(nlogn)O(nlogn)O(n2)O(logn)不稳定
快速排序O(nlogn)O(nlogn)O(nlogn)O(1)不稳定
计数排序O(n + k)O(n + k)O(n2)O(n + k)稳定
桶排序O(n + k)O(n + k)O(n + k)O(k)稳定
基数排序O(n × k)O(n × k)O(n × k)O(n + k)稳定

具体思路和代码均为顺序排序。

前三种排序比较类似,都是将数组划分成已排序部分未排序部分,因此有两层循环,一层循环划分已排序和未排序部分的边界,一层循环选择不同的方法依次对未排序的部分进行排序。

1 冒泡排序

顾名思义,冒泡排序(bubble sort)是将最大的数依次 “上浮” 到数组的末尾,实现数组有序。

具体的算法实现原理:

两层循环,第一层划分边界,从后向前。第二层循环从最前往后依次两两比较,如果前面的数比后面的数大,则交换两个数,如果前面的数比后面的数小,则保持不变。

动态图解:

代码:

#include <iostream>
#include <vector>
using namespace std;
 
//冒泡排序
void bubbleSort(vector<int> &vec){
    int len = vec.size();
    if (len <= 1){
        return;
    }
    for (int i = len -1; i > 0; i--){
        bool flag = false;  //使用flag判断j前面的子序列是否已经有序
        for (int j = 0; j < i; j++){
            if (vec[j] > vec[j + 1]){
                swap(vec[j], vec[j + 1]);
                flag = true;
            }
        }
        if (!flag){
            break;
        }
    }
}
 
//打印数组
void printVec(vector<int> vec){
    for (auto c : vec){
        cout << c << " ";
    }
    cout << endl;
}
 
//test
int main(){
    vector<int> test_vec = {1, 2, 5, 7, 3, 5, 9, 33, 44, 99, 55};
    printVec(test_vec);
    bubbleSort(test_vec);
    printVec(test_vec);    
    system("pause");
    return 0;
}

2 选择排序

具体的算法实现原理:

选择排序(selection sort)已排序部分为数组的前部,然后选择数组后部未排序中的最小的数依次与未排序的第一个数交换(交换会造成排序不稳定),然后边界后移,继续选择、交换,直到数组有序。

两层循环,第一层划分边界,第二层循环查找未排序部分最小的数,并与未排序部分的第一个数交换。

动态图解:

代码:

#include <iostream>
#include <vector>
using namespace std;
 
//选择排序
void selectSort(vector<int> &vec){
    int len = vec.size();
    if (len <= 1){
        return;
    }
     
    for (int i = 0; i < len; i++){
        int min = i;
        for (int j = i; j < len; j++){
            if (vec[j] < vec[min]){
                min = j;
            }
        }
        swap(vec[i], vec[min]);
    }
}
 
//打印数组
void printVec(vector<int> vec){
    for (auto c : vec){
        cout << c << " ";
    }
    cout << endl;
}
 
//test
int main(){
    vector<int> test_vec = {1, 5, 2, 7, 3, 5, 9, 33, 44, 99, 55};
    printVec(test_vec);
    selectSort(test_vec);
    printVec(test_vec);    
    system("pause");
    return 0;
}

3 插入排序

具体的算法实现原理:

插入排序(insertion sort)已排序部分也为数组的前部,然后将未排序部分的第一个数插入到已排序部分的合适的位置。

两层循环,第一层划分边界,第二层循环将已排序部分的数从后向前依次与未排序部分的第一个数比较,若已排序部分的数比未排序部分的第一个数大则交换,这样未排序部分的第一个数就插入到已排序部分的合适的位置,然后向后移动边界,重复此过程,直到有序。

动态图解:

?代码:

#include <iostream>
#include <vector>
using namespace std;
 
//插入排序
void insertSort(vector<int> &vec){
    int length = vec.size();
    if (length <= 1){
        return;
    }
    for (int i = 1; i < length - 1; i++){
        //int temp = vec[i];
        for (int j = i - 1; j >= 0; j--){
            if (vec[j] > vec[j + 1]){
                swap(vec[j+1], vec[j]);
            }
        }
    }
}
 
//打印数组
void printVec(vector<int> vec){
    for (auto c : vec){
        cout << c << " ";
    }
    cout << endl;
}
 
//test
int main(){
    vector<int> test_vec = {1, 5, 2, 7, 3, 5, 9};
    printVec(test_vec);
    insertSort(test_vec);
    printVec(test_vec);    
    system("pause");
    return 0;
}

4 希尔排序

希尔排序是插入排序的升级,算法原理如下:

1) 首先,从数组的首元素开始每隔“步长(间隔)”个元素就挑选一个元素出来作为子数组元素;

2) 然后每个子数组各自进行比较,比较好后,每个子数组都有顺序,进入下一轮,步长(间隔)减少,再根据步长(间隔)分组进行比较;

3) 重复以上操作,最后就有序了。
图解:

?代码:

#include <iostream>
#include <vector>
using namespace std;
 
//希尔排序
void shellSort(vector<int> &vec){
    int len = vec.size();
    if (len <= 1) return;
    //以h为步长划分数组,h /= 2为缩小的增量,数字2可自己根据数据选择
    for (int h = len / 2; h > 0; h /= 2){
        //以下为插入排序
        for (int j = h; j < len; j++){
            int temp = vec[j];
            for (int k = j - h; k >= 0; k -= h){
                if (vec[k] > temp){
                    swap(vec[k], vec[k + h]);
                }
            }
        }
    }
}
 
//打印数组
void printVec(vector<int> vec){
    for (auto c : vec){
        cout << c << " ";
    }
    cout << endl;
}
 
//test
int main(){
    vector<int> test_vec = {1, 5, 2, 7, 3, 5, 9, 33, 44, 99, 55};
    printVec(test_vec);
    shellSort(test_vec);
    printVec(test_vec);    
    system("pause");
    return 0;
}

5 归并排序

6 堆排序

7 快速排序

8 计数排序

9 桶排序

10 基数排序

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-23 11:42:30  更:2021-09-23 11:42:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:36:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码