文章目录

  • 一、直接插入排序
  • 二、冒泡排序

一、直接插入排序

1、算法思想
直接插入排序(straight insertion sort),有时也简称为插入排序,是减治法的一种典型应用。其基本思想如下:
对于一个数组A[0,n]的排序问题,假设认为数组在A[0,n-1]排序的问题已经解决了。
考虑A[n]的值,从右向左扫描有序数组A[0,n-1],直到第一个小于等于A[n]的元素,将A[n]插在这个元素的后面。
很显然,基于增量法的思想在解决这个问题上拥有更高的效率。

2、直接插入的效率和特点
直接插入排序对于最坏情况(严格递减的数组),需要比较和移位的次数为n(n-1)/2;对于最好的情况(严格递增的数组),需要比较的次数是n-1,需要移位的次数是0。当然,对于最好和最坏的研究其实没有太大的意义,因为实际情况下,一般不会出现如此极端的情况。然而,直接插入排序对于基本有序的数组,会体现出良好的性能,这一特性,也给了它进一步优化的可能性。直接插入排序的时间复杂度是O(n^2),空间复杂度是O(1),同时也是稳定排序。

3、举例
现有一个无序数组,共7个数:89 45 54 29 90 34 68。使用直接插入排序法,对这个数组进行升序排序。
89 45 54 29 90 34 68

45 89 54 29 90 34 68

45 54 89 29 90 34 68

29 45 54 89 90 34 68

29 45 54 89 90 34 68

29 34 45 54 89 90 68

29 34 45 54 68 89 90

4、C++代码实现(核心在InsertSort函数中)

#include <iostream>
using namespace std;typedef int KeyType;  //给int的别名KeyType
typedef int InfoType;  //给int的别名InfoType
//数据元素类型定义
typedef struct
{KeyType key;  //定义数据的关键字域InfoType otherinfo;  //定义数据的其他域
} ElemType;  //数据元素类型名
//顺序表定义
typedef struct
{   ElemType R[11];  //存储空间的基地址(用R[]数据可以正常输出) int length;  //顺序表的长度
}SqList;  //表类型名//顺序表的初始化
void Init_SqList(SqList &L)
{int i, flag=-1;L.length= 11;  //表长设为10+1,因为需要留一个监视哨R[0]的位置 //设置表的前10个数据元素值(无序) for(i=1; i<L.length; i++)  //从1到10的正负摆动交叉数列 {L.R[i].key= i*flag;  //初始化为: 下标乘标志位 开始的数字flag*=-1;  //每次变一次号 }
} //对顺序表进行直接插入排序
void InsertSort(SqList &L)
{int i, j;  //遍历 for(i=2; i<=L.length; i++) //不断遍历比较 {if(L.R[i].key<L.R[i-1].key)  //若前一个比后一个大,则需要重新排序小的那个数 {L.R[0]= L.R[i];  //将待插入的记录暂存到监视哨中(中间变量R[0]) L.R[i]= L.R[i-1];  //R[i-1](大的那个数)需要向后移一位 for(j=i-2; L.R[0].key<L.R[j].key; j--)  //(小的那个数)从后往前寻找插入位置 L.R[j+1]= L.R[j];   //记录逐个后移,直到找到能够插入的位置 L.R[j+1]= L.R[0];  //将小的那个数插入到那个位置 }}
} int main()
{int i;  //遍历SqList sq;  //初始化顺序表Init_SqList(sq);cout << "原表:   ";for(i=1; i<sq.length; i++)   //第0个是监视哨,不需要输出 cout << sq.R[i].key << " "; cout << endl;InsertSort(sq);  //对顺序表进行插入排序//输出顺序表的元素 cout << "排序后:";for(i=1; i<sq.length; i++)  //第0个是监视哨,不需要输出 cout << sq.R[i].key << " ";
}

二、冒泡排序

1、算法思想: 依次比较相邻的两个数,将比较小的数放在前面,比较大的数放在后面。
1)第一次比较,首先比较第一和第二个数,将小数放在前面,将大数放在后面。

2)比较第2和第3个数,将小数 放在前面,大数放在后面。

3))如此继续,知道比较到最后的两个数,将小数放在前面,大数放在后面,重复步骤,直至全部排序完成。

4)在上面一趟比较完成后,最后一个数一定是数组中最大的一个数,所以在比较第二趟的时候,最后一个数是不参加比较的。

5)在第二趟比较完成后,倒数第二个数也一定是数组中倒数第二大数,所以在第三趟的比较中,最后两个数是不参与比较的。

6)依次类推,每一趟比较次数减少依次。

2、C++代码实现(核心在BubbleSort函数中)

#include <iostream>
using namespace std;typedef int KeyType;  //给int的别名KeyType
typedef int InfoType;  //给int的别名InfoType
//数据元素类型定义
typedef struct
{KeyType key;  //定义数据的关键字域InfoType otherinfo;  //定义数据的其他域
} ElemType;  //数据元素类型名
//顺序表定义
typedef struct
{   ElemType R[11];  //存储空间的基地址(用R[]数据可以正常输出) int length;  //顺序表的长度
}SqList;  //表类型名//顺序表的初始化
void Init_SqList(SqList &L)
{int i, flag=-1;L.length= 11;  //表长设为10+1,因为需要留一个监视哨R[0]的位置 //设置表的前10个数据元素值(无序) for(i=1; i<L.length; i++)  //从1到10的正负摆动交叉数列 {L.R[i].key= i*flag;  //初始化为: 下标乘标志位 开始的数字flag*=-1;  //每次变一次号 }
} void BubbleSort(SqList &L)
{int m= L.length-1;  //从后往前进行排序 int flag=1;  //用flag来标记某一趟排序是否发生交换int j;  //遍历ElemType t;  //中间变量 while((m>0) && (flag==1))  //总共进行m趟排序{flag= 0;  //flag置零表示初始每一趟都表示没有交换,则不会执行下趟排序 for(j=1; j<=m; j++)if(L.R[j].key>L.R[j+1].key)  //若前面的大于后面的{flag= 1;  //已经发生排序//交换两个记录的前后顺序 t=L.R[j];L.R[j]=L.R[j+1];L.R[j+1]= t;} --m;  //向前继续排序 }
}

3、测试部分

int main()
{int i;  //遍历SqList sq;  //初始化顺序表Init_SqList(sq);cout << "原表:   ";for(i=1; i<sq.length; i++)   //第0个是监视哨,不需要输出 cout << sq.R[i].key << " "; cout << endl;BubbleSort(sq);  //对顺序表进行冒泡排序 //输出顺序表的元素    cout << "排序后:";for(i=1; i<sq.length; i++)  //第0个是监视哨,不需要输出 cout << sq.R[i].key << " ";
}

直接插入排序、冒泡排序实验详解【数据结构实验报告】相关推荐

  1. 实验详解——Cobbler自动部署最小化安装

    实验详解--Cobbler自动部署最小化安装 一.实验:自动部署 二.Cobbler自动装机服务搭建步骤 1.导入epel源并加载在线安装源 2.安装Cobbler以及其相关服务软件包 3.修改cob ...

  2. 实验详解——DNS网关服务器的分离解析

    实验详解--DNS网关服务器的分离解析 一.实验图 二.要求 三.实验开始 1.网关服务器的配置 ①.新添加一块网卡,用双网卡来演示网关服务器的两个端口 ②.对两个网卡进行配置的修改 ③.重启网卡并查 ...

  3. 实验详解——DNS反向解析、DNS主服务器和从服务器的配置

    实验详解--DNS反向解析.DNS主服务器和从服务器的配置 实验一:DNS反向解析 1.安装bind 2.查找配置文件路径 3.配置/etc/named.conf主配置文件 4.修改/etc/name ...

  4. 详解FTP服务完成Linux和WIN10之间的信息传输(实验详解)

    详解FTP服务完成Linux和WIN10之间的信息传输(实验详解) 一.FTP简介 1. FTP服务--用来传输文件的协议 2.端口 3.数据连接模式 二.相关配置 1.安装FTP服务 2.设置匿名用 ...

  5. 详解 Linux环境中DHCP分配IP地址(实验详解)

    Linux中DHCP小实验详解 一.DHCP中继概述 二.DHCP在linux系统中的相关配置 1.配置DHCP服务器 2.设置全局配置参数 3.subnet网段声明 4.host主机声明 三.实验例 ...

  6. 实验详解——parted单磁盘分区并进行配额

    实验详解--parted单磁盘分区并进行配额 一.实验要求 二.实验开始 1.添加新硬盘 2.对新硬盘进行parted分区,格式设置为ext4 3.格式化分区,格式为ext4 4.设置配额方式和挂载 ...

  7. 数字信号处理实验matlab版答案,数字信号处理习题答案及matlab实验详解.pdf

    数字信号处理习题答案及matlab实验详解.pdf 第一章 参考答案: 1 (1)2 2 14 ,有理数,所以周期为 14 0 3  3 7 2 2 (2 ) 12 ,无理数,非周期  ...

  8. 第20节 核心交换机配置热备份详解及实验演示—基于Cisco Packet Tracer

    核心交换机配置热备份详解及实验演示 1 网络规划 1.1 核心交换机的重要性及作用 1.2 对核心交换机做热备份 2 拓扑图分析 2.1 网络环路问题及解决方案 2.1.1 网络环路问题 2.1.2 ...

  9. STM32F429第二十五篇之MCU屏实验详解

    文章目录 前言 硬件 软件 结构体 SRAM_HandleTypeDef Instance(FMC寄存器地址) Extended(拓展寄存器地址) Init(初始化变量) Lock(锁) State( ...

  10. CS144课程实验详解-lab0-第一部分

    CS144课程实验详解-lab0-第一部分 配置环境 下载并安装VirtualBox 下载实验虚拟机cs144_vm.ova并导入VirtualBox 额外提示-图形用户界面 额外提示-共享文件夹 手 ...

最新文章

  1. gcc可以编译python程序吗_gcc c语言编译流程
  2. Makefile for OpenCV
  3. caioj 1063 动态规划入门(一维一边推1:美元和马克)
  4. 点击关闭按钮时缩小到系统任务栏
  5. 一个 bug / Masonry的引入
  6. Teams App设备的地理位置能力
  7. 深度:关于Linux内核最硬核的文章
  8. Unity中录制VR全景视频(可录制UGUI)
  9. HM-A300小程序安卓打印异常
  10. 视频剪辑教程,教你批量给全部视频添加上下图片水印
  11. 瀑布流无限加载的原理
  12. 基于VS2010MFC平台使用C++编写的上位机源程序(可在虚拟机下实现两个com端口的数据传输)
  13. MPEG2 TS与ISMA的比较
  14. 从知识直播和创新活动中,看搜狐的内容“新”路
  15. 【NvRAM】apk中中读写nvram
  16. Qt 封装一个简单的LED(指示灯)控件
  17. Github上有什么好的unity开源项目?
  18. android申请蓝牙的权限,Android Studio 真机调试捕获异常申请和蓝牙权限代码
  19. 脑机接口科普0019——大脑的分区及功能
  20. 开挂进大厂:BATJ面试官能问到的Java面试题,都被打包在这份PDF文档里

热门文章

  1. c语言 北京时间转换utc时间_PHP时间戳和日期相互转换操作
  2. c语言设计阶段作业答案,C语言程序设计阶段考试练习题(答案)
  3. null索引表键值_MySQL 的B+树索引
  4. python中copytree的用法_python复制文件的方法实例详解
  5. java freemarker_Java: FreeMarker的配置和使用
  6. k6前级效果器怎么用_P18:调制类效果器的那些事儿(Modulation)
  7. 全自动安装MySQL_自动部署安装mysql-5.6.22
  8. AIX、hpux、linux 通过nfs文件系统运行oracle 数据库
  9. oracle中正则表达式相关函数regexp_like简介
  10. php js绝对路径,javascript将相对路径转绝对路径示例_基础知识