單結點刪除
描述:編寫一個函數用於刪除二叉樹中的全部單度結點
要求:結點刪除後,其惟一的子結點替代它的位置
定義功能:delOdd1(node)node
- 刪除 node 爲根結點的二叉樹中的單度結點
#include <iostream> #include "BTreeNode.h" using namespace std; using namespace DTLib; template < typename T > BTreeNode<T>* createTree() { static BTreeNode<int> ns[9]; for(int i=0; i<9; i++) { ns[i].value = i; ns[i].parent = NULL; ns[i].left = NULL; ns[i].right = NULL; } ns[0].left = &ns[1]; ns[0].right = &ns[2]; ns[1].parent = &ns[0]; ns[2].parent = &ns[0]; ns[1].left = &ns[3]; ns[1].right = NULL; ns[3].parent = &ns[1]; ns[2].left = &ns[4]; ns[2].right = &ns[5]; ns[4].parent = &ns[2]; ns[5].parent = &ns[2]; ns[3].left = NULL; ns[3].right = &ns[6]; ns[6].parent = &ns[3]; ns[4].left = &ns[7]; ns[4].right = NULL; ns[7].parent = &ns[4]; ns[5].left = &ns[8]; ns[5].right = NULL; ns[8].parent = &ns[5]; return ns; } template < typename T > void printInOrder(BTreeNode<T>* node) { if( node != NULL ) { printInOrder(node->left); cout << node->value <<" "; printInOrder(node->right); } } template < typename T > void printDualList(BTreeNode<T>* node) { BTreeNode<T>* g = node; cout << "head -> tail: " << endl; while( node != NULL ) { cout << node->value << " "; g = node; node = node->right; } cout << endl; cout << "tail -> head: " << endl; while( g != NULL ) { cout << g->value << " "; g = g->left; } cout << endl; } //---------------------------------------------------------------------- template <typename T> BTreeNode<T>* delOdd1(BTreeNode<T> *node) { BTreeNode<T> *ret = nullptr; if (node != nullptr) { if (((node->left != nullptr) && (node->right == nullptr)) || ((node->left == nullptr) && (node->right != nullptr))) { BTreeNode<T> *parent = dynamic_cast<BTreeNode<T>*>(node->parent); BTreeNode<T> *child = (node->left != nullptr) ? node->left : node->right; if (parent != nullptr) { BTreeNode<T> *& parent_child = (parent->left == node) ? parent->left : parent->right; parent_child = child; child->parent = parent; } else { child->parent = nullptr; } if (node->flag()) { delete node; } ret = delOdd1(child); } else { delOdd1(node->left); delOdd1(node->right); ret = node; } } return ret; } int main() { BTreeNode<int>* ns = createTree<int>(); printInOrder(ns); cout << endl; ns = delOdd1(ns); printInOrder(ns); return 0; }
輸出:ios
3 6 1 0 7 4 2 8 5 6 0 7 2 8
定義功能: delOdd2(node)面試
- 刪除 node 爲根結點的二叉樹中的單度結點
#include <iostream> #include "BTreeNode.h" using namespace std; using namespace DTLib; template < typename T > BTreeNode<T>* createTree() { static BTreeNode<int> ns[9]; for(int i=0; i<9; i++) { ns[i].value = i; ns[i].parent = NULL; ns[i].left = NULL; ns[i].right = NULL; } ns[0].left = &ns[1]; ns[0].right = &ns[2]; ns[1].parent = &ns[0]; ns[2].parent = &ns[0]; ns[1].left = &ns[3]; ns[1].right = NULL; ns[3].parent = &ns[1]; ns[2].left = &ns[4]; ns[2].right = &ns[5]; ns[4].parent = &ns[2]; ns[5].parent = &ns[2]; ns[3].left = NULL; ns[3].right = &ns[6]; ns[6].parent = &ns[3]; ns[4].left = &ns[7]; ns[4].right = NULL; ns[7].parent = &ns[4]; ns[5].left = &ns[8]; ns[5].right = NULL; ns[8].parent = &ns[5]; return ns; } template < typename T > void printInOrder(BTreeNode<T>* node) { if( node != NULL ) { printInOrder(node->left); cout << node->value <<" "; printInOrder(node->right); } } template < typename T > void printDualList(BTreeNode<T>* node) { BTreeNode<T>* g = node; cout << "head -> tail: " << endl; while( node != NULL ) { cout << node->value << " "; g = node; node = node->right; } cout << endl; cout << "tail -> head: " << endl; while( g != NULL ) { cout << g->value << " "; g = g->left; } cout << endl; } //---------------------------------------------------------------------- template <typename T> void delOdd2(BTreeNode<T> *&node) { if (node != nullptr) { if (((node->left != nullptr) && (node->right == nullptr)) || ((node->left == nullptr) && (node->right != nullptr))) { if (node->flag()) { delete node; } node = (node->left != nullptr) ? node->left : node->right; delOdd2(node); } else { delOdd2(node->left); delOdd2(node->right); } } } int main() { BTreeNode<int>* ns = createTree<int>(); printInOrder(ns); cout << endl; delOdd2(ns); printInOrder(ns); return 0; }
輸出:編程
3 6 1 0 7 4 2 8 5 6 0 7 2 8
中序線索化二叉樹
描述:編寫一個函數用於中序線索化二叉樹
要求:不容許使用其餘數據結構
- 使用輔助指針,在中序遍歷時指向當前結點的前驅結點
- 訪問當前結點時,鏈接與前驅結點的前後次序
inOrderThread(node, pre)數據結構
- node : 根結點,也是中序訪問的結點
- pre: 爲中序遍歷時的前驅結點指針
#include <iostream> #include "BTreeNode.h" using namespace std; using namespace DTLib; template < typename T > BTreeNode<T>* createTree() { static BTreeNode<int> ns[9]; for(int i=0; i<9; i++) { ns[i].value = i; ns[i].parent = NULL; ns[i].left = NULL; ns[i].right = NULL; } ns[0].left = &ns[1]; ns[0].right = &ns[2]; ns[1].parent = &ns[0]; ns[2].parent = &ns[0]; ns[1].left = &ns[3]; ns[1].right = NULL; ns[3].parent = &ns[1]; ns[2].left = &ns[4]; ns[2].right = &ns[5]; ns[4].parent = &ns[2]; ns[5].parent = &ns[2]; ns[3].left = NULL; ns[3].right = &ns[6]; ns[6].parent = &ns[3]; ns[4].left = &ns[7]; ns[4].right = NULL; ns[7].parent = &ns[4]; ns[5].left = &ns[8]; ns[5].right = NULL; ns[8].parent = &ns[5]; return ns; } template < typename T > void printInOrder(BTreeNode<T>* node) { if( node != NULL ) { printInOrder(node->left); cout << node->value <<" "; printInOrder(node->right); } } template < typename T > void printDualList(BTreeNode<T>* node) { BTreeNode<T>* g = node; cout << "head -> tail: " << endl; while( node != NULL ) { cout << node->value << " "; g = node; node = node->right; } cout << endl; cout << "tail -> head: " << endl; while( g != NULL ) { cout << g->value << " "; g = g->left; } cout << endl; } template <typename T> void inOrderThread(BTreeNode<T> *node, BTreeNode<T> *&pre) { if (node != nullptr) { inOrderThread(node->left, pre); node->left = pre; if (pre != nullptr) { pre->right = node; } pre = node; inOrderThread(node->right, pre); } } template <typename T> BTreeNode<T> *inOrderThread(BTreeNode<T> *node) { BTreeNode<T> * pre = nullptr; inOrderThread(node, pre); while ((node != nullptr) && (node->left != nullptr)) { node = node->left; } return node; } int main() { BTreeNode<int>* ns = createTree<int>(); printInOrder(ns); cout << endl; ns = inOrderThread(ns); printDualList(ns); return 0; }
輸出:函數
3 6 1 0 7 4 2 8 5 head -> tail: 3 6 1 0 7 4 2 8 5 tail -> head: 5 8 2 4 7 0 1 6 3
- 使用輔助指針,指向轉換後雙向鏈表的頭結點和尾結點
- 根結點與左右子樹轉換的雙向鏈表鏈接,成爲完整雙向鏈表
inOrderThread(node, head, tail)spa
- node: 根結點,也是中序訪問的結點
- head: 轉換成功後指向雙向鏈表的首結點
- tail:轉換成功後指向雙向鏈表的尾結點
#include <iostream> #include "BTreeNode.h" using namespace std; using namespace DTLib; template < typename T > BTreeNode<T>* createTree() { static BTreeNode<int> ns[9]; for(int i=0; i<9; i++) { ns[i].value = i; ns[i].parent = NULL; ns[i].left = NULL; ns[i].right = NULL; } ns[0].left = &ns[1]; ns[0].right = &ns[2]; ns[1].parent = &ns[0]; ns[2].parent = &ns[0]; ns[1].left = &ns[3]; ns[1].right = NULL; ns[3].parent = &ns[1]; ns[2].left = &ns[4]; ns[2].right = &ns[5]; ns[4].parent = &ns[2]; ns[5].parent = &ns[2]; ns[3].left = NULL; ns[3].right = &ns[6]; ns[6].parent = &ns[3]; ns[4].left = &ns[7]; ns[4].right = NULL; ns[7].parent = &ns[4]; ns[5].left = &ns[8]; ns[5].right = NULL; ns[8].parent = &ns[5]; return ns; } template < typename T > void printInOrder(BTreeNode<T>* node) { if( node != NULL ) { printInOrder(node->left); cout << node->value <<" "; printInOrder(node->right); } } template < typename T > void printDualList(BTreeNode<T>* node) { BTreeNode<T>* g = node; cout << "head -> tail: " << endl; while( node != NULL ) { cout << node->value << " "; g = node; node = node->right; } cout << endl; cout << "tail -> head: " << endl; while( g != NULL ) { cout << g->value << " "; g = g->left; } cout << endl; } template <typename T> void inOrderThread2(BTreeNode<T> *node, BTreeNode<T> *& head, BTreeNode<T> *&tail) { if (node != nullptr) { BTreeNode<T> *h = nullptr; BTreeNode<T> *t = nullptr; inOrderThread2(node->left, h, t); node->left = t; if (t != nullptr) { t->right = node; } head = (h != nullptr) ? h : node; h = nullptr; t = nullptr; inOrderThread2(node->right, h, t); node->right = h; if (h != nullptr) { h->left = node; } tail = (t != nullptr) ? t : node; } } template <typename T> BTreeNode<T> *inOrderThread2(BTreeNode<T> *node) { BTreeNode<T> *head = nullptr; BTreeNode<T> *tail = nullptr; inOrderThread2(node, head, tail); return head; } int main() { BTreeNode<int>* ns = createTree<int>(); printInOrder(ns); cout << endl; ns = inOrderThread2(ns); printDualList(ns); return 0; }
輸出:指針
3 6 1 0 7 4 2 8 5 head -> tail: 3 6 1 0 7 4 2 8 5 tail -> head: 5 8 2 4 7 0 1 6 3
以上內容整理於狄泰軟件學院系列課程,請你們保護原創!code