(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;
#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);
}
#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
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];
}
}
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;
#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);
}
#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
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);
}
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
Press any key to continue
注意:增量序列中 dlta[] 没有除了1以外的公因子,并且最后一个增量值必须等于1。