| |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| -> 数据结构与算法 -> 【排序综合】直接插入排序,希尔排序,快速排序,堆排序,冒泡排序,简单选择排序的简介,实现和算法复杂度分析 -> 正文阅读 |
|
|
[数据结构与算法]【排序综合】直接插入排序,希尔排序,快速排序,堆排序,冒泡排序,简单选择排序的简介,实现和算法复杂度分析 |
|
目录 1. 直接插入排序1.1 直接插入排序简介1. 什么是直接插入排序直接插入排序是一种最简单的排序方法,其基本操作是将需要排序的元素插入到已排好的有序表序列中,从而得到一个完整的有序序列 2. 排序思想
1.2 排序实现1. 排序代码void insertsort(struct element a[],int n){
int i,j;
struct element x;
for(i=1;i<n;i++){
if(a[i].key<a[i-1].key) //反序时
{
x=a[i];
j=i-1;
do //找a[i].key的插入位置
{
a[j+1]=a[j]; //将关键字大于a[i].key的记录后移
count1++;
j--;
move1++;
}while(j>=0&&a[j].key>x.key);
a[j+1]=x; //在j+1处插入a[i]
move1=move1+2;
}
count1++;
}
}
2. 复杂度分析:时间复杂度:最坏情况下为O(N*N),此时待排序列为逆序,或者说接近逆序 3. 运行结果:
1.3 学习链接2. 希尔排序(分组排序)2.1 希尔排序简介1. 什么是希尔排序希尔排序是把序列按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量的逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个序列恰好被分为一组,算法便终止。 2.排序思想
2.2 排序实现1. 希尔排序代码void shellsort(struct element a[],int n){
int i,j,k;
struct element tmp;
k=n/2; //增量置初值
while(k>0)
{
for(i=k;i<n;i++) //对所有组采用直接插入排序
{
tmp=a[i]; //对相隔k个位置一组采用直接插入排序
j=i-k;
while(j>=0&&tmp.key<a[j].key)
{
a[j+k]=a[j];
j=j-k;
move2=move2+3;
}
a[j+k]=tmp;
count2++;
}
k=k/2; //减小增量
}
}
2. 复杂度分析
时间复杂度平均:O(N^1.3) 3. 运行结果
2.3 学习链接[算法]六分钟彻底弄懂希尔排序,简单易懂_哔哩哔哩_bilibili 3. 快速排序3.1 快速排序简介1. 什么是快速排序通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 2.排序思想
3.2 排序实现1. 快速排序代码int hoare(struct element a[size],int low,int high){ //分区处理函数
int i,j;
struct element x;
i=low;
j=high;
x.key=a[i].key; //以a[i]为基准
while(i<j) //从两端交替向中间扫描,直至i=j为止
{
while(j>i&&a[j].key>=x.key){
j--; //从右向左扫描,找一个小于x.key的a[j]
count3++;
}
a[i]=a[j]; //找到这样的a[j],放入a[i]处
move3++;
while(i<j&&a[i].key<=x.key){
i++; //从左向右扫描,找一个大于x.key的a[i]
count3++;
}
a[j]=a[i]; //找到这样的a[i],放入a[j]处
move3++;
}
a[i]=x;
return i;
}
void quicksort(struct element a[size],int low,int high){ //对a[low....high]的元素进行快速排序
int i;
if(low<high){ //区间内至少存在两个元素的情况
i=hoare(a,low,high); //划为两个区
quicksort(a,low,i-1); //对左分区快速排序
quicksort(a,i+1,high); //对右分区快速排序
}
}
2. 复杂度分析时间复杂度: 快速排序最优的情况下时间复杂度为:O( nlogn ) 快速排序最差的情况下时间复杂度为:O( n^2 ) 快速排序的平均时间复杂度也是:O(nlogn) 空间复杂度: 最优的情况下空间复杂度为:O(logn) ;每一次都平分数组的情况 最差的情况下空间复杂度为:O( n ) ;退化为冒泡排序的情况 3. 运行结果
3.3 学习链接4. 堆排序4.1 堆排序简介1. 什么是堆排序堆排序就是基于这种结构而产生的一种程序算法。堆是一种叫做完全二叉树的数据结构,可以分为大根堆,小根堆,即子结点的键值或索引总是小于(或大于)它的父节点。 2.排序思想
注意:升序用大根堆,降序就用小根堆(默认为升序),前提是排序满足完全二叉树 4.2 排序实现1. 堆排序代码void heap(struct element a[size],int i,int m){ //调整堆的函数
//i是根结点编号,m是以i为根的子树的最后一个结点编号
struct element x;
int j;
x.key=a[i].key; //保存记录内容
j=i*2; //j为左孩子编号
while(j<=m){
count4=count4+2;
if(j<m)
if(a[j].key>a[j+1].key){ //当结点i有左、右两个孩子时,j取关键较小的孩子编号
j++;
}
if(a[j].key<x.key){ //向下一层探测 ,若根节点大于最小孩子的关键字
a[i].key=a[j].key; //将a[j]调整到双亲节点位置上
i=j;
j=2*i;
move4=move4+3;
}
else
j=m+1; //x.key小于左、右孩子的关键字时,使j>m,以便结束循环 (若根节点小于最小孩子关键字)
}
a[i].key=x.key; //被筛选结点放入最终位置上
}
void heapsort(struct element a[size],int n){ //堆函数的主体函数
int i,v;
struct element x;
for(i=n;i>0;i--)
a[i].key=a[i-1].key;
for(i=n/2;i>=1;i--)
heap(a,i,n);
for(v=n;v>=2;v--){
x.key=a[1].key; //堆顶堆尾元素交换
a[1].key=a[v].key;
a[v].key=x.key;
move4=move4+3;
heap(a,1,v-1); //这次比上次少处理一个记录
}
for(i=0;i<n;i++)
a[i].key=a[i+1].key;
for(i=0;i<n/2;i++){
int k;
k=a[i].key;
a[i].key=a[n-i-1].key;
a[n-i-1].key=k;
}
}
2. 复杂度分析时间复杂度:最好,最坏,和平均时间复杂度都为:O(nlogn) 空间复杂度:O(1) 3. 运行结果
4.3 学习链接5. 冒泡排序5.1 冒泡排序简介1. 什么是冒泡排序冒泡排序(BubbleSort)以其”在排序过程中相邻元素不断交换,一些元素慢慢被换到最后,看起来就像是元素在冒泡一样“而得名,是一种简单的基于关键词比较的排序算法。 2. 排序思想
冒泡排序分从大到小和从小到大两种排序方式。它们的唯一区别就是两个数交换的条件不同,从大到小排序是前面的数比后面的小的时候交换,而从小到大排序是前面的数比后面的数大的时候交换。 5.2 排序实现1. 冒泡排序代码void bubblesort(struct element a[],int n)
{
int i,j;
struct element tmp;
bool exchange;
for(i=0;i<n-1;i++)
{
exchange=false; //一趟前exchange为假
for(j=n-1;j>i;j--){ //归位a[i],循环n-i-1次
if(a[j].key<a[j-1].key) //相邻两个元素反序时
{
tmp.key=a[j].key; //将a[j]和a[j-1]两个元素交换
a[j].key=a[j-1].key;
a[j-1].key=tmp.key;
exchange =true; //一旦有交换,exchange置为真
move5=move5+3;
}
count5++;
}
if(!exchange) //本趟没有发生交换,中途结束算法
return;
}
}
2. 复杂度分析时间复杂度: 最好情况的时间复杂度为O(n) 最坏情况子下的时间复杂度为O(n^2) 平均的时间复杂度为:O( n^2 ) 空间复杂度: 最优的空间复杂度就是开始元素顺序已经排好了,则空间复杂度为:0; 最差的空间复杂度就是开始元素逆序排序了,则空间复杂度为:O(n); 平均的空间复杂度为:O(1); 稳定性: 因为每次比较后如果两个相邻元素相等我们并不会将他们交换,所以冒泡不会改变相同元素的下标,所以冒泡排序是一个稳定的排序 3. 运行结果
5.3 学习链接6. 简单选择排序6.1 简单选择排序简介1. 什么是简单选择排序简单选择排序采用最简单的选择方式,从头至尾顺序扫描序列,找出最小的一个关键字,和第一个关键字交换,接着从剩下的关键字中继续这种选择和交换,最终达到排序的目的 2.排序思想
6.2 排序实现1. 简单选择排序代码void selectsort(struct element a[],int n)
{
int i,j,k;
struct element tmp;
for(i=0;i<n-1;i++) //做第i趟排序
{
k=i;
for(j=i+1;j<n;j++){ //在当前无序区a[i...n-1]中选出key最小的a[k]
count6++;
if(a[j].key<a[k].key)
k=j; //k记下目前找到的最小关键字所在的位置
}
if(k!=i){
tmp.key=a[i].key; //a[i],a[k]两个元素交换
a[i].key=a[k].key;
a[k].key=tmp.key;
move6=move6+3;
}
}
}
2. 复杂度分析时间复杂度:最好、最差、平均时间复杂度都是O(n^2) 空间复杂度:O(1); 是不稳定的算法 3. 运行结果
6.3 学习链接7. 排序算法比较
|
|
|
|
|
| 上一篇文章 下一篇文章 查看所有文章 |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| 360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年11日历 | -2025/11/22 21:17:48- |
|
| 网站联系: qq:121756557 email:121756557@qq.com IT数码 |