排序——冒泡排序和希尔排序

1,冒泡排序的基本思想:

       1,每次从后向前进行(假设为第 i 次),j = n - 1, n - 2, ..., i,两两比较 v[j-1] 和 v[j] 的关键字;如果发生逆序,则交换 v[j-1] 和 v[j];

          1,水低泡泡,因为轻,从水底冒出来;

 

2,第 i 次冒泡排序示例及元素排序示例:

 

       1,冒泡排序每次将最后无序序列中最小的元素找出并排到有序队列后面;

       2,Exchang 用来记录是否发生交换,一旦发生逆序就交换,交换则 Exchang == 1,当待排对象已经排好序,如果比较一致,发现Exchang 没有改变,则说明对象已经排好序了,没必要进行排好序了;

       3,关键是从后向前进行,两两进行比较,发生逆序就交换;

 

3,冒泡排序 Sort::Bubble 的实现(仅 *.cpp 文件):

 1 /* 冒泡排序 */
 2     template <typename T>
 3     static void Bubble(T array[], int len, bool min2max = true)  // O(n*n) 最坏情况下,冒泡排序的较其他排序要多一点点
 4     {
 5         bool exchange = true;  // 标记位,是否发生了交换,不交换时候就排好序了;不一定是最坏排序,取决于这个 exchange
 6         for(int i=0; (i<len) && exchange; i++)  // 标记位为假,则没有交换,那么就排序好了;最坏情况下这个循环要做完
 7         {
 8             exchange= false;  // 还没有排序,还没有交换
 9 
10             /* 具体的冒泡操作,从后向前,前面 i 个位置已经排好序了,所以 j>i;最//坏情况下这个循环要做完 */
11             for(int j=len-1; j>i; j--)
12             {
13                 if( min2max ? (array[j]<array[j-1]) : (array[j]>array[j-1]) )   // 发生逆序
14                 {
15                     Swap(array[j], array[j-1]);  // 交换
16                     exchange = true;  // 交换了
17                 }
18             }
19         }
20 }

             

4,希尔排序的基本思想:

       1,将待排序列划分为若干组,在每一组内进行插入排序,以使整个序列基本有序,然后再对整个序列进行插入排序;

 

5,希尔排序示例及元素排序示例:

 

 

 

6,希尔排序 Sort::Shell 实现(仅 *.cpp 文件):

 1 /* 希尔排序 */
 2     template <typename T>
 3     static void Shell(T array[], int len, bool min2max = true) // 不稳定的排序法,O(n的1.5)
 4     {
 5         int d = len;  // 设置间隔为 len
 6 
 7         do  // 多做几次插入排序就可以得到更快的算法了
 8         {
 9             /* 数学角度证明这样比较好比较困难,但是实践证明这样比较好,这个公式保证了 d 大于 1,同时当 d 很大的时候,减小比较快,当 d 接近 1 的时候减小比较慢;而 d-- 不能提高效率*/
10             d = d / 3 + 1;
11 
12             for(int i=d; i<len; i+=d)  // 这里是插入排序,初始值和循环增量都是 d
13             {
14                 int k = i;
15                 T e = array[i];  // 将要插入的数据元素拿出来
16                 for(int j=i-d; (j>=0)&&(min2max ? (array[j]>e) : (array[j]<e)); j-=d)  // 三目运算符决定排序方向
17                 {
18                     array[j+d] = array[j];
19                     k = j;
20                 }
21 
22                 if( k != i )  // 当要比较的元素 array[i] 比前面要被插入的元素都大的时候, k = i, 不用赋值,太耗时
23                 {
24                     array[k] = e;  // k 记录了比较后挪动的空位置下标
25                 }
26             }
27 
28         }while( d > 1 );
29    }

 

7,小结:

       1,冒泡排序每次从后向前将较小的元素交互到位;

       2,冒泡排序是一种稳定的排序法,其复杂度为 O(n*n);

       3,希尔排序通过分组的方式进行多次插入排序;

       4,希尔排序是一种不稳定的排序法,其复杂度为 O(n*√n);

              1,分组的排序方法,所以是个不稳定的排序法;

转载于:https://www.cnblogs.com/dishengAndziyu/p/10923921.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
冒泡排序是一种简单的排序算法,它重复地遍历待排序的元素,比较相邻元素的大小,如果顺序错误就交换它们,直到没有需要交换的元素为止。下面是冒泡排序的C语言实现: ```c void bubbleSort(int arr[], int n) { for(int i = 0; i < n-1; i++) { int flag = 0; //是否冒泡 for(int j = 0; j < n-1; j++) { if(arr[j > arr[j+1]) { swap(&arr[j], &arr[j+1]); flag = 1; } } if(flag == 0) { //如果没有发生交换,说明数组已经有序,可以提前结束循环 break; } } } ``` 在这个实现中,冒泡排序函数`bubbleSort`接受一个整型数组`arr`和数组长度`n`作为参数。它使用两层循环来遍历数组,并通过比较相邻元素的大小来进行交换。内层循环每次将最大的元素冒泡到数组的末尾。外层循环控制了冒泡的轮数,每一轮都会将当前未排序的最大元素放在正确的位置上。如果在某一轮的冒泡过程中没有发生交换,说明数组已经有序,可以提前结束循环,从而提高算法的效率。 需要注意的是,上述代码中使用了一个`swap`函数来交换两个元素的值,你可以根据需要自行实现该函数。此外,为了减少冒泡排序的时间复杂度,可以在内层循环中添加一个标志位`flag`,用于标记是否发生了交换。如果某一轮的冒泡过程中没有发生交换,说明数组已经有序,可以提前结束循环。这样可以避免不必要的比较和交换操作,提高排序的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值