排序算法系列学习,主要描述冒泡排序,选择排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序等排序进行分析。
文章规划:
一。通过自己对排序算法本身的理解,对每个方法写个小测试程序。 具体思路分析不展开描述。
二。通过《大话数据结构》一书的截图,详细分析该算法 。
在此,推荐下程杰老师的《大话数据结构》一书,当然不是打广告,只是以一名读者的身份来客观的看待这本书,确实是通俗易懂,值得一看。
ps:一个较为详细的学习链接 http://blog.csdn.net/MoreWindows/article/category/859207
八。双向冒泡排序。
一。个人理解
首先,这篇文章是建立在已经了解了冒泡排序的基础上写的。 如果对普通冒泡排序还有什么不懂的,可以看看我之前的一篇博客。
排序算法c语言描述---冒泡排序 http://blog.csdn.net/hitwhylz/article/details/9773589
下面简单谈谈双向冒泡。
双向冒泡排序是在冒泡排序的基础上改进而来的,其基本思想跟最原始的冒泡排序是一样的,只不过排序过程稍微优化了一点。
我们还是以整数升序排序为例来简单说说这种排序的过程:首先从前往后把最大数移到最后,然后反过来从后往前把最小的一个数移动到数组最前面,这一过程就是第一轮,然后重复这一过程,最终就会把整个数组从小到大排列好。双向冒泡排序要稍微优于传统的冒泡排序,因为双向排序时数组的两头都排序好了,我们只需要处理数组的中间部分即可,而单向即传统的冒泡排序只有尾部的元素是排好序的,这时每轮处理都需要从头一直处理到已经排好序元素的前面一个元素。虽然它在效率上有了点改进,但它也不能大幅度提高其排序的效率,这是由冒泡排序的基本过程所决定了的。
所以就本质来说,算法上也没什么优化,只是双向调整而已。下面具体看代码。
- #include<stdio.h>
- #define Max_ 10
- // 打印结果
- void Show(int arr[], int n)
- {
- int i;
- for ( i=0; i<n; i++ )
- printf("%d ", arr[i]);
- printf("\n");
- }
- // 交换数组元素位置
- void Swap( int *num_a, int *num_b )
- {
- int temp = *num_b;
- *num_b = *num_a;
- *num_a = temp;
- }
- //改进版的冒泡排序(双向冒泡)
- void BidBubbleSort(int array[], int n)
- {
- int low, high, flag, i;
- low = 0;
- high = n - 1;
- while(low < high)
- {
- flag=0;
- for(i=low; i<high; i++) //正向冒泡
- {
- if(array[i] > array[i+1]) //找到剩下中最大的
- {
- Swap(&array[i], &array[i+1]);
- flag = 1; //标志, 有数据交换
- }
- }
- if( !flag )
- break;
- high--;
- for( i=high; i>low; i-- ) //反向冒泡
- {
- if(array[i] < array[i-1]) //找到剩下中最小的
- Swap(&array[i], &array[i-1]);
- }
- low++;
- }
- }
- int main()
- { //测试数据
- int arr_test[Max_] = { 8, 4, 2, 3, 5, 1, 6, 9, 0, 7 };
- //排序前数组序列
- Show( arr_test, Max_ );
- BidBubbleSort( arr_test, Max_);
- //排序后数组序列
- Show( arr_test, Max_ );
- return 0;
- }
总的来说,代码也没什么难度,思路也简单,就不多做描述了。
按以往的行文风格,下面应该是《大话数据结构》一书的截图了。
不过,双向冒泡也不算一种全新的算法,顶多是冒泡排序的优化,并且书中也没有相关的知识,就不多做介绍了。
简单的用测试程序中的排序过程来做个总结吧
双向冒泡前数组 8 4 2 3 5 1 6 9 0 7
第1次排序-->4 2 3 5 1 6 8 0 7 9 //第一次正向排序,得到未排序数组中最大的数 9
第1次排序<--0 4 2 3 5 1 6 8 7 9 //第一次反向排序,得到未排序数组中最小的数 0
第2次排序-->0 2 3 4 1 5 6 7 8 9 //第二次正向排序,得到未排序数组中最大的数 8
第2次排序<--0 1 2 3 4 5 6 7 8 9 //第一次反向排序,得到未排序数组中最大的数 1
第3次排序-->0 1 2 3 4 5 6 7 8 9 //运气比较好,前两次已经排好序了,flag = 0,不进行第三次排序
双向冒泡后数组 0 1 2 3 4 5 6 7 8 9