经典的三色旗问题
首先来看,什么是三色旗问题。
有一根绳子,上面有红、白、蓝三种颜色的旗子。绳子上旗子的颜色并没有顺序,现在要对旗子进行分类,按照蓝色、白色、红色的顺序排列。只能在绳子上进行移动,并且一次只能调换两面旗子,怎样移动才能使旗子移动的次数最少?
此为简述的三色旗问题。
这次,我们就来研究一下三色旗问题。
我们将它简单化。颜色什么的忽略。
我们将它理解为一个数组,有1,2,3;组成。且为无序的。
我们的任务就是将它按照前面均为1,紧接着为2,3,的数列。
当然解法有很多种。
比如说:多来几个数组,将它拆开。
再比如,我们记录各成分的个数。再分别输出。
在这里呢,我们讨论一种尽量简单,移动次数最少的算法。
那么,现在我们开始分析该算法。
我们定义三个变量,两个为0,一个为n-1;(假设数组长度为n)。
现在暂时将这三个变量分别称为n1,n2,n1;
其中n1=n2=0,n3=n-1;
我们我们用n1从头开始判断,如果为1的话,那么将n1,n2换位,同时n1,n2均向后移动一个单位(后面表示换位的均为其下标在数组中对应的元素换位。)
如果为2的话n1向后移动一位,n2不变。
如果是3的话,将n1和n3换位,同时n3向前移动一位,n1不变。
直至n1=n3时,说明排列完成。下面就是输出的问题了
怎么输出这里就不用多说了吧
下面我们看代码。
#include<stdio.h>
#include<stdlib.h>
void arr(int a[],int n)//重排列函数
{
int i,k,l;
int x;//定义中间变量,用于交换
i=0,k=n-1;//赋初值
l=0;
while(l<=k)//进行排列。
{
switch (a[l])
{
case /* constant-expression */1:
x=a[l];
a[l]=a[i];
a[i]=x;
i++;
l++;
/* code */
break;
case 2:
l++;
break;
case 3:
x=a[l];
a[l]=a[k];
a[k]=x;
k--;
break;
}
}
}
void Put(int a[],int n)//输出函数
{
int i;
for(i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}
int main()//主函数
{
int n;//长度
printf("请输入长度\n");
scanf("%d",&n);
int *a=(int *)malloc(4*n);//申请内存
int i,k,l;//定义变量
int x;
for(i=0;i<n;i++)//输入数组。
{
scanf("%d",&a[i]);
}
arr(a,n);//排列
Put(a,n);//输出
return 0;
}
下面来看运行结果
![](https://img2018.cnblogs.com/i-beta/1854053/202001/1854053-20200109074939197-1710068375.png)
OK,
如果这篇博客里面有什么问题的话,还希望大家能够给我提出来,大家共同学习,一起进步。
个人作品,
如有错误,请指出;
如要转载,请注明出处。
三克油。。