您的位置:首页 > 其它

插入排序(直接插入排序,折半插入排序,2路插入排序,希尔排序)

2012-11-07 18:13 603 查看
/*
插入排序:直接插入排序,折半插入排序,2路插入排序,希尔排序
将数据由小到大排列
运行环境:VS2010
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define OK 1
#define ERROR 0
#define MAXSIZE 50

typedef struct
{
int value;
}RedType;

typedef struct
{
RedType red[MAXSIZE+1];	//red[0]用作哨兵单元
int length;
}SqList;

SqList *CreateSqList()
{
int i = 0;
int j = 0;
char buf[4*MAXSIZE] = "";
char *ptr = NULL;
SqList *sqlist = (SqList *)malloc(sizeof(SqList));
memset(sqlist, 0, sizeof(SqList));

printf("请输入待排序数据,以逗号分隔,以分号结束\n"
"例:23,12,65,36,35;\n"
"input:");
scanf("%s", buf);

ptr = buf;
sqlist->red[i].value = 0;	//red[0]不存值用作哨兵单元
i = 1;
while(*ptr != ';')
{
sqlist->red[i].value = atoi(ptr);
i++;

ptr = strstr(ptr, ",");
if(!ptr)
{
break;
}
ptr++;
}
sqlist->length = (i - 1);

return sqlist;
}

//直接插入排序
int StraightInsertSort(SqList *sqlist)
{
int i = 0;
int j = 0;
for(i = 2; i <= sqlist->length; i++)
{
if(sqlist->red[i].value < sqlist->red[i-1].value)
{
sqlist->red[0] = sqlist->red[i];
sqlist->red[i] = sqlist->red[i-1];

for(j = (i - 2); (sqlist->red[0].value < sqlist->red[j].value); j--)
{
sqlist->red[j+1] = sqlist->red[j];	//大于哨兵位置的记录后移
}
sqlist->red[j+1] = sqlist->red[0];	//将哨兵处的数据插入到正确位置
}
}

return OK;
}

//折半插入排序
int BinaryInsertSort(SqList *sqlist)
{
int i = 0;
int j = 0;
int low = 0;
int high = 0;
int mid = 0;

for(i = 2; i <= sqlist->length; i++)
{
sqlist->red[0] = sqlist->red[i];
low = 1;
high = i-1;
while(low <= high)
{
mid = (high + low) / 2;

if(sqlist->red[0].value < sqlist->red[mid].value)
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}

for(j = i - 1; j > high; j--)
{
sqlist->red[j+1] = sqlist->red[j];
}
sqlist->red[j+1] = sqlist->red[0];
}

return OK;
}

//2路插入排序
int P2InsertSort(SqList *sqlist)
{
int i = 0;
int j = 0;
int first = 0;	//记录排好序的那段数据的第一个位置,即最小值所在位置
int final = 0;	//记录排好序的那段数据的最后一个位置,即最大值所在位置
RedType *d = NULL;

d = (RedType *)malloc(sqlist->length * sizeof(RedType));
memset(d, 0, sqlist->length * sizeof(RedType));
d[0].value = sqlist->red[1].value;
first = 0;
final = 0;

for(i = 2; i <= sqlist->length; i++)
{
if(sqlist->red[i].value > d[final].value)	//sqlist->red[i]的值比当前有序数组最大值还大
{
final = final + 1;
d[final] = sqlist->red[i];
}
else if(sqlist->red[i].value < d[first].value)	//sqlist->red[i]的值比当前有序数组最小值还小
{
first = (first - 1 + sqlist->length) % sqlist->length;
d[first] = sqlist->red[i];
}
else		//插入到d[]的中间,需要移动d
{
j = final;
sqlist->red[0] = sqlist->red[i];
while(d[j].value > sqlist->red[0].value)
{
d[(j + 1) % sqlist->length] = d[j];
j = (j - 1 + sqlist->length) % sqlist->length;
}
d[(j + 1) % sqlist->length] = sqlist->red[0];
final = final + 1;		//别忘了final+1,因为添了一个数据,一部分数据都向后移了一个单位
}
}
//最后把d[]中的值放到sqlist->red[]中
j = first;
for(i = 1; i <= sqlist->length; i++)
{
sqlist->red[i] = d[j];
j = (j + 1) % sqlist->length;
}

free(d);
return OK;
}

//一趟希尔排序
int ShellInsert(SqList *sqlist, int dk)
{
int i = 0;
int j = 0;
for(i = (dk + 1); i <= sqlist->length; i++)
{
if(sqlist->red[i].value < sqlist->red[i-dk].value)
{
sqlist->red[0] = sqlist->red[i];	//暂存在sqlist->red[0]中
for(j = (i - dk); ((j > 0) && (sqlist->red[0].value < sqlist->red[j].value)); j = (j - dk))
{
sqlist->red[j+dk] = sqlist->red[j];		//记录后移,查找插入位置
}
sqlist->red[j+dk] = sqlist->red[0];
}
}

return OK;
}

/*
功能:希尔排序
参数:	sqlist	待排序的数组
dlta		记录增量的数组
t		增量数组的长度
*/
int ShellSort(SqList *sqlist,int dlta[],int t)
{
int k;
for(k = 0; k < t; k++)
{
// 一趟增量为dlta[k]的插入排序
ShellInsert(sqlist, dlta[k]);
}

return OK;
}

//打印表中数据
int PrintSqList(SqList sqlist)
{
int i = 0;
for(i = 1; i <= sqlist.length; i++)
{
printf("%d,", sqlist.red[i].value);
}
printf("\b;\n");
return OK;
}

int main()
{
SqList *sqlist = NULL;
SqList *testSqList = NULL;
int dt[3] = {5,3,1};	//希尔排序中的增量数组
sqlist = CreateSqList();
testSqList = (SqList *)malloc(sizeof(SqList));

printf("\n直接插入排序:\n");
memcpy(testSqList, sqlist, sizeof(SqList));
PrintSqList(*testSqList);
StraightInsertSort(testSqList);
PrintSqList(*testSqList);

printf("\n折半插入排序:\n");
memcpy(testSqList, sqlist, sizeof(SqList));
PrintSqList(*testSqList);
BinaryInsertSort(testSqList);
PrintSqList(*testSqList);

printf("\n2路插入排序:\n");
memcpy(testSqList, sqlist, sizeof(SqList));
PrintSqList(*testSqList);
P2InsertSort(testSqList);
PrintSqList(*testSqList);

printf("\n希尔排序:\n");
memcpy(testSqList, sqlist, sizeof(SqList));
PrintSqList(*testSqList);
ShellSort(testSqList, dt, 3);
PrintSqList(*testSqList);

free(testSqList);
free(sqlist);
system("pause");

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐