| |
|
开发:
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图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 23:21:43- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |