一. 插入类排序
1. 直接插入排序
待排数列初始状态是正序,反序,无序时的时间复杂度为O(n), O(n^2), O(n^2)
是稳定的排序算法
2. 二分插入排序
3.希尔排序
希尔排序优于直接插入排序。理由:1> 当待排数列大致有序时,比较和移动的次数较少(比较后才移动,比较的少自然移动的少,移动的少比较的也少)
2> 当待排数列元数个数较少时,n 与 n^2 的差距也小。即O(n)与O(n^2)差不多
3>希尔排序刚开始时,增量大,分组多,之后增量减少,分组减少,组内元素增加,但却大致有序,故希尔排序在效率上较直接插入排序有较大的改进!
希尔排序是不稳定的算法,即相同关键字排序后的相对顺序()会改变
插入类排序的基本思想是:把无序区的记录按关键字大小,插入已排好的有序区内!
1. 直接插入排序
大体思路:a>把无序区的记录按关键字大小,插入已排好的有序区内!
b>单趟具体如何插入?把无序区的待排记录,从后向前与有序区的元素相比,不一定比较到第一个元素!
void insert_sort(int a[], int len)
{
int i, j;
int tmp;
for (i = 1; i < len; i++) {
tmp = a[i];
for (j = i - 1; j >= 0; j--) {
if (tmp >= a[j]) // 此处tmp改成a[j + 1]呢? tmp是待排元素! a[j + 1]呢?
break;
a[j + 1] = a[j]; // 此处仅是后移,不是交换! 整个外层与内层循环才是交换,所以也可以写个SWAP宏来实现,不过效率降低了
}
a[j + 1] = tmp;
}
return ;
}
2. 二分法插入排序
int binary_search(int a[], int len, int x)
{
int left, right;
left = 0;
right = len - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (x > a[mid])
left = mid + 1;
else if (x = a[mid])
return mid;
else
right = mid - 1;
}
return left;
}
void binary_sort(int a[], int len)
{
int i, j, n;
int tmp;
for (i = 1; i < len; i++) {
tmp = a[i];
n = binary_search(a, i, tmp);
for (j = i - 1; j >= n; j--) {
a[j + 1] = a[j];
}
a[j + 1] = tmp;
}
}
待排数列:9, 8, 3, 1, 7, 4, 10, 14
输入结果:3 1 4 7 8 9 10 14
检查了几遍,一是算法,符合逻辑,应该没问题 二调用也应该没问题。。。不知到该检查什么了。。。
后来不注意看到 else if (x = a[mid])....比较表达式,怎么成赋值了啊!知道哪里有问题了.............脑子不是很清醒时,就易犯这种很二的错误,并别检查了几遍都没看出来!
所以,三应该检查语言本身容易出错的地方,如“==” 写成 "="
3.希尔排序
大体思路:取一个小于len的数d1作为第一个增量,把待排数列分为d1组,所有距离为d1的元数为一组,在组内进行直接插入排序;
然后取第二个增量d2 (d2 < d1),重复上述分组和排序。直至所取的增量dt = 1时,即所有的元素放在一个组内进行插入排序为止!该方法实质上是分组方法!
void shell_sort(int a[], int len)
{
int gap = len / 3;
while (gap) {
int i, j;
int tmp;
for (i = 0; i < len - gap; i++) { //需改! 从第一序列的第二个元素开始扫描,对首先出现的各子序列的第二个元素 ,分别在各子序列中进行插入处理。。直到各子序列最后一个元素
tmp = a[i];
for (j = i - gap; j >= 0; j = j - gap) {
if (a[j + gap] >= a[j])
break;
a[j + gap] = a[j];
}
a[j + gap] = tmp;
}
gap = gap - 1;
}
}
另一种方法:每次比较后,进行交换
void shellSorting(T data[], size_t len)
{
int gap = len;
int i, j;
while (gap /= 2) {
for (i = 1 ; i < len - gap; i++) {
for (j = i + gap; j >= gap; j--) // for (j = i + gap; j >= 0; j = j - gap)
if (data[j - gap] > data[j])
SWAP(data[j - gap], data[j]);
}
}
}
********************************************
不足 :变量命名??
3 void shellsorting(int ary[], int len)
4 {
5 int i, j; //放到循环 内
6 int d = len / 3;
7 int tmp; //同上
8
9 while (d <= 1) //while (d)
10 {
11 for (i = d; i < len; i++)
12 {
13 tmp = ary[i];
14
15 for (j = i - d; j >= 0; j = j - d)
16 {
17 if (tmp >= ary[j])
18 break;
19 ary[j + d] = ary[j];
20 }
21 ary[j + d] = tmp;
22 }
23
24 d--;
25 } }