折半插入排序

2016年7月28日08:21:18
	折半插入排序:折半插入排序算法是对直接插入排序算法的改进,它的主要改进在于在已经有序的子集中确定待排序元素的位置
	找到要插入的位置后,将相应的元素插入到该位置即可;
	假设所给的数据为:[67,53,73,21]
	第一趟排序:初始的状态为:[67,|53,73,21]
				t = 53,在有序子集中min = 0,max = 0;->mid = (min+max)/2 = 0
				将53与L->data[mid]进行比较->发现53<67;更新有序子集的查找范围:max = mid-1 = -1;
				___________________________________________________________________________________
					注意:假设[67,|67,73,21]
					t = 67,在有序子集中min = 0,max = 0;->mid = (min+max)/2 = 0
					将67与67进行比较,发现相等,那么为了排序的稳定性,排序前第二位置的67,在第一个位置前面,
					排序后它也应该在第一个的前面,
				_____________________________________________________________________________________
				发现max<min这时就不能继续查找了,需要查找的位置已经找到,即为min,将min到有序子集
				的元素向后移动->[67,|67,73,21]
				将元素插入到min所在的位置:->[53,|67,73,21]
				同时有序子集的个数增加一个->[53,67|73,21]
	第二趟排序:初始的状态为:[53,67|73,21]
				t = 73,在有序子集中min = 0,max = 1;->mid = (min + max )/2 = 0;
				将73与L->data[mid]进行比较->发现73>53;更新有序子集的查找范围:min = mid+1 = 1;中间mid = (min+max)/2 = 1
				将73与L->data[mid]进行比较->发现73>67;更新有序子集的查找范围:min = mid+1 = 2;发现max<min
				这时就不用再继续查找了,需要查找的位置已经找到,即为min = 2;
				这时不用移动有序表表中的元素了,直接将元素插入到它原来的位置;
				同时有序表子集的个数增加一个->[53,67,73|21]
	第三趟排序:初始的状态为:[53,67,73|21]
				______________________________________________________________________________________
					注意:假设[53,67,73|67]
					在有序子集中min = 0,max = 2;->mid = (min+max)/2 =1
					将67和67比较,发现相等,那么那么为了排序的稳定性,排序前第二位置的67,在第一个位置前面,
					排序后它也应该在第一个的前面,[53,67,73|73]->[53,67,67,73],即令min = mid+1

				______________________________________________________________________________________
				t = 21;在有序子集中min = 0,max = 2;->mid = (min + max )/2 = 1;
				将21与L->data[mid]进行比较->发现21<67;更新有序子集的查找范围:max = mid-1 = 0;中间mid = (min+max)/2 = 0;
				将21与L->data[mid]进行比较->发现21<53;更新有序子集的查找范围:max = mid-1 = -1;发现max<min
				这时就不用再继续查找了,需要查找的位置已经找到,即为min = 0;
				将min及其有序表后面的所有元素都往后移动一个元素的位置;
				[53,67,73|21]->[53,67,73|73]->[53,67,67|73]->[53,53,67|73]
				最后将当前的元素插入到min所在的位置;
				同时有序表子集的个数增加一个->[53,67,73,21|]
				当未排序的子集中元素为空,算法执行结束;
#include<stdio.h>
#include<stdlib.h>
#define MAXISIZE 100
#define random(x)(rand()%x)


//顺序表结构体类型
typedef struct 
{
	int data[MAXISIZE];
	int length;
}SeqList;

//函数前置声明
void initSeqList(SeqList * S);
void seqListAssign(SeqList * S);
void traverseSeqList(SeqList * S);
void binInsertSort(SeqList * S);

//折半插入排序
void binInsertSort(SeqList * S)
{
	int i,j;
	int min,max,mid;
	int tempVal;
	for( i = 1;i<S->length;i++)
	{
		tempVal = S->data[i];
		min = 0;
		max = i-1;
		mid = (min+max)/2;
		while(min<=max)
		{
			if(tempVal<S->data[mid])
			{
				max = mid-1;
			    mid = (min+max)/2;
			}
			else if(tempVal>=S->data[mid])
			{
				min = mid+1;
				mid = (min+max)/2;
			}
			/*else 
			{
				min = mid +1;
				break;
			}*/
		}
		for(j = i-1;j>= min;j--)
		{
			/*
				S->data[i] = S->data[i-1];
				S->data[i-1] = S->data[i-2];
				...
				S->data[min+1] = S->data[min];
			*/
			S->data[j+1] = S->data[j];
		}
		S->data[min] = tempVal; 
		/*for( j = 0;j<=i-1&&min<=max;j++)
		{
			min = j;
			max = i-1;
			mid = (min+max)/2;
			if(tempVal<S->data[mid])
			{
				max = mid-1;
			}
			else if(tempVal>S->data[mid])
			{
				min = mid+1;
			}

		}*/
		//S->data[min] = tempVal; 
	}
	return;
}

//初始化顺序表
void initSeqList(SeqList * S)
{
	S->length = 0;
	return ;
}

//给顺序表赋值
void seqListAssign(SeqList * S)
{
	int i;
	for(i = 0;i<MAXISIZE;i++)
	{
		S->data[i] = random(100);
	}
	S->length = MAXISIZE;
	return;
}

//将顺序表中的元素遍历输出
void traverseSeqList(SeqList * S)
{
	int i;
	for( i = 0;i<S->length;i++)
	{
		printf("%-6d",S->data[i]);
	}
	printf("\n");
	return ;
}

//主函数
int main(void)
{
	SeqList S;
	initSeqList(&S);
	seqListAssign(&S);
	printf("产生的随机数据为:\n");
	traverseSeqList(&S);
	binInsertSort(&S);
	printf("排序后数据为:\n");
	traverseSeqList(&S);
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值