C++作業:將左右孩子互換 / 複製一棵二叉樹
阿新 • • 發佈:2019-01-07
/* 邵發, 1309班, */ /* 12周作業 練習1:編寫遞迴演算法、將左右孩子互換 (用遞迴) 練習2:編寫複製一棵二叉樹 (不用遞迴) */ #include <stdio.h> // 定義節點 struct Node { int value; Node* left, *right; }; // 練習1:交換左右孩子節點 void SwapChildren(Node* tree) { if(!tree) return; Node* t = tree->left; tree->left = tree->right; tree->right = t; SwapChildren(tree->left); SwapChildren(tree->right); } // 練習2:複製一棵二叉樹 // 遞迴版本 // 也可以把引用改成**,不過可讀性會差一些 void Copy_r(Node* oldtree, Node* &newtree) { // 空節點 if(oldtree == NULL) { newtree = NULL; } else { // 附加節點 newtree = new Node(); // 拷貝節點的值 newtree->value = oldtree->value; // 遞迴拷貝子節點 Copy_r(oldtree->left, newtree->left); Copy_r(oldtree->right,newtree->right); } } // 非遞迴版本 (直接由遞迴版本改造, 由自定義棧替換遞迴邏輯) void Copy_nr(Node* oldtree, Node** newtree) { Node* stack_old[256]; Node** stack_new[256]; // 注意這裡存放的是** int top = 0; // 頂點位置,同時也是棧的元素個數 // 推入根節點 stack_old[top] = oldtree; stack_new[top] = newtree; top ++; while(top > 0) { // 取節點複製 top--; // 先減再取
Node** pNew = stack_new[top]; Node* pOld = stack_old[top]; //top --; // 複製, 跟前面copy_r實際上相同 // 使用引用來去掉一個*,否則可讀性欠佳 Node*& p = *pNew; if(pOld == NULL) { p = NULL; } else { // 複製本節點 p = new Node(); p->value = pOld->value; // 再複製子節點, 相當於遞迴呼叫 stack_new[top] = & (p->left); stack_old[top] = pOld->left; top ++; stack_new[top] = & (p->right); stack_old[top] = pOld->right; top ++; } } }