基于C/C++的插入排序


前言

重新温习数据结构与算法,对一些常用的算法进行代码实现。

一、直接插入排序

1. 代码实现

#include<bits/stdc++.h>
using namespace std;
#define maxSize 100
typedef struct
{
	int Elem[maxSize];	//存储元素 
	int length;			//元素数组长度 
}SqList;

void sortCP(SqList &ql)
{
	//Elem[0]用于保存哨兵元素 
	int i=0,j=0;	//两层循环的标记位 
	for(i=2;i<ql.length;i++)	//从数组的第二个元素开始进行插入排序 
	{
		if(ql.Elem[i]<ql.Elem[i-1])		//如果当前数组元素小于它相邻的前一位数据 
		{
			ql.Elem[0] = ql.Elem[i];			//首先将当前数组元素保存到哨兵中,其实就是为了保存要排序的当前元素 
			for(j=i-1;ql.Elem[j]>ql.Elem[0];--j)	//将从当前元素的前一位元素位置开始往前遍历 
			{
				ql.Elem[j+1] = ql.Elem[j];	//如果所遍历的元素都大于哨兵数据,则依次往前移动 
			}								//循环结束的条件是当所遍历的元素刚好小于哨兵数据时,即当前位置是插入的正确位置 
			ql.Elem[j+1] = ql.Elem[0];
		}
	}
} 
int main()
{
	SqList QL;
	QL.length = 8;
	for(int i=1;i<=QL.length;++i)
	{
		cin>>QL.Elem[i];
	}

	cout<<"插入前元素:";
	for(int i=1;i<=QL.length;++i)
	{
		cout<<QL.Elem[i]<<" ";
	}
	
	sortCP(QL);
	
	cout<<endl;
	cout<<"插入后元素:";
	for(int i=1;i<=QL.length;++i)
	{
		cout<<QL.Elem[i]<<" ";
	}	
	//cout<<"ok!"<<endl; 
	return 0;
} 

2. 运行结果

在这里插入图片描述

二、折半插入排序

1.代码实现

#include<bits/stdc++.h>
using namespace std;
#define maxSize 100
typedef struct
{
	int Elem[maxSize];	//存储元素 
	int length;			//元素数组长度 
}SqList;

void sortCP(SqList &ql)
{
	int i=0,j=0;
	for(i=2;i<=ql.length;++i)
	{
		ql.Elem[0] = ql.Elem[i];	//将当前元素保存到哨兵位置
		int low = 1;
		int high = i-1;			//在查找这部分采用二分查找
		while(low<=high)
		{
			int mid = (low+high)/2;		//取中间位置作为与当前对象的比较标准 
			if(ql.Elem[i]<ql.Elem[mid])	//当前位置元素小于中间元素 
			high = mid-1;	//区间从上限缩小 
			else		
			low =mid+1;		//否则区间从下限缩小
			 
		} //当循环结束时,high+1为插入的位置
		
		for(j=i-1;j>=high+1;--j)		//把从插入位置后面的元素全都后移一位以便于进行插入操作 
		ql.Elem[j+1] = ql.Elem[j]; 
		
		ql.Elem[high+1] = ql.Elem[0];	//插入  
	}
} 

int main()
{
	SqList QL;
	QL.length = 8;
	for(int i=1;i<=QL.length;++i)
	{
		cin>>QL.Elem[i];
	}

	cout<<"插入前元素:";
	for(int i=1;i<=QL.length;++i)
	{
		cout<<QL.Elem[i]<<" ";
	}
	
	sortCP(QL);
	
	cout<<endl;
	cout<<"插入后元素:";
	for(int i=1;i<=QL.length;++i)
	{
		cout<<QL.Elem[i]<<" ";
	}	
	//cout<<"ok!"<<endl; 
	return 0;
} 

2.运行结果

在这里插入图片描述

三、希尔插入排序

1.代码实现

#include<bits/stdc++.h>
using namespace std;
#define maxSize 100
typedef struct
{
	int Elem[maxSize];	//存储元素 
	int length;			//元素数组长度 
}SqList;

void ShellInsert(SqList &ql,int dk)
{
	int i=0,j=0;
	for(i=dk+1;i<=ql.length;++i)//以dk为间隔长度 
	{
		if(ql.Elem[i]<ql.Elem[i-dk])	//当前元素与其前一个dk间隔的数据元素进行比较 
		{
			ql.Elem[0] = ql.Elem[i];	//保存当前元素到哨兵 
			for(j=i-dk;j>0&&ql.Elem[0]<ql.Elem[j];j=j-dk)	//以dk为单位长度进行遍历查找
			{
				ql.Elem[j+dk] = ql.Elem[j];		//将大于当前元素的数据后移,后移步长以dk为单位  
			}
			ql.Elem[j+dk] = ql.Elem[0];			//内层遍历结束,找到了合适位置,将哨兵元素数据插入到该位置 
		}
	}
}
void ShellSort(SqList &ql,int dlta[],int t)
{
	//按照增量序列dlta进行排序 
	for(int k=0;k<t;k++)	//步长按照序列进行插入排序,此方法仅是提高了排序速度,但是排序效率与增量序列的设置有很大关系 
	{
		ShellInsert(ql,dlta[k]);	//进行增量为dlta[k]的插入排序 
	}
}


int main()
{
	SqList QL;
	QL.length = 8;
	for(int i=1;i<=QL.length;++i)
	{
		cin>>QL.Elem[i];
	}

	cout<<"插入前元素:";
	for(int i=1;i<=QL.length;++i)
	{
		cout<<QL.Elem[i]<<" ";
	}
	
	int dlta[3]={5,3,1};	//希尔增量序列设置,该序列最后一位一定是1。且各个元素必须互为质数 
	 
	ShellSort(QL,dlta,3); 
	
	cout<<endl;
	cout<<"插入后元素:";
	for(int i=1;i<=QL.length;++i)
	{
		cout<<QL.Elem[i]<<" ";
	}	
	//cout<<"ok!"<<endl; 
	return 0;
} 

2.运行结果

在这里插入图片描述


总结

  1. 用哨兵进行当前元素的保存与比较,将其放在数组下标为0的位置,以便于进行遍历和比较操作。
  2. 折半插入排序相较于直接插入排序,主要区别在于查找部分的不同。
  3. 希尔排序相较于直接插入排序,直接插入排序是以步长为1进行遍历查找以及排序的。而希尔排序是按照事先给定的序列作为步长进行多次插入排序。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

creator_gzw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值