三色旗算法
来源:互联网 发布:大道行知传媒官方网站 编辑:程序博客网 时间:2024/05/01 12:47
算法描述:
三色旗的问题最早由E.W.Dijkstra所提出,他所使用的用语为Dutch Nation Flag(Dijkstra为荷兰人),而多数的作者则使用Three-Color Flag来称之。
解法:
只是要让移动次数最少的话,就要有些技巧:
如果图中w所在的位置为白色,则w+1,表示未处理的部份移至至白色群组。
如果w部份为蓝色,则b与w的元素对调,而b与w必须各+1,表示两个群组都多了一个元素。
如果w所在的位置是红色,则将w与r交换,但r要减1,表示未处理的部份减1。
注意的细节:
第一,当w指向的是红色而和r交换时,如果此时r指向的是红色,显然没有必要把两个红色的旗子交换。所以这时应该把r前移,直到r指向的不是红色的时候才和w指向的旗子交换。当然移动时必须确保w<r。
第二,同样地,当w指向的是蓝色而要和b的指向交换时,如果b指向的不是蓝色,则交换。否则如果b指向的是蓝色,则也没有必要把两个蓝色的旗子交换。所以这时应该把b和w都往后移一位。
注意b、w、r并不是三色旗的个数,它们只是一个移动的指针;什幺时候移动结束呢?一开始时未处理的r指针处于最后一个旗子位子,当r的索引数减至少于w的索引数时,表示接下来的旗子就都是红色了,此时就可以结束移动。
运行结果:
三色旗的问题最早由E.W.Dijkstra所提出,他所使用的用语为Dutch Nation Flag(Dijkstra为荷兰人),而多数的作者则使用Three-Color Flag来称之。
假设有一条绳子,上面有红、白、蓝三种颜色的旗子,起初绳子上的旗子颜色并没有顺序,您希望将之分类,并排列为蓝、白、红的顺序,要如何移动次数才会最少,注意您只能在绳子上进行这个动作,而且一次只能调换两个旗子。示意图:
解法:
在一条绳子上移动,在程式中也就意味只能使用一个阵列,而不使用其它的阵列来作辅助,问题的解法很简单,您可以自己想像一下在移动旗子,从绳子开头进行,遇到蓝色往前移,遇到白色留在中间,遇到红色往后移。
只是要让移动次数最少的话,就要有些技巧:
如果图中w所在的位置为白色,则w+1,表示未处理的部份移至至白色群组。
如果w部份为蓝色,则b与w的元素对调,而b与w必须各+1,表示两个群组都多了一个元素。
如果w所在的位置是红色,则将w与r交换,但r要减1,表示未处理的部份减1。
注意的细节:
第一,当w指向的是红色而和r交换时,如果此时r指向的是红色,显然没有必要把两个红色的旗子交换。所以这时应该把r前移,直到r指向的不是红色的时候才和w指向的旗子交换。当然移动时必须确保w<r。
第二,同样地,当w指向的是蓝色而要和b的指向交换时,如果b指向的不是蓝色,则交换。否则如果b指向的是蓝色,则也没有必要把两个蓝色的旗子交换。所以这时应该把b和w都往后移一位。
注意b、w、r并不是三色旗的个数,它们只是一个移动的指针;什幺时候移动结束呢?一开始时未处理的r指针处于最后一个旗子位子,当r的索引数减至少于w的索引数时,表示接下来的旗子就都是红色了,此时就可以结束移动。
Java 代码实现:
public static void main(String[] args) { char[] threeFlag = new char[]{'R','B','R','W','R','R','W','B','B','W'}; int bPointer = 0; int wPointer = 0; int rPointer = threeFlag.length - 1; printProcess(threeFlag, bPointer, wPointer, rPointer); while (wPointer < rPointer) { if (threeFlag[wPointer] == 'B') { char temp = threeFlag[bPointer]; threeFlag[bPointer] = threeFlag[wPointer]; threeFlag[wPointer] = temp; bPointer++; wPointer++; } else if (threeFlag[wPointer] == 'W') { wPointer++; } else if (threeFlag[wPointer] == 'R') { char temp = threeFlag[rPointer]; threeFlag[rPointer] = threeFlag[wPointer]; threeFlag[wPointer] = temp; rPointer--; } printProcess(threeFlag, bPointer, wPointer, rPointer); } } public static void printProcess(char[] threeFlag, int bPointer, int wPointer, int rPointer) { char arrow = '↓'; String space1 = " "; String space2 = " "; String space3 = " "; String s1 = ""; String s2 = ""; for (int i=0; i<threeFlag.length; i++) { if ((bPointer == wPointer) && (bPointer==i)) { s1 = s1 + "bw" + space1; s2 = s2 + arrow + arrow + space1; } else if ((wPointer == rPointer) && (wPointer==i)) { s1 = s1 + "wr" + space1; s2 = s2 + arrow + arrow + space1; } else { if (bPointer == i) { s1 = s1 + "b" + space2; s2 = s2 + arrow + space2; } else if (wPointer == i) { s1 = s1 + "w" + space2; s2 = s2 + arrow + space2; } else if (rPointer == i) { s1 = s1 + "r" + space2; s2 = s2 + arrow + space2; } else { s1 = s1 + space3; s2 = s2 + space3; } } } String s3 = ""; String s4 = ""; String split = "---"; for (int i=0;i<threeFlag.length;i++) { s3 = s3 + threeFlag[i] + space2; s4 = s4 + split; } System.out.println(s1); System.out.println(s2); System.out.println(s3); System.out.println(s4); }
运行结果:
0 0
- 趣味算法-三色旗
- 三色旗算法
- 三色旗算法实现
- 算法思考---------三色旗
- [算法系列]三色旗
- 算法之三色旗
- 三色旗算法
- 三色旗算法
- 算法之三色旗
- 经典算法之三色旗
- 三色旗算法及其C程序
- 从三色旗算法到快速排序
- 榆木脑壳练算法之三色旗问题
- 每日一算法:三色旗问题
- 数据结构经典算法(4)三色旗
- 三色旗算法(C描述)
- 数据结构经典算法学习之三色旗
- 三色旗
- 如何还原像素级别的设计稿 切图工具 Photoshop操作
- 在Android上使用Https连接
- Windows BAT批处理脚本教程
- C++ STL模板与容器 知识 初学 小结 ( 一 )
- avformat_find_stream_info函数卡住问题
- 三色旗算法
- jquery.paginate分页插件使用
- Android UI-自定义日历控件
- 我的一些简单的shell脚本实例
- 用户微博阅读量、互动数、新增粉丝统计
- Poj 3984 迷宫问题(BFS)
- achartengine(Google给android提供的绘图工具包)的介绍和使用
- ios中使用fstream方式打开文件
- C# 调用Webservice并传递序列化对象