有了二叉樹的前序和中序或者中序和後序遍歷序列就可以利用這些信息來重構一棵二叉樹了,這是編程之美3.9裏面的一個題目。
java實現中遇到的難點:
java的值傳遞機制
當一個對象被當作參數傳遞到一個方法後,此方法可改變這個對象的屬性,並可返回變化後的結果,那麼這裏到底是值傳遞還是引用傳遞?
答:是值傳遞。Java 編程語言只有值傳遞參數。當一個對象實例作爲一個參數被傳遞到方法中時,參數的值就是該對象的引用一個副本。指向同一個對象,對象的內容可以在被調用的方法中改變,但對象的引用(不是引用的副本)是永遠不會改變的。
Java參數,不管是原始類型還是引用類型,傳遞的都是副本(有另外一種說法是傳值,但是說傳副本更好理解吧,傳值通常是相對傳址而言)。
本問題書中的返回值是void,但是由於書中是c++代碼,而java又有值傳遞機制,所以返回值改爲TreeNode39,尤其需要注意,第44行和第48行的左右子樹重新賦值操作。函數執行完畢在最後返回proot。
public class Test_3_9 {
/**
* @param args
*/
public static void main(String[] args) {
String preorder = "abdcef";
String inorder = "dbaecf";
int len = preorder.length();
TreeNode39 proot =null;
inorder(ReBuild(preorder,inorder,len,proot));
}
//根據中序和前序序列,重建二叉樹
public static TreeNode39 ReBuild(String preorder,String inorder,int len,TreeNode39 proot){
if(preorder==null||inorder==null)return null;
TreeNode39 temp = new TreeNode39();
temp.setValue(preorder.charAt(0));
temp.setLeft(null);
temp.setRight(null);
if(proot == null)proot =temp;
if(len ==1){
return proot;
}
//尋找子樹長度
//int templen =0;
int i =0;
while(preorder.charAt(0)!=inorder.charAt(i)){
i++;
if(i>=len)break;
}
//左子樹長度
int leftlen=i;
//右子樹長度
int rightlen = len -leftlen-1;
//重建左子樹
if(leftlen>0){
//java的值傳遞機制,此時要重新給proot.left賦值,
proot.setLeft(ReBuild(preorder.substring(1),inorder,leftlen,proot.getLeft()));
}
//重建右子樹
if(rightlen>0){
proot.setRight(ReBuild(preorder.substring(leftlen+1),inorder.substring(leftlen+1),rightlen,proot.getRight()));
}
return proot;
}
//中序遍歷
public static void inorder(TreeNode39 root){
if(root!=null){
inorder(root.getLeft());
System.out.println(root.getValue());
inorder(root.getRight());
}
}
}
class TreeNode39{
private TreeNode39 left;
private TreeNode39 right;
private char value;
public TreeNode39 getLeft() {
return left;
}
public void setLeft(TreeNode39 left) {
this.left = left;
}
public TreeNode39 getRight() {
return right;
}
public void setRight(TreeNode39 right) {
this.right = right;
}
public char getValue() {
return value;
}
public void setValue(char value) {
this.value = value;
}
}