插入排序

插入排序的描述

       我们假设对较小数组A[0...n-2]排序的问题已经解决了,我们得到了一个大小为n-1的有序数组:A[0] ≤...≤ A[n-2]。我们如何把这个较小规模的解和元素A[n-1]一同考虑,来得到原问题的解呢?显然,我们所需要做的就是在这些有序的元素中为A[n-1]找到一个合适的位置,然后把它插入到那里。

       有3种合理的做法可以达到这个目的,它们各不相同。第一,我们可以从左到右扫描这个有序的子数组,直到遇到第一个大于等于A[n-1]的元素,然后把A[n-1]插在该元素的前面。第二,我们可以从右到左扫描这个有序的子数组,直到遇到第一个小于等于A[n-1]的元素,然后把A[n-1]插在该元素的后面。这两种做法本质上来说是相同的,但一般来说,在实践中,第二种方法用的更多一些,因为对于有序和基本有序的数组,它的效率更高一些。这两种算法被称为直接插入排序,或者简称为插入排序。第三种做法是使用折半查找为A[n-1]在有序子数组总找到一个合适的位置。这种算法被称为折半插入排序

       从A[1]开始,到A[n-1]为止,A[i]被插在数组的前i个有序元素中的适当位置上(但是,和选择排序不同,这个位置一般来说并不是它们的最终位置)。

                                             


       算法:

InsertionSort(A[0...n-1])
 //该算法用插入排序对给定的数组排序
 //输入:一个可排序的数组A[0...n-1]
 //输出:非降序排列的数组A[0...n-1]
 for i <- 1 to i <- n-1 do 
    v <- A[i]
    j <- i-1
    while j >= 0 and A[j] > v  do
	  A[j+1] <- A[j]
          j <- j -1
    A[j+1] <- v


插入排序的实现

// InsertSort.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "typedef.h"

/*
*函数名:Compare_uint
*参数:pKey1  指向第一个比较元素的地址
*      pKey2  指向第二个比较元素的地址
*功能:比较两个元素的大小
*返回值:1 表示Key1 大于 Key2
*        -1 表示Key1 小于 Key2
*        0 表示Key1 等于 Key2
*作者:AlbertoNo1
*日期:2016-03-15
*/
INT32 Compare_uint(VOID *pKey1, VOID *pKey2)
{
	/*对两个无符号整型数进行比较*/
	if (*((UINT32*)pKey1) > *((UINT32*)pKey2))
	{
		return 1;
	}
	else if (*((UINT32*)pKey1) < *((UINT32*)pKey2))
	{
		return -1;
	}
	else
	{
		return 0;
	}
}

/*
*函数名:InsertionSort
*参数:pData  待排序数组数据的首地址
*      uiSize 数据的元素个数
*      uiElmSize  数据元素所占内存大小(Byte)
*      compare  两个元素的比较函数
*功能:对数组进行插入排序
*返回值:无
*作者:AlbertoNo1
*日期:2016-03-23
*/
VOID InsertionSort(VOID *pData, UINT32 uiSize, UINT32 uiElmSize, INT32 (*compare)(VOID *pKey1, VOID *pKey2))
{
	UINT32 i = 0;
	INT32 j = 0;

	CHAR *pucData = NULL;
	CHAR *pTemp = NULL;

	if (uiSize <= 1)
	{/*不用排序*/
		return ;
	}

	pTemp = (CHAR*)malloc(uiElmSize);
	if (NULL == pTemp)
	{
		return ;
	}

	pucData = (CHAR*)pData;

	for (i = 1; i < uiSize; i++)
	{/*进过 uiSzie-1 轮插入后,排序完成*/

		memcpy(pTemp, &pucData[i*uiElmSize], uiElmSize);

		j = i-1;

		while((j>=0)&&(compare(&pucData[j*uiElmSize], pTemp)>0))
		{
			memcpy(&pucData[(j+1)*uiElmSize], &pucData[j*uiElmSize], uiElmSize);
			j--;
		}

		memcpy(&pucData[(j+1)*uiElmSize], pTemp, uiElmSize);
	}

	return ;
}


int _tmain(int argc, _TCHAR* argv[])
{
	INT32 iRet = 0;
	UINT32 uiLoop = 0;

	//UINT32 auiData[] = {10,15,15,18,20,20,20,36,48,51,51,77,77};
	//UINT32 auiData[] = {77,77,51,51,48,36,20,20,20,18,15,15,10};
	UINT32 auiData[] = {77,15,20,18,51,51,36,10,77,15,20,20,48};
	//UINT32 auiData[] = {77,77};
	//UINT32 auiData[] = {77};

	InsertionSort(auiData, sizeof(auiData)/sizeof(auiData[0]), sizeof(auiData[0]),Compare_uint);

	printf("Insertion Sort Success.\n");
	printf("Result:\n");

	for (uiLoop = 0; uiLoop < sizeof(auiData)/sizeof(auiData[0]); uiLoop++)
	{
		printf("%d  ", auiData[uiLoop]);
	}

	getchar();
	return 0;
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值