这道题的意思是给一摞纸牌,上面标有大小的数字,让你在一定条件限制下完成排序,条件是你只能看到上面两张牌,要么交换两张牌,要么将最上面的牌放到这摞牌的底部。
从这道题的描述可以发现,纸牌的交换类似于冒泡排序。
先复习一下什么是冒泡排序。
冒泡排序通过重复地走访待排序列,发现相邻的两项顺序颠倒,就交换两项,不断循环重复,直到没有元素交换的时候(每次循环都能确定一个元素的固定位置,循环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
- 比较第一个数和第二个数的大小,将小的数放在第一位。
3 > 1,交换,变成1 3 6 2 4
- 将第一位进行标志,然后将第一位放在最右边。
3 6 2 4 *1
- 比较第一位和第二位,将小的数放在第一位,然后将第一位放在最右边。
3 < 6, 不用交换,直接将3放在最右边。6 2 4 *1 3
- 重复第3步,直到标志位走到第二位,退出循环。
6 *1 3 2 4
- 直接将6放在最右边,结束第一轮的循环。
*1 3 2 4 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