您的位置:首页 > 理论基础 > 数据结构算法

数据结构之排序--插入类排序

2013-11-17 11:53 274 查看
一. 插入类排序

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 } }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: