《算法》第四版2.1.14

匿名 (未验证) 提交于 2019-12-03 00:03:02

这道题的意思是给一摞纸牌,上面标有大小的数字,让你在一定条件限制下完成排序,条件是你只能看到上面两张牌,要么交换两张牌,要么将最上面的牌放到这摞牌的底部。

从这道题的描述可以发现,纸牌的交换类似于冒泡排序。
先复习一下什么是冒泡排序。
冒泡排序通过重复地走访待排序列,发现相邻的两项顺序颠倒,就交换两项,不断循环重复,直到没有元素交换的时候(每次循环都能确定一个元素的固定位置,循环n次就能排序完成),循环终止完成排序。名字由来是因为在排序的过程中,越小的元素会经由交换慢慢地“浮”到顶端。
代码如下:

void bubblesort(int num[]) {     int n = 5;     int i = 0;     int swapped = 1;     while(swapped == 1){         swapped = 0;         for(i = 1; i < n; i++){             if(num[i - 1] > num[i]){                 int temp = num[i];                 num[i] = num[i - 1];                 num[i - 1] = temp;                 swapped = 1;             }         }     } }

一般情况下,我们知道一共就循环n次,还可以这样写:

void bubblesort(int num[]) {    int n = 5;    int i = 0;    for(i = 0; i < n; i++){        for(int j = 0; j < n - i - 1; j++){            if(num[j] > num[j + 1]){                int temp = num[j];                num[j] = num[j + 1];                num[j + 1] = temp;            }        }    } }

下面针对限制条件,尝试改变冒泡排序算法来解决这个问题。可以将纸牌抽象成数字,进行排序。
比如:3 1 6 2 4

  1. 比较第一个数和第二个数的大小,将小的数放在第一位。
    3 > 1,交换,变成 1 3 6 2 4
  2. 将第一位进行标志,然后将第一位放在最右边。
    3 6 2 4 *1
  3. 比较第一位和第二位,将小的数放在第一位,然后将第一位放在最右边。
    3 < 6, 不用交换,直接将3放在最右边。6 2 4 *1 3
  4. 重复第3步,直到标志位走到第二位,退出循环。
    6 *1 3 2 4
  5. 直接将6放在最右边,结束第一轮的循环。*1 3 2 4 6
  6. 返回第一步重新循环,直到在该循环中没有交换发生,退出循环,完成排序。

说明:每一个循环产生的结果和使用冒泡排序(无限制情况下)的结果是相同的。
下面是参考代码:

#include <stdio.h> void bubblesort(int num[]); void swap(int num[], int i, int j); void order(int num[]);//将第一位的数字放到最右边  int main() {     int num[] = {12,4,7,5,0};     int i;      printf("Original:\n");     for(int i = 0; i < 5; i++){         printf("%d ",num[i]);     }     printf("\n");      bubblesort(num);      printf("Result:\n");     for(int i = 0; i < 5; i++){         printf("%d ",num[i]);     }      return 0; }  void bubblesort(int num[]) {     int flag = 0;     int i;     int swapped = 1;     int cnt = 1;     while(swapped == 1){         swapped = 0;         if(num[0] > num[1]){             swap(num,0,1);             swapped = 1;         }         flag = 4;          order(num);          while(flag != 1){             if(num[0] > num[1]){                 swap(num,0,1);                 swapped = 1;             }             order(num);             flag --;         }         order(num);         printf("Iteration %d:\n",cnt);         cnt++;         for(int i = 0; i < 5; i++){             printf("%d ",num[i]);         }         printf("\n\n");     } }  void swap(int num[], int i, int j) {     int temp = num[i];     num[i] = num[j];     num[j] = temp; }  void order(int num[]) {     int temp = num[0];     int i = 0;     for(i = 0; i < 4; i++){         num[i] = num[i + 1];     }     num[4] = temp; }

运行效果:

Original: 12 4 7 5 0  Iteration 1: 4 7 5 0 12   Iteration 2: 4 5 0 7 12   Iteration 3: 4 0 5 7 12   Iteration 4: 0 4 5 7 12   Iteration 5: 0 4 5 7 12   Result: 0 4 5 7 12
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!