【排序算法2】插入排序

插入排序的中心思想就是将一个元素插入到已经排好序的数组当中。
数组a[n]
初始时,a[0]自成一格有序区,无序区为a[1…n-1] 令i = 1
将a[i]并入当前有序区a[0…i-1]中形成有序区间
i++并重复第二步直到 i == n -1

#include <stdio.h>
#include <Windows.h>
#include "MyFunctions.h"
/*
	数组a[n]
		1.初始时,a[0]自成一格有序区,无序区为a[1....n-1]  令i = 1
		将a[i]并入当前有序区a[0...i-1]中形成有序区间
		i++并重复第二步直到 i == n -1
*/



void insert_sort(int a[],int n)
{
	int i,j,k,temp;
	for( i = 1; i < n ; ++i )
	{
		for( j = i - 1 ; j >= 0 ; --j )
		{
			/*
			if( a[i] < a[j - 1] )
			{
				a[j] = a[j - 1];  //这里不能交换数据,因为a[i]的数据可能会被前面的数据覆盖
			}
			else
			{
				//a[j] = temp;
				break;
			}
			*/

			if( a[j] < a[i]  )
			{
				break;
			}
		}
		//判断j的位置是否是原来的位置,不是的话要将数据后移至j之后
		if( j != i - 1 )
		{
			temp = a[i];
			for( k = i - 1 ; k > j ; --k )
			{
				a[k + 1] = a[k];
			}
			a[k + 1] = temp;
		}
		//a[j] = temp;  上面 j == i的情况下a[j]会被赋值成上次的temp
		// j == i 就不用换
	}
}

//优化上面的插入排序
void insert_sort2(int a[],int n)
{
	int i,j,temp;
	for(int i = 1; i < n ; ++i )
	{
		if( a[i] < a[i - 1] )
		{
			temp = a[i];
			for(j = i - 1 ; j >= 0 && a[j] > temp ; --j)  //退出的情况j < 0 || a[j] <= temp所以不管哪种退出情况这个插入的位置都是j+1
			{
				a[j + 1] = a[j];
			}
			a[j + 1] = temp;
		}
	}
}

//优化insert_sort2,不用前一个数据覆盖后一个数据的方法,而是使用2个数据交换的方式
void insert_sort3(int a[],int n)
{
	for(int i = 1 ; i < n ; ++i )
	{
		if( a[i] < a[i - 1] )
		{
			//for( int j = i - 1 ; j >= 0 ; --j )
			//{
			//	if( a[j + 1] < a[j] )
			//	{
			//		Swap(&a[j + 1],&a[j]);  //如果前一个数比后一个数大就交换
			//	}
			//	else
			//	{
			//		break;  //如果没有交换就代表着这次插入排序已经完成
			//	}
			//}
			
			//优秀写法  与上面的逻辑一模一样
			for( int j = i - 1 ; j >= 0 && a[j + 1] < a[j] ; --j)
			{
				PJDSwap(&a[j + 1],&a[j]);
			}

		}
	}
}



int main()
{
	int a[10] = {5,3,7,0,9,4,1,8,2,6};
	insert_sort3(a,10);
	PJDprint(a,10);
	system("pause");
	return 0;
}

这里偷了个小小的懒,我将Swap函数和Print函数放到了自己写的函数文件中,这样就不用每次都写一遍,嘿嘿。
我以前不是很了解,一直以为插入排序要开辟一个与原数组一样大的空间,向其中插入数据。
这里非常感谢MoreWindows的系列博客白话经典算法白话经典算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值