再来讲讲函数之间的调用:
现在有三个函数——main()、func1()、func2()。
其中,main()函数中调用了func1(),并且func1()中调用了func2()。
三个函数的执行过程:main()先执行,执行到一半时调用func1(),会转向执行func1()中的代码,与main()一样,func1()执行一半时会转向执行func2()中的代码;当func2()中的代码执行结束的时候,会返回到func1()中继续执行之前还没执行的代码,直到func1()的代码执行结束后,又会继续执行main()中的代码。
如果在main()中用for循环把func1()包起来,则当上面的过程结束后,会开始下一次循环,重复上面的过程。
递归也就是函数调用自身,过程和上面的调用过程一样,可以照着慢慢理解。
简单化的背包问题:
有一个最多装8kg的背包,现有4个物品,每个物品至多装1次,问能否刚好装满8kg?
用一个数组来保存这4个物品,然后挨个尝试将物品装进背包使满足条件。
过程如图所示:
不难从图中发现有后进先出的特点,自然而然就会想到使用递归或栈,得出伪代码:
用数组weight来保存每个物体的重量,一共有n个物体,背包能背m kg
sum=0; //记录已经装入的重量
bagTest(int currentIndex){
if(sum==m){
//表示能刚好装满
return;
}
for(int i=currentIndex;i<n;i++){
if(sum+weight[i]>m){
//表示装入当前的物品会产生溢出,尝试装入下一个物品
continue;
}
// 装入当前的物品,并继续尝试装入物品
sum+=weight[i];
bagTest(current+1)
}
}
通过上面的代码可以尝试完所有的装入情形。
回到最初的问题——图的m着色问题
图中有n个顶点,要给这n个顶点着色,且要满足相邻的顶点的颜色不同,问有m种颜色能否满足条件?
其实,解题思路和上面的一样, 现在我们根据上面的思路尝试写出伪代码:
coloring(当前颜色curColor,当前着色顶点curNode){
if(curNode>=n){
//表示已经着色完所有顶点
return;
}
for(int i=curColor;i<m;i++){
if(能给当前顶点着色){
coloring(curColor+1,curNode+1)
}
}
}
两个代码的形式都是一样的,只是一些判断需要根据不同问题进行调整而已,都是不断尝试的过程,如果发现不能实现目标时,则回退重新选择新的对象进行尝试。
代码部分:
/**
*
*********************
* @Title: coloring
* @Description: TODO(Coloring.Output all possible schemes.)
*
* @param paraNumColors The number of colors.
*********************
*
*/
public void coloring(int paraNumColors) {
// Step 1.Initialize.
int tempNumNodes = connectivityMatrix.getRows();
int[] tempColorScheme = new int[tempNumNodes];
Arrays.fill(tempColorScheme, -1);
coloring(paraNumColors, 0, tempColorScheme);
}// Of coloring
/**
*
*********************
* @Title: coloring
* @Description: TODO(Coloring.Output all possible schemes.)
*
* @param paraNumColors The number of colors.
* @param paraCurrentNumNodes The number of nodes that have been colored.
* @param paraCurrentColoring The array recording the coloring scheme.
*********************
*
*/
public void coloring(int paraNumColors, int paraCurrentNumNodes, int[] paraCurrentColoring) {
// Step 1.Initialize.
int tempNumNodes = connectivityMatrix.getRows();
System.out.println("coloring: paraNumColors = " + paraNumColors + ", paraCurrentNumNodes = "
+ paraCurrentNumNodes + ", paraCurrentColoring" + Arrays.toString(paraCurrentColoring));
// A complete scheme.
if (paraCurrentNumNodes >= tempNumNodes) {
System.out.println("Find one:" + Arrays.toString(paraCurrentColoring));
return;
} // Of if
for (int i = 0; i < paraNumColors; i++) {
paraCurrentColoring[paraCurrentNumNodes] = i;
if (!colorConflict(paraCurrentNumNodes + 1, paraCurrentColoring)) {
coloring(paraNumColors, paraCurrentNumNodes + 1, paraCurrentColoring);
}
} // Of for i
}// Of coloring
/**
*
*********************
* @Title: colorConflict
* @Description: TODO(Coloring conflict or not.Only compare the current last
* node with previous ones.)
*
* @param paraCurrentNumNodes The current number of nodes.
* @param paraColoring The current scheme.
* @return Conflict or not.
*********************
*
*/
public boolean colorConflict(int paraCurrentNumNodes, int[] paraColoring) {
for (int i = 0; i < paraCurrentNumNodes - 1; i++) {
if (connectivityMatrix.getValue(paraCurrentNumNodes - 1, i) == 0) {
continue;
} // Of if
if (paraColoring[paraCurrentNumNodes - 1] == paraColoring[i]) {
return true;
} // Of if
} // Of for i
return false;
}// Of colorConflict
/**
*
*********************
* @Title: coloringTest
* @Description: TODO(Coloring test)
*
*********************
*
*/
public static void coloringTest() {
int[][] tempMatrix = { { 0, 1, 1, 0 }, { 1, 0, 0, 1 }, { 1, 0, 0, 0 }, { 0, 1, 0, 0 } };
Graph tempGraph = new Graph(tempMatrix);
// tempGraph.coloring(2);
tempGraph.coloring(3);
}// Of coloringTest
/**
*
*********************
* @Title: main
* @Description: TODO(The entrance of the program)
*
* @param args Not used now.
*********************
*
*/
public static void main(String args[]) {
System.out.println("Hello!");
Graph tempGraph = new Graph(3);
System.out.println(tempGraph);
// Unit test.
// getConnectivityTest();
// breadthFirstTraverseTest();
// depthFirstTraverseTest();
coloringTest();
}// Of main
运行结果: