(1)直接插入
算法的复杂度O(n * n)。
头文件:
#define MAXSIZE 20
#define EQ(a, b) ((a) == (b))
#define LT(a, b) ((a) < (b))
#define LQ(a, b) ((a) <= (b))
typedef int KeyType;
typedef int InfoType;

typedef struct ...{
KeyType key;
InfoType otherinfo;
}RedType;

typedef struct ...{
//r[0] is the sentinel, not used.
RedType r[MAXSIZE + 1];
int length;
}SqList;源文件:
#include "stdio.h"
#include "sort.h"

void init(SqList &s, int w[], int n)...{
s.length = n;
for(int i = 1; i <= n; i++)...{
s.r[i].key = w[i - 1];
}
}

void show(SqList s)...{
for(int i = 1; i <= s.length; i++)...{
printf("%d ", s.r[i]);
}
printf(" ");
}

void insert(SqList &s)...{
for(int i = 2; i <= s.length; i++)...{
if(LT(s.r[i].key, s.r[i - 1].key))...{
//set the sentinel
s.r[0] = s.r[i];
s.r[i] = s.r[i - 1];
for(int j = i - 2; LT(s.r[0].key, s.r[j].key); j--)...{
s.r[j + 1] = s.r[j];
}
s.r[j + 1] = s.r[0];
}
}
}

void main()...{
int w[] = ...{49, 38, 65, 97, 76, 13, 27, 49};
int n = 8;
SqList s;
init(s, w, n);
insert(s);
show(s);
}执行结果:
13 27 38 49 49 65 76 97
Press any key to continue(2)减少比较次数-折半插入
源文件添加:
//use the binary search method to find the location to insert.
void binaryInsert(SqList &s)...{
for(int i = 2; i <= s.length; i++)...{
//set the sentinel
s.r[0] = s.r[i];
//binary search the location to insert
int low = 1, high = i - 1;
int m;
while(low <= high)...{
m = (low + high) / 2;
if(LT(s.r[0].key, s.r[m].key))...{
high = m - 1;
}else...{
low = m + 1;
}
}

for(int j = i - 1; j >= high + 1; j--)...{
s.r[j + 1] = s.r[j];
}
s.r[high + 1] = s.r[0];
}
}折半插入仅减少了比较次数,而记录的移动次数没变。
(3)减少移动次数-表插入排序
头文件:
#define SIZE 100
#define EQ(a, b) ((a) == (b))
#define LT(a, b) ((a) < (b))
#define LQ(a, b) ((a) <= (b))
typedef int KeyType;
typedef int InfoType;

typedef struct ...{
KeyType key;
InfoType otherinfo;
}RedType;

typedef struct ...{
RedType rc;
int next;
}SLNode;

typedef struct ...{
//r[0] is head of static list
SLNode r[SIZE];
int length;
}SLinkListType;源文件:
#include "stdio.h"
#include "SLLInsert.h"

void init(SLinkListType &s, int w[], int n)...{
s.length = n;
for(int i = 1; i <= n; i++)...{
s.r[i].rc.key = w[i - 1];
//point to the head, to use r[o] as a sentinal
s.r[i].next = 0;
}
s.r[0].next = 1;
}

void show(SLinkListType s)...{
for(int i = 0; i <= s.length; i++)...{
printf("%d: %d(%d) ", i, s.r[i].rc.key, s.r[i].next);
}
printf(" ");
}

void insert(SLinkListType &s)...{
int parent, next;

for(int i = 2; i <= s.length; i++)...{
s.r[0].rc.key = s.r[i].rc.key;
parent = 0;
next = s.r[parent].next;

while(LT(s.r[next].rc.key, s.r[0].rc.key))...{
parent = next;
next = s.r[next].next;
}
//insert
s.r[i].next = next;
s.r[parent].next = i;
}
}

void main()...{
int w[] = ...{49, 38, 65, 97, 76, 13, 27, 49};
int n = 8;
SLinkListType s;
init(s, w, n);
insert(s);
show(s);
}程序执行结果:
0: 49(6) 1: 49(3) 2: 38(8) 3: 65(5) 4: 97(0)
5: 76(4) 6: 13(7) 7: 27(2) 8: 49(1)
Press any key to continue表插入并没有减少比较次数,故复杂度仍为O(n * n)。
(4)shell排序
子序列的构成不是简单的“逐段分割”,而是将相隔某个“增量”的记录组成一个子序列。
源文件添加:
//one pass of shell sort
void shellInsert(SqList &s, int dk)...{
int j;
for(int i = dk + 1; i <= s.length; i++)...{
if(LT(s.r[i].key, s.r[i - dk].key))...{
s.r[0] = s.r[i];
for(j = i - dk; j > 0 && LT(s.r[0].key, s.r[j].key); j -= dk)...{
s.r[j + dk] = s.r[j];
}
s.r[j + dk] = s.r[0];
}
}
}

void shellSort(SqList &s, int dlta[], int t)...{
for(int k = 0; k < t; k++)...{
shellInsert(s, dlta[k]);
}
}

void main()...{
int w[] = ...{49, 38, 65, 97, 76, 13, 27, 49};
int n = 8;

int dlta[] = ...{5, 3, 1};
int t = 3;
SqList s;
init(s, w, n);
//binaryInsert(s);
shellSort(s, dlta, t);
show(s);
}程序执行结果:
13 27 38 49 49 65 76 97
Press any key to continue注意:增量序列中 dlta[] 没有除了1以外的公因子,并且最后一个增量值必须等于1。
1万+

被折叠的 条评论
为什么被折叠?



