选择类排序 (简单选择排序,堆排序)— c语言实现
选择类排序包括:
(1) 简单选择排序
(2)树形选择排序
(3)堆排序
简单选择排序:
【算法思想】:在第 i 趟简单选择排序中,从第 i 个记录开始,通过 n - i 次关键字比较,从 n - i + 1 个记录中选出关键字最小的记录,并和第 i 个记录进行交换
时间复杂度:O(n^2)
//此函数中a[0]不用,即对 a[1] ~ a[length-1] 排序;
//如果对a[0]~a[length-1]排序,将 for 循环中的 i = 1 改为 i = 0 即可,注意输出
void select(int a[],int length){//length为数组的长度
int i,j;
int min;//记录最小值的位置 for(i = ;i < length - ;i++){
min = i;
//选择最小的值
for(j = i + ;j < length;j++){
if(a[j] < a[min]) //更新最小值的坐标
min = j;
}
if(min != i){
int temp;
temp = a[min];
a[min] = a[i];
a[i] = temp;
}
}
}
堆排序:
堆排序是威洛母斯在1964年提出的对树形选择排序的改进算法,其只需要一个记录大小的辅助空间,采用向量数组方式存储,采用完全二叉树的顺序结构的特征进行分析,而非采用树的存储结构。
从小到大排序采用大根(顶)堆:r[i].key >= r[2i].key && r[i].key >= r[2i+1].key (结点值大于等于其左子与右子)
从大到小排序采用小根(顶)堆:r[i].key <= r[2i].key && r[i].key<= r[2i+1].key (结点值小于等于其左子与右子)

【算法思想】把待排序的记录的关键字存放在数组 r[1...n] 中,将 r 看成一棵完全二叉树的顺序表示,每个结点表示一个记录,第一个记录 r[1] 作为二叉树的根,以下各记录 r[2] ~ r[n] 依次逐层从左到右顺序排列,任意结点 r[i] 的左孩子是 r[2i] ,右孩子是 r[2i+1],双亲是 r[i/2]。对这棵二叉树进行调整建堆。
时间复杂度:O(nlog2n)
说明:在c语言中,i/2 的含义是整除,不同于数学中的定义,即 3/2 = 1,有一个向下取整的意思
堆排序可分为2步(从小到大排序):
<1> 建初堆:建立一个大根堆
<2>重建堆:进行 n - 1 趟的交换(r[1] 与 堆尾进行交换)和建堆的过程
/*堆排序*/
/*建初堆:大根堆*/
void AdjustDown(int a[],int k,int len);
void BuildMaxHeap(int a[],int len){
int i;
for(i = len/;i > ;i--){
AdjustDown(a,i,len);
}
}
//调整堆
void AdjustDown(int a[],int k,int len){
a[] = a[k];//将第一个记录移出
int i;
for(i = *k;i <= len;i = *i){
if(i < len && a[i] < a[i+])//不能忘记i < len,否则会超出范围
i++;//取左右子中的最大值
if(a[] >= a[i])
break;
else{
a[k] = a[i]; //将a[i]调整到其双亲结点上
k = i; //修改k值,以便继续向下筛选
}
}
a[k] = a[];
} void HeapSort(int a[],int len){
BuildMaxHeap(a,len);
int i;
int temp;
for(i = len;i > ;i--){
//第一个和堆尾进行交换
temp = a[];
a[] = a[i];
a[i] = temp;
//调整堆
AdjustDown(a,,i-);
}
}
图可参照:https://blog.csdn.net/u013384984/article/details/79496052
测试:
int main(){
int a[] = {-,,,,,,,,,,};
int b[] = {-,,,,,,,,,,};
int i,j;
select(a,); //没有用a[0],对后面的元素进行排序
HeapSort(b,);//数组的最后一个下标,a[0]为辅助单元
for ( i = ;i < ;i++){
printf("%d \t",a[i]);
}
printf("\n");
for ( i = ;i < ;i++){
printf("%d \t",b[i]);
}
printf("\n");
}
选择类排序 (简单选择排序,堆排序)— c语言实现的更多相关文章
- 选择排序—简单选择排序(Simple Selection Sort)
基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素 ...
- 选择排序—简单选择排序(Simple Selection Sort)原理以及Java实现
基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素 ...
- 9, java数据结构和算法: 直接插入排序, 希尔排序, 简单选择排序, 堆排序, 冒泡排序,快速排序, 归并排序, 基数排序的分析和代码实现
内部排序: 就是使用内存空间来排序 外部排序: 就是数据量很大,需要借助外部存储(文件)来排序. 直接上代码: package com.lvcai; public class Sort { publi ...
- 八大排序算法之三选择排序—简单选择排序(Simple Selection Sort)
基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素 ...
- 内部排序->选择排序->简单选择排序
文字描述 简单排序的基本思想是:每一趟在n-i+1(i=1,2,…,n)个记录中选取关键字最小的记录作为有序列表中的第i个记录. 示意图 略 算法分析 简单排序算法中,所需进行记录移动的操作次数较少, ...
- Python实现八大排序(基数排序、归并排序、堆排序、简单选择排序、直接插入排序、希尔排序、快速排序、冒泡排序)
目录 八大排序 基数排序 归并排序 堆排序 简单选择排序 直接插入排序 希尔排序 快速排序 冒泡排序 时间测试 八大排序 大概了解了一下八大排序,发现排序方法的难易程度相差很多,相应的,他们计算同一列 ...
- 常见排序算法总结:插入排序,希尔排序,冒泡排序,快速排序,简单选择排序以及java实现
今天来总结一下常用的内部排序算法.内部排序算法们需要掌握的知识点大概有:算法的原理,算法的编码实现,算法的时空复杂度的计算和记忆,何时出现最差时间复杂度,以及是否稳定,何时不稳定. 首先来总结下常用内 ...
- 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现)
程序员必知的8大排序(一)-------直接插入排序,希尔排序(java实现) 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现) 程序员必知的8大排序(三)-------冒 ...
- 简单选择排序 Selection Sort 和树形选择排序 Tree Selection Sort
选择排序 Selection Sort 选择排序的基本思想是:每一趟在剩余未排序的若干记录中选取关键字最小的(也可以是最大的,本文中均考虑排升序)记录作为有序序列中下一个记录. 如第i趟选择排序就是在 ...
随机推荐
- linux命令之------touch命令
touch命令 1) 作用:用于修改文件或目录的时间属性,包括存取时间和更改时间.若文件不存在,系统会建立一个新的文件. 2) -a:改变档案的读取时间记录: 3) -m:改变档案的 ...
- MySQL性能优化 分区
简述 分区是指根据一定的规则,数据库将表分解为多个更小的,更容易管理的部分,就访问数据库而言,逻辑上只有一张表或一个索引,但实际上这张表可能又多个物理分区共同构成,每一个分区都是一个独立的对象,可以独 ...
- Nginx服务器作反向代理实现内部局域网的url转发配置
情景 由于公司内网有多台服务器的http服务要映射到公司外网静态IP,如果用路由的端口映射来做,就只能一台内网服务器的80端口映射到外网80端口,其他服务器的80端口只能映射到外网的非80端口.非80 ...
- Mybatis27题
1.什么是Mybatis? Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动.创建连接.创建statement等繁杂 ...
- [Beta阶段]第十次Scrum Meeting
Scrum Meeting博客目录 [Beta阶段]第十次Scrum Meeting 基本信息 名称 时间 地点 时长 第十次Scrum Meeting 19/05/16 大运村寝室6楼 30min ...
- Spark2.x(六十三):(Spark2.4)Driver如何把Task(闭包等)分配给Executor
在Spark中一个appliation可能包含多个job,每个job都是由SparkContext#runJob(...)触发的,一个Job下包含1个或多个Stage,Job的最后一个stage为Re ...
- sudoku 心得 视觉消除法(Visual Elimination)
虽然我是程序员,但这里只介绍人类的思维方法. 这个方法我是从这里看到的: https://www.learn-sudoku.com/visual-elimination.html Most peopl ...
- android为什么不允许新开启一个线程来更新UI,而是用handler来更新界面
下面是快速创建一个新线程的方法: 第一种:直接创建子线程并启动 new Thread() {@Overridepublic void run() { //这里写入子线程需要做的工作 ...
- QT5.12 qtcreate 在Ubuntu14.04
Ubuntu14.04 下出现了 symbol dbus_message_get_allow_interactive_authorization, version LIBDBUS_1_3 not de ...
- Html表格和表头文字不换行
[本文出自天外归云的博客园] 希望表头中的文字和表格中的文字不换行,只需要在th和td标签加上: nowrap="nowrap"