基数排序及其思想 C++代码实现及分析 恋上数据结构笔记
文章目录
- 复习梗概
- 算法思想
- 时间及空间复杂度
- 基数排序基础版代码 及输出结果
- 计数排序函数
- 基数排序函数
- 可视化输出
- 另一种思路
- 完整版代码
复习梗概
- 思想
- 如何取数字各个位位数
- 计数排序保证稳定性怎么保证
算法思想
- 基数排序思想:本质是按照个位数字,十位数字,百位数字。。。分别对数组进行排序
- 在排序高位的时候,就把前面低位的最终顺序完全确定了,直到排到最高位就完全确定顺序
而因为每位数字都是0-9的范围,又正好可以采用计数排序 - 思想不难,主要把思想转换成代码有一定难度,要注意如何取到每一位上的位数:个位:X/1%10 十位:X/10%10 百位:X/100%10
- 也要注意计数排序的写法细节,以及在位数和原元素索引之间的转换
输入数组:
9 6 7 5 8 8 29 15 11 10
计数排序基础版
计数数组【0-9】
次数 1 1 0 0 0 2 1 1 2 2
次数 1 2 0 0 0 4 5 6 8 10
按个位排序: 10 11 5 15 6 7 8 8 9 29
计数数组【0-9】
次数 6 3 1 0 0 0 0 0 0 0
次数 6 9 10 0 0 0 0 0 0 0
按十位排序: 5 6 7 8 8 9 10 11 15 29排序结果:
5 6 7 8 8 9 10 11 15 29
时间及空间复杂度
基数排序基础版代码 及输出结果
计数排序函数
void countingSort(vector<int> &array,int radix){int * countArray = new int[10]{0}; //!计数数组,注意这里的10是数组长度,不是索引啊啊啊啊,和java一样for(int i = 0;i<array.size();i++){countArray[array[i]/radix%10]++;}arrayPrint(countArray,10);cout<<endl;int locatingNum = 0; //!对计数数组的计数值进行累加,解决稳定性问题,详情见计数排序笔记for(int i = 0;i<10;i++){if(countArray[i]==0){continue;}locatingNum = locatingNum+countArray[i];countArray[i] = locatingNum;}arrayPrint(countArray,10);cout<<endl;int * tempArray = new int[array.size()];//!根据计数数组,把数组有序地输出到一个临时数组for(int i = array.size()-1;i>=0;i--){//! 记得这里一定要从后往前遍历,才能保证计数排序的稳定性!!!tempArray[countArray[array[i]/radix%10]-1] = array[i];countArray[array[i]/radix%10]--;}for(int i = 0;i<array.size();i++){//!用刚刚那个有序的临时数组,覆盖原数组array[i] = tempArray[i];}vectorPrint(array);cout<<endl;}
基数排序函数
主要就是确定最大位数,并按照位数进行计数排序
void radixSort(vector<int> &array){int maxNumIndex = 0;for(int i = 1;i<array.size();i++){ //!这里是找数组的最大值,确定计数排序的位数//!但是这里只考虑了数组内都是正整数的情况if(array[i]>array[maxNumIndex]){maxNumIndex = i;}}int max = array[maxNumIndex];for(int i = 1;i<=max;i = i*10){ //!按照个位,十位,百位。。。分别对数组进行计数排序countingSort(array,i);}
}
可视化输出
输入数组:
9 6 7 5 8 8 29 15 11 10
计数排序基础版
次数 1 1 0 0 0 2 1 1 2 2
次数 1 2 0 0 0 4 5 6 8 10
10 11 5 15 6 7 8 8 9 29次数 6 3 1 0 0 0 0 0 0 0
次数 6 9 10 0 0 0 0 0 0 0
5 6 7 8 8 9 10 11 15 29算法用时:(微秒)
[AlgoTime: 6001 us]
排序结果:
5 6 7 8 8 9 10 11 15 29
另一种思路
图片来自网课 图片来自网课恋上数据结构与算法,腾讯课堂
完整版代码
#include <iostream>
#include <vector>
#include "MeasureAlgoTime.hpp"
using namespace std;void vectorPrint(vector<int> &array)
{for (int i = 0; i < array.size(); i++){cout << array[i] << ' ';}cout << endl;
}void arrayPrint(int array[],int length){cout<<"次数"<<" ";for(int i = 0;i<length;i++){cout<<array[i]<<" ";}
}//!基数排序思想:本质是按照个位数字,十位数字,百位数字。。。分别对数组进行排序
//! 而因为每位数字都是0-9的范围,又正好可以采用计数排序
//!思想不难,主要把思想转换成代码有一定难度,要注意如何取到每一位上的位数:个位:X/1%10 十位:X/10%10 百位:X/100%10
//!也要注意计数排序的写法细节,以及在位数和原元素索引之间的转换
void countingSort(vector<int> &array,int radix){int * countArray = new int[10]{0}; //!计数数组,注意这里的10是数组长度,不是索引啊啊啊啊,和java一样for(int i = 0;i<array.size();i++){countArray[array[i]/radix%10]++;}arrayPrint(countArray,10);cout<<endl;int locatingNum = 0; //!对计数数组的计数值进行累加,解决稳定性问题,详情见计数排序笔记for(int i = 0;i<10;i++){if(countArray[i]==0){continue;}locatingNum = locatingNum+countArray[i];countArray[i] = locatingNum;}arrayPrint(countArray,10);cout<<endl;int * tempArray = new int[array.size()];//!根据计数数组,把数组有序地输出到一个临时数组for(int i = array.size()-1;i>=0;i--){//! 记得这里一定要从后往前遍历,才能保证计数排序的稳定性!!!tempArray[countArray[array[i]/radix%10]-1] = array[i];countArray[array[i]/radix%10]--;}for(int i = 0;i<array.size();i++){//!用刚刚那个有序的临时数组,覆盖原数组array[i] = tempArray[i];}vectorPrint(array);cout<<endl;}void radixSort(vector<int> &array){int maxNumIndex = 0;for(int i = 1;i<array.size();i++){ //!这里是找数组的最大值,确定计数排序的位数//!但是这里只考虑了数组内都是正整数的情况if(array[i]>array[maxNumIndex]){maxNumIndex = i;}}int max = array[maxNumIndex];for(int i = 1;i<=max;i = i*10){ //!按照个位,十位,百位。。。分别对数组进行计数排序countingSort(array,i);}
}int main()
{Tools::Time::AlgoTimeUs time1;Tools::Time::AlgoTimeUs time2;Tools::Time::AlgoTimeUs time3;vector<int> array;array = { 9, 6, 7, 5, 8, 8, 29, 15, 11, 10};vector<int> array2 = { 9, 6, 7, 5, 8, 8, 29, 15, 11, 10};vector<int> array3 = array2;cout<<"输入数组:"<<endl;vectorPrint(array);time1.start();cout << "计数排序基础版" << endl;radixSort(array);cout << "算法用时:(微秒)";time1.printElapsed();cout << "排序结果:" << endl;vectorPrint(array);cout << ' ' << endl;return 0;
}
基数排序及其思想 C++代码实现及分析 恋上数据结构笔记相关推荐
- 计数排序及其改进 C++代码实现与分析 恋上数据结构笔记
文章目录 复习梗概 算法思想 基础思想 改进空间复杂度,改进不能对负数进行排序问题 改进稳定性 计数排序时间空间复杂度 计数排序基础版 代码及输出 计数排序第一次改进版 代码及输出 计数排序终极版 代 ...
- 选择排序 C++代码实现及性能分析 恋上数据结构笔记
文章目录 复习梗概 算法思想及时间复杂度 选择排序的优化 代码及输出 完整代码 复习梗概 选择排序算法图解 选择排序在什么地方进行元素的调换 选择排序在什么地方优化,优化后的算法 时间复杂度分析 算法 ...
- 希尔排序(缩小增量排序)(插入排序的优化版) C++代码实现及算法分析 恋上数据结构笔记
文章目录 复习概要 算法思想 算法流程 算法复杂度分析及稳定性 希尔排序代码正常版 希尔排序与插入排序代码对比 希尔排序个人青春版(别看以免走上歧途) 复习概要 算法思想与流程 分这么多组分别插入排序 ...
- 2021-10-15 红黑树 概念和平衡操作理解以及与AVL对比分析 恋上数据结构笔记
文章目录 红黑树的由来 红黑树需要遵守的五大规则 红黑树与4阶B树的相互转换!! 红黑树的插入(12种情况) 红黑树的删除(3大类情况) 红黑树的平衡 以及与AVL树的性能比较 红黑树的由来 红黑树: ...
- 快速排序 C++代码实现及其算法思想及时间复杂度分析及优化 恋上数据结构笔记
文章目录 复习梗概 算法思想 算法复杂度分析及稳定性 如何优化? 快速排序改进版代码C++ 快速排序个人青春版代码 完整代码 复习梗概 算法思想,别的排序名字直接就能让人联想到它的算法思想,唯独快速排 ...
- 堆排序 C++代码实现及思想 排序过程输出 恋上数据结构笔记
复习梗概 文章目录 复习梗概 什么是堆思想? 堆排序算法怎么来的? 什么是下滤?代码 什么是建堆?代码 堆排序本体 代码及排序过程输出 和时间复杂度 完整代码 什么是堆思想? 最大堆:树形结构,每一个 ...
- 插入排序算法 及其二分搜索优化版 C++代码实现 恋上数据结构笔记
复习梗概 文章目录 复习梗概 插入排序算法思想 插入排序时间复杂度与特性(多少,与什么有关?) 插入排序基础版 插入排序2nd优化版(优化了哪里?) !!!插入排序二分搜索优化版(优化了哪里?如何优化 ...
- 二分搜索法 C++代码实现 恋上数据结构笔记
复习梗概 二分搜索法的end有两种定义方式,两种分别是什么含义? 二分搜索法end的两种定义方式分别影响了什么?(结束条件,更新指针) 二分搜索法的结束条件和更新指针两步代码? 二分搜索法的整体流程? ...
- 【恋上数据结构】排序算法前置知识及代码环境准备
排序准备工作 何为排序? 何为稳定性? 何为原地算法? 时间复杂度的知识 写排序算法前的准备 项目结构 Sort.java Asserts.java Integers.java Times.java ...
最新文章
- 【Ctsc2011】幸福路径
- Android中Parcel的分析以及使用
- 数字锁相环的matlab仿真
- 计算机组成原理第4章-指令系统
- 推荐一款非常好用的java反编译工具(转)
- 香农编码二叉树c语言,shannon码的编码实验总结.docx
- 服务器怎么打开本地电脑文件夹,如何在云服务器上打开本地文件夹
- Day1 安装虚拟机和centos7系统
- 【专题】我国银行系科技子公司比较研究
- iOS7 tabbar遮盖tableview的cell解决方法
- echarts+高德地图设置卫星图层
- 【UE4】物理引擎(蓝图)
- 14.[保护模式]TSS任务段
- 三井住友保险郑永强:一个区块链用得极溜的CIO
- 量化交易日记20210120
- 约数定理(约数个数定理,约束和定理)
- 港科夜闻丨香港科大获越秀集团捐赠港币一亿元支持大学发展
- 小飞鱼通达商务平台课程 OA开发程序基础课 3月4日 PHP第一部分课程签到及作业
- 【安装pycocotools,烦死了】
- 面试常问集锦——多线程部分