直接插入排序到底有多“直男”

这篇具有很好参考价值的文章主要介绍了直接插入排序到底有多“直男”。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

作者主页:paper jie的博客_CSDN博客-C语言,算法详解领域博主

本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。

本文录入于《算法详解》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造,将算法基础知识一网打尽,希望可以帮到读者们哦。

其他专栏:《系统解析C语言》《C语言》《C语言-语法篇》

内容分享:本期将对八大排序中的直接插入排序进行详细的讲解,各位看官姥爷快搬好小板凳坐好叭。

    -------- 不要998,不要98,只要一键三连,三连买不了吃亏,买不了上当

目录

前言

什么是直接插入排序

直接插入排序的实现

基本思想

具体代码

直接插入排序的原理

直接插入排序的特点和性能

复杂度 

稳定性

二分查找代码的应用


前言

上期我们对快速排序进行了分析,了解了它的思想,原理和实现代码及它的特性。今天我们来了解一下插入排序中的直接插入排序。

什么是直接插入排序

插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法 。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动

直接插入排序的实现

基本思想

1.   每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。

2.   第一趟比较前两个数,然后把第二个数按大小插入到有序表中

3.   第二趟把第三个数据与前两个数从后向前扫描,把第三个数按大小插入到有序表中;

4.   依次进行下去,进行了(n-1)趟以后就完成了整个排序过程。

具体代码

#include <stdio.h>
//直接插入排序
void InsertSort(int* arr, int len)
{
	//定义变量用来循环
	int i = 0;
	int j = 0;
	//哨兵变量 即用来存放需要查入的元素
	int tmp = 0;
	//第一层循环 循环len-1次
	//因为当数组只有一个元素时它就是有序的不用比较
	//所以从第二个元素开始比较 即i=1
	for (i = 1; i < len; i++)
	{
		//将需要插入的元素放入tmp中
		tmp = arr[i];
		//第二层循环 和要插入的元素比较
		//要比较的就是插入元素前面的 即j=i-1
		for (j = i - 1; j >= 0; j--)
		{
			//如果插入元素前一个大于插入元素就将它们交换
			if (arr[j] > arr[j + 1])
			{
				arr[j + 1] = arr[j];
				arr[j] = tmp;
			}
			//如果不大于插入元素的时候就跳出
			//因为要插入元素前面的子数组的元素已经是有序的
			//只要大于子数组后面的元素,前面的就不用比较了
			else
				break;
		}
	}
}
int main()
{
	//待排序数组
	int arr[] = { 3,8,7,2,6,9,1,4 };
	//直接插入排序函数
	InsertSort(arr, sizeof(arr) / sizeof(arr[0]));
	//打印
	int i = 0;
	for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d ", arr[i]);
	}

	return 0;
}

直接插入排序的原理

直接插入排序是由两层嵌套循环组成的。外层循环标识并决定待比较的趟术和数值。内层循环为待比较数值确定其最终位置。直接插入排序将待比较的数值与它的前一个数值进行比较,所以外层循环是从第二个数值开始的。当前一数值比待比较数值大的情况下继续循环比较,直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环。

这里我们以代码中的数组为例:我们将数组{ 3,8,7,2,6,9,1,4}进行升序。我们将3元素从无序表中拿出来放到有序表中,有序表中无元素,它仍然有序。注意(比较中是从后往前,比较的数组是有序的,如果待插入的元素大于比较元素,则比较元素前面的就不用比较了。)这时开始正式比较,第一次比较8大于3,不用交换直接插入,有序表3,8。第二次比较7小于8交换,7大于3不交换,直接插入,有序表3,7,8。第三次比较2小于8交换,2小于7交换,2小于3交换,前面没有元素了,插入。有序表2,3,7,8。第四次交换比较6小于8交换,6小于7交换,6大于3不交换,插入。有序表2,3,6,7,8。第五次交换比较9大于6不交换,直接插入。有序表2,3,6,7,8,9。第六次交换比较1小于9交换,1小于7交换,1小于6交换,1小于3交换,1小于2交换。有序表1,2,3,6,7,8,9。第7次交换比较4小于9交换,4小于8交换,4小于7交换,4小于6交换,4大于3不交换,直接插入,有序表1,2,3,4,6,7,8,9。这时数组就已经变成有序的了。

画图分析:

直接插入排序到底有多“直男”,算法详解,# 八大排序,排序算法,算法

直接插入排序的特点和性能

复杂度 

直接插入排序的时间复杂度为 O (n^2) ,空间复杂度为 O (1) 。 在排序过程中,如果待排序的序列已经近似有序,则直接插入排序的效率会很高,因为少需移动已排序部分的元素。 但如果待排序序列的规模很大或者是随机分布的,那么直接插入排序的效果会不如其他高效率排序算法,如快速排序等。

稳定性

插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。如果碰见一个和插入元素相等的,那么将会把待插入元素放在相等元素的后面。所以,相等元素的相对的前后顺序没有改变,所以插入排序是稳定的。

二分查找代码的应用

下面还有一个插入排序中的二分查找,大家可以看看文章来源地址https://www.toymoban.com/news/detail-574698.html


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define MaxSize 100
#define ElemType int
#define Status int
using namespace std;
//顺序表数据结构
typedef struct
{
	ElemType data[MaxSize];//顺序表元素
	int length;            //顺序表当前长度
}SqList;
//***************************基本操作函数*******************************//
//初始化顺序表函数,构造一个空的顺序表 
Status InitList(SqList &L)
{
	memset(L.data,0,sizeof(L));//初始化数据为0
	L.length=0;                //初始化长度为0
	return 0;
}
//创建顺序表函数 初始化前n个数据
bool CreatList(SqList &L,int n)
{
	if(n<0||n>MaxSize)false;//n非法
	for(int i=0;i<n;i++)
	{
		scanf("%d",&L.data[i]);
		L.length++;
	}
	return true;
}
//插入函数 位置i插入数据 i及之后元素后移  1=<i<=length+1 
bool InsertList(SqList &L,int i,ElemType e)
{
	if(i<1||i>L.length+1) //判断位置是否有效
     {
		printf("位置无效!!!\n");
    	return false;
	 }
	if(L.length>=MaxSize)//判断存储空间是否已满
	{
		printf("当前存储空间已满!!!\n");
		return false;
	}
	for(int j=L.length;j>=i;j--)//位置i及之后元素后移
	{
		L.data[j]=L.data[j-1];
	}
	L.data[i-1]=e;
	L.length++;
	return true;
}
//删除函数 删除位置i的元素 i之后的元素依次前移
bool  ListDelete(SqList &L,int i)
{
	if(i<1||i>L.length)
     {
		printf("位置无效!!!\n");
    	return false;
	 }
	for(int j=i;j<=L.length-1;j++)//位置i之后元素依次前移覆盖
	{
		L.data[j-1]=L.data[j];
	}
	L.length--;
	return true;
}
//查找函数 按位置从小到大查找第一个值等于e的元素 并返回位置
int LocateElem(SqList L,ElemType e)
{
 for(int i=0;i<L.length;i++)//从低位置查找
	{
		if(L.data[i]==e)
			return i+1;
	}
 return 0;
 
}
//二分查找函数
int Binary_search(SqList L,ElemType key)
{
	int low = 0;int mid = 0;int high = L.length-1;
	while(low<=high)
	{
		mid = (low+high)/2;
 		if(key==L.data[mid])
		{
			return mid;
		}
		else if(key>L.data[mid])
		{
			low = mid+1;
		}
		else
		{
			high = mid-1;
		}
	}
	return -1;
}
//********************************功能函数*****************************************//
//输出功能函数 按位置从小到大输出顺序表所有元素
void PrintList(SqList L)
{
	printf("当前顺序表所有元素:");
	for(int i=0;i<L.length;i++)
	{
		printf("%d ",L.data[i]);
	}
	printf("\n");
}
//创建顺序表函数
void Create(SqList &L)
{
	int n;bool flag;
	printf("请输入要创建的顺序表长度(>1):");
	scanf("%d",&n);
	printf("请输入%d个数(空格隔开):",n);
	flag=CreatList(L,n);
	if(flag){
		printf("创建成功!\n");
		PrintList(L);
	}
	else printf("输入长度非法!\n");
 
}
//插入功能函数 调用InsertList完成顺序表元素插入 调用PrintList函数显示插入成功后的结果
void Insert(SqList &L)
{
  int place;ElemType e;bool flag;
  printf("请输入要插入的位置(从1开始)及元素:\n");
  scanf("%d%d",&place,&e);
  flag=InsertList(L,place,e);
  if(flag) 
  {
	printf("插入成功!!!\n");
	PrintList(L);
  }
}
//删除功能函数 调用ListDelete函数完成顺序表的删除 调用PrintList函数显示插入成功后的结果
void Delete(SqList &L)
{
  int place;bool flag;
  printf("请输入要删除的位置(从1开始):\n");
  scanf("%d",&place);
  flag=ListDelete(L,place);
  if(flag) 
  {
	printf("删除成功!!!\n");
	PrintList(L);
  }
}
//查找功能函数 调用LocateElem查找元素
void Search(SqList L)
{
  ElemType e;int flag;
  printf("请输入要查找的值:\n");
  scanf("%d",&e);
  flag=LocateElem(L,e);
  if(flag) 
  {
	printf("该元素位置(从1起)为:%d\n",flag);
  }
  else
	  printf("未找到该元素!\n");
}
//简单选择排序功能函数 为二分做准备
void SelectSort(SqList &L)
{
	int min;int temp;
	for(int i=0;i<L.length;i++)
	{
		min=i;
		for(int j=i+1;j<L.length;j++)
		{
			if(L.data[j]<L.data[min])min=j;
		}			
		if(min!=i)
		{
			temp=L.data[min];
			L.data[min]=L.data[i];
			L.data[i]=temp;
		}
	}
}
//二分查找功能函数 调用Binary_search
void Binary(SqList L)
{
	int key;int place;
	SelectSort(L);       //二分查找前先排序
	PrintList(L);
	printf("请输入要查找的值:\n");
	scanf("%d",&key);
	place=Binary_search(L,key);
	if(place>=0)printf("位置(从0起)为:%d\n",place);
	else printf("未找到!\n");
}
//菜单
void menu()
{
   printf("********1.创建    2.插入*********\n");
   printf("********3.删除    4.查找*********\n");
   printf("********5.输出    6.二分查找*********\n");
   printf("********7.退出\n");
}
int main()
{
 SqList L;int choice;
 InitList(L);
 while(1)
 {
  menu();
  printf("请输入菜单序号:\n");
  scanf("%d",&choice);
  if(7==choice) break;
  switch(choice)
  {
  case 1:Create(L);break;
  case 2:Insert(L);break;
  case 3:Delete(L);break;
  case 4:Search(L);break;
  case 5:PrintList(L);break;
  case 6:Binary(L);break;
  default:printf("输入错误!!!\n");
  }
 }
 return 0;
}

到了这里,关于直接插入排序到底有多“直男”的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 八大排序:直接插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、归并排序、计数排序

    排序 :所谓排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 稳定性 :假定在待排序的记录序列中,存在多个具有相同的的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而

    2024年02月09日
    浏览(38)
  • 【数据结构】详解七大排序算法(直接插入排序、希尔排序、直接选择排序、堆排序、冒泡排序、快速排序)

    1、基本思想    把待排序的数按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所以的记录插入完为止,得到一个新的有序序列。    实际中我们玩扑克牌时,就用到了插入排序的思想 基本步骤:    当插入第i个元素时,前面的arr[0]、arr[2]…arr

    2024年02月04日
    浏览(45)
  • C语言实现八大排序算法(详解插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序(递归和非递归)、归并排序(递归和非递归)和计数排序)

    本篇文章使用C语言实现了数据结构中常见的八大排序算法,它们分别是 插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、归并排序和计数排序 。在排序算法的实现过程中,每种算法都有其独特的特点和适用场景。插入排序通过逐步构建有序序列来排序,希尔

    2024年01月24日
    浏览(38)
  • 八大排序算法之插入排序+希尔排序

    目录 一.前言(总体简介) 关于插入排序  关于希尔排序: 二.插入排序 函数首部: 算法思路: 算法分析 插入排序代码实现: 插入排序算法的优化前奏:  三.希尔排序(缩小增量排序) 1.算法思想:  2.算法拆分解析  序列分组 分组预排序: 分组预排序的另一种实现方式: 希尔排序的实现

    2023年04月09日
    浏览(31)
  • 八大排序算法(C语言版)之插入排序

    八大排序算法: 超链接: 插入排序 选择排序 交换排序 归并排序 非比较排序 排序:所谓排序,就是使一串记录, 按照其中的某个或某些的大小,递增或递减的排列起来的操作。稳定性:假定在待排序的记录序列中,存在多个具有相同的的记录,若经过排序,这些

    2024年02月07日
    浏览(35)
  • 排序算法:插入排序(直接插入排序、希尔排序)

    朋友们、伙计们,我们又见面了,本期来给大家解读一下有关排序算法的相关知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! C 语 言 专 栏: C语言:从入门到精通 数据结构专栏: 数据结构 个  人  主  页 : stackY、 目录   前言: 1.排序

    2024年02月09日
    浏览(37)
  • 【排序算法】排序算法介绍及插入排序 ( 直接插入排序 && 希尔排序 )

    ​ ​📝个人主页:@Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:数据结构 🎯 长路漫漫浩浩,万事皆有期待 排序 :所谓排序,就是将一串数据,按照某种规律,或者以某种特性或,将数据按照递增或者递减,将数据从 无序转变为有序

    2023年04月21日
    浏览(27)
  • 排序算法之一:直接插入排序

    直接插入排序是一种简单的插入排序法,其基本思想是: 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列  实际中我们玩扑克牌时,就用了插入排序的思想 当插入第i(i=1)个元素时, 前面的

    2024年02月04日
    浏览(23)
  • 十大排序算法(上)直接插入排序、希尔排序、直接选择排序、堆排序

    排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 稳定性 :假设在待排序的序列中,存在多个具有相同内容的元素,如果经过排序,这些元素的相对位置并不发生改变,则称这种排序算法是稳定的。 稳定的排序可以变成不稳定的

    2024年02月05日
    浏览(34)
  • 数据结与算法之排序-插入排序(直接插入/折半插入/希尔)

    文章目录 目录 前言 一、什么是插入排序 1.直接插入排序 2.折半插入排序          3.希尔排序 总结 理解三种排序,并将三种排序用C++实现,借鉴了王卓老师和没有难学的知识的图例 提示:以下是本篇文章正文内容,下面案例可供参考         插入排序是简单直观的排序方

    2024年02月04日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包