插入排序(直接插入排序,折半插入排序,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; }
相关文章推荐
- 插入排序(直接插入排序,折半插入排序,2路插入排序,希尔排序)
- 通俗理解插入排序(直接插入排序,折半插入排序,希尔排序)
- 各种排序算法汇总(插入排序:直接插入排序、折半插入排序、希尔排序)
- 插入排序(直接插入排序,折半插入排序,2路插入排序)
- java实现排序算法之插入排序(直接插入排序,折半插入排序,希尔排序)
- Java排序算法总结之(一)——插入排序(直接插入排序、折半插入排序、希尔排序)
- java数据结构之插入排序(直接插入排序、折半插入排序、希尔排序)
- 排序算法之直接插入排序、二分插入排序和希尔排序
- 插入排序【直接插入排序和希尔排序】
- 三种常用的插入排序算法--直接插入排序、二分插入排序、希尔排序
- 【Java常用排序算法】插入排序(直接插入排序、希尔排序)
- 【Java常用排序算法】插入排序(直接插入排序、希尔排序)
- 插入排序——直接插入排序和希尔排序,C++代码实现
- 直接插入排序、二分插入排序、希尔排序、冒泡排序与简单选择排序
- 【排序】插入排序(直接插入排序、希尔排序)
- 排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序
- 插入排序法之——直接插入排序、折半插入排序、希尔排序
- 直接插入排序、折半插入排序、shell插入排序
- 直接插入排序、折半插入排序、shell插入排序
- 算法-排序-插入排序(直接插入和希尔排序)