第七十课 二叉树经典面试题分析

Posted wanmeishenghuo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第七十课 二叉树经典面试题分析相关的知识,希望对你有一定的参考价值。

技术分享图片

 

技术分享图片

 

技术分享图片

 

删除结点1之后,下一个删除的就是3了。

程序:

  1 #include <iostream>
  2 #include "BTreeNode.h"
  3 
  4 using namespace std;
  5 using namespace DTLib;
  6 
  7 template < typename T >
  8 BTreeNode<T>* createTree()
  9 {
 10     static BTreeNode<int> ns[9];
 11 
 12     for(int i=0; i<9; i++)
 13     {
 14         ns[i].value = i;
 15         ns[i].parent = NULL;
 16         ns[i].left = NULL;
 17         ns[i].right = NULL;
 18     }
 19 
 20     ns[0].left = &ns[1];
 21     ns[0].right = &ns[2];
 22     ns[1].parent = &ns[0];
 23     ns[2].parent = &ns[0];
 24 
 25     ns[1].left = &ns[3];
 26     ns[1].right = NULL;
 27     ns[3].parent = &ns[1];
 28 
 29     ns[2].left = &ns[4];
 30     ns[2].right = &ns[5];
 31     ns[4].parent = &ns[2];
 32     ns[5].parent = &ns[2];
 33 
 34     ns[3].left = NULL;
 35     ns[3].right = &ns[6];
 36     ns[6].parent = &ns[3];
 37 
 38     ns[4].left = &ns[7];
 39     ns[4].right = NULL;
 40     ns[7].parent = &ns[4];
 41 
 42     ns[5].left = &ns[8];
 43     ns[5].right = NULL;
 44     ns[8].parent = &ns[5];
 45 
 46     return ns;
 47 }
 48 
 49 template < typename T >
 50 void printInOrder(BTreeNode<T>* node)
 51 {
 52     if( node != NULL )
 53     {
 54         printInOrder(node->left);
 55 
 56         cout << node->value <<" ";
 57 
 58         printInOrder(node->right);
 59     }
 60 }
 61 
 62 template < typename T >
 63 void printDualList(BTreeNode<T>* node)
 64 {
 65     BTreeNode<T>* g = node;
 66 
 67     cout << "head -> tail: " << endl;
 68 
 69     while( node != NULL )
 70     {
 71         cout << node->value << " ";
 72 
 73         g = node;
 74 
 75         node = node->right;
 76     }
 77 
 78     cout << endl;
 79 
 80     cout << "tail -> head: " << endl;
 81 
 82     while( g != NULL )
 83     {
 84         cout << g->value << " ";
 85 
 86         g = g->left;
 87     }
 88 
 89     cout << endl;
 90 }
 91 
 92 template < typename T>
 93 BTreeNode<T>* delOdd1(BTreeNode<T>* node)
 94 {
 95     BTreeNode<T>* ret = NULL;
 96 
 97     if( node != NULL )
 98     {
 99         if( ((node->left != NULL) && (node->right == NULL))  ||
100             ((node->left == NULL) && (node->right != NULL)) )
101         {
102             BTreeNode<T>* parent = dynamic_cast<BTreeNode<T>*>(node->parent);
103             BTreeNode<T>* node_child = (node->left != NULL) ? node->left : node->right;
104 
105             if( parent != NULL )  //根节点有可能是单度的
106             {
107                 BTreeNode<T>*& parent_child = (parent->left == node) ? parent->left : parent->right;
108 
109                 parent_child = node_child;
110                 node_child->parent = parent;
111             }
112             else
113             {
114                 node_child->parent = NULL;
115             }
116 
117             if( node->flag() )
118             {
119                 delete node;
120             }
121 
122             ret = delOdd1(node_child);
123         }
124         else
125         {
126             delOdd1(node->left);
127             delOdd1(node->right);
128 
129             ret = node;
130         }
131     }
132 
133     return ret;
134 }
135 
136 int main()
137 {
138     BTreeNode<int>* ns = createTree<int>();
139 
140     printInOrder(ns);
141 
142     cout << endl;
143 
144     ns = delOdd1(ns);
145 
146     printInOrder(ns);
147 
148     cout << endl;
149 
150     int a[] = {6, 7, 8};
151 
152     for(int i = 0; i < 3; i++)
153     {
154         TreeNode<int>* n = ns + a[i];
155 
156         while( n != NULL )
157         {
158             cout << n->value << " ";
159 
160             n = n->parent;
161         }
162 
163         cout << endl;
164     }
165 
166     cout << endl;
167 
168     return 0;
169 }

结果如下:

技术分享图片

 

 

技术分享图片

 

技术分享图片

 

第一个要删除的结点是1,node是一个引用,指向1这个结点,也就是0结点中的孩子指针的引用,node = node->child执行完之后,0结点里面的孩子指针就指向了3,也就是node这个指针指向了3,这个node此时还是0结点中的孩子指针的引用。

树结点没有父节点的情况,删除单度结点的程序如下:

  1 #include <iostream>
  2 #include "BTreeNode.h"
  3 
  4 using namespace std;
  5 using namespace DTLib;
  6 
  7 template < typename T >
  8 BTreeNode<T>* createTree()
  9 {
 10     static BTreeNode<int> ns[9];
 11 
 12     for(int i=0; i<9; i++)
 13     {
 14         ns[i].value = i;
 15         ns[i].parent = NULL;
 16         ns[i].left = NULL;
 17         ns[i].right = NULL;
 18     }
 19 
 20     ns[0].left = &ns[1];
 21     ns[0].right = &ns[2];
 22     ns[1].parent = &ns[0];
 23     ns[2].parent = &ns[0];
 24 
 25     ns[1].left = &ns[3];
 26     ns[1].right = NULL;
 27     ns[3].parent = &ns[1];
 28 
 29     ns[2].left = &ns[4];
 30     ns[2].right = &ns[5];
 31     ns[4].parent = &ns[2];
 32     ns[5].parent = &ns[2];
 33 
 34     ns[3].left = NULL;
 35     ns[3].right = &ns[6];
 36     ns[6].parent = &ns[3];
 37 
 38     ns[4].left = &ns[7];
 39     ns[4].right = NULL;
 40     ns[7].parent = &ns[4];
 41 
 42     ns[5].left = &ns[8];
 43     ns[5].right = NULL;
 44     ns[8].parent = &ns[5];
 45 
 46     return ns;
 47 }
 48 
 49 template < typename T >
 50 void printInOrder(BTreeNode<T>* node)
 51 {
 52     if( node != NULL )
 53     {
 54         printInOrder(node->left);
 55 
 56         cout << node->value <<" ";
 57 
 58         printInOrder(node->right);
 59     }
 60 }
 61 
 62 template < typename T >
 63 void printDualList(BTreeNode<T>* node)
 64 {
 65     BTreeNode<T>* g = node;
 66 
 67     cout << "head -> tail: " << endl;
 68 
 69     while( node != NULL )
 70     {
 71         cout << node->value << " ";
 72 
 73         g = node;
 74 
 75         node = node->right;
 76     }
 77 
 78     cout << endl;
 79 
 80     cout << "tail -> head: " << endl;
 81 
 82     while( g != NULL )
 83     {
 84         cout << g->value << " ";
 85 
 86         g = g->left;
 87     }
 88 
 89     cout << endl;
 90 }
 91 
 92 template < typename T>
 93 BTreeNode<T>* delOdd1(BTreeNode<T>* node)
 94 {
 95     BTreeNode<T>* ret = NULL;
 96 
 97     if( node != NULL )
 98     {
 99         if( ((node->left != NULL) && (node->right == NULL))  ||
100             ((node->left == NULL) && (node->right != NULL)) )
101         {
102             BTreeNode<T>* parent = dynamic_cast<BTreeNode<T>*>(node->parent);
103             BTreeNode<T>* node_child = (node->left != NULL) ? node->left : node->right;
104 
105             if( parent != NULL )  //根节点有可能是单度的
106             {
107                 BTreeNode<T>*& parent_child = (parent->left == node) ? parent->left : parent->right;
108 
109                 parent_child = node_child;
110                 node_child->parent = parent;
111             }
112             else
113             {
114                 node_child->parent = NULL;
115             }
116 
117             if( node->flag() )
118             {
119                 delete node;
120             }
121 
122             ret = delOdd1(node_child);
123         }
124         else
125         {
126             delOdd1(node->left);
127             delOdd1(node->right);
128 
129             ret = node;
130         }
131     }
132 
133     return ret;
134 }
135 
136 template < typename T>
137 void delOdd2(BTreeNode<T>*& node)
138 {
139     if( node != NULL )
140     {
141         if( ((node->left != NULL) && (node->right == NULL))  ||
142             ((node->left == NULL) && (node->right != NULL)) )
143         {
144             BTreeNode<T>* node_child = (node->left != NULL) ? node->left : node->right;
145 
146             if( node->flag() )
147             {
148                 delete node;
149             }
150 
151             node = node_child;
152 
153             delOdd2(node);
154         }
155         else
156         {
157             delOdd2(node->left);
158             delOdd2(node->right);
159         }
160     }
161 }
162 
163 int main()
164 {
165     BTreeNode<int>* ns = createTree<int>();
166 
167     printInOrder(ns);
168 
169     cout << endl;
170 
171     delOdd2(ns);
172 
173     printInOrder(ns);
174 
175     cout << endl;
176 
177     return 0;
178 }

结果如下:

技术分享图片

 

 

技术分享图片

 

技术分享图片

 

技术分享图片

 

 

程序如下:

  1 #include <iostream>
  2 #include "BTreeNode.h"
  3 
  4 using namespace std;
  5 using namespace DTLib;
  6 
  7 template < typename T >
  8 BTreeNode<T>* createTree()
  9 {
 10     static BTreeNode<int> ns[9];
 11 
 12     for(int i=0; i<9; i++)
 13     {
 14         ns[i].value = i;
 15         ns[i].parent = NULL;
 16         ns[i].left = NULL;
 17         ns[i].right = NULL;
 18     }
 19 
 20     ns[0].left = &ns[1];
 21     ns[0].right = &ns[2];
 22     ns[1].parent = &ns[0];
 23     ns[2].parent = &ns[0];
 24 
 25     ns[1].left = &ns[3];
 26     ns[1].right = NULL;
 27     ns[3].parent = &ns[1];
 28 
 29     ns[2].left = &ns[4];
 30     ns[2].right = &ns[5];
 31     ns[4].parent = &ns[2];
 32     ns[5].parent = &ns[2];
 33 
 34     ns[3].left = NULL;
 35     ns[3].right = &ns[6];
 36     ns[6].parent = &ns[3];
 37 
 38     ns[4].left = &ns[7];
 39     ns[4].right = NULL;
 40     ns[7].parent = &ns[4];
 41 
 42     ns[5].left = &ns[8];
 43     ns[5].right = NULL;
 44     ns[8].parent = &ns[5];
 45 
 46     return ns;
 47 }
 48 
 49 template < typename T >
 50 void printInOrder(BTreeNode<T>* node)
 51 {
 52     if( node != NULL )
 53     {
 54         printInOrder(node->left);
 55 
 56         cout << node->value <<" ";
 57 
 58         printInOrder(node->right);
 59     }
 60 }
 61 
 62 template < typename T >
 63 void printDualList(BTreeNode<T>* node)
 64 {
 65     BTreeNode<T>* g = node;
 66 
 67     cout << "head -> tail: " << endl;
 68 
 69     while( node != NULL )
 70     {
 71         cout << node->value << " ";
 72 
 73         g = node;
 74 
 75         node = node->right;
 76     }
 77 
 78     cout << endl;
 79 
 80     cout << "tail -> head: " << endl;
 81 
 82     while( g != NULL )
 83     {
 84         cout << g->value << " ";
 85 
 86         g = g->left;
 87     }
 88 
 89     cout << endl;
 90 }
 91 
 92 template < typename T>
 93 BTreeNode<T>* delOdd1(BTreeNode<T>* node)
 94 {
 95     BTreeNode<T>* ret = NULL;
 96 
 97     if( node != NULL )
 98     {
 99         if( ((node->left != NULL) && (node->right == NULL))  ||
100             ((node->left == NULL) && (node->right != NULL)) )
101         {
102             BTreeNode<T>* parent = dynamic_cast<BTreeNode<T>*>(node->parent);
103             BTreeNode<T>* node_child = (node->left != NULL) ? node->left : node->right;
104 
105             if( parent != NULL )  //根节点有可能是单度的
106             {
107                 BTreeNode<T>*& parent_child = (parent->left == node) ? parent->left : parent->right;
108 
109                 parent_child = node_child;
110                 node_child->parent = parent;
111             }
112             else
113             {
114                 node_child->parent = NULL;
115             }
116 
117             if( node->flag() )
118             {
119                 delete node;
120             }
121 
122             ret = delOdd1(node_child);
123         }
124         else
125         {
126             delOdd1(node->left);
127             delOdd1(node->right);
128 
129             ret = node;
130         }
131     }
132 
133     return ret;
134 }
135 
136 template < typename T>
137 void delOdd2(BTreeNode<T>*& node)
138 {
139     if( node != NULL )
140     {
141         if( ((node->left != NULL) && (node->right == NULL))  ||
142             ((node->left == NULL) && (node->right != NULL)) )
143         {
144             BTreeNode<T>* node_child = (node->left != NULL) ? node->left : node->right;
145 
146             if( node->flag() )
147             {
148                 delete node;
149             }
150 
151             node = node_child;
152 
153             delOdd2(node);
154         }
155         else
156         {
157             delOdd2(node->left);
158             delOdd2(node->right);
159         }
160     }
161 }
162 
163 template < typename T >
164 void inOrderThread(BTreeNode<T>* node, BTreeNode<T>*& pre)
165 {
166     if( node != NULL )
167     {
168         inOrderThread(node->left, pre);
169 
170         node->left = pre;
171 
172         if( pre != NULL )
173         {
174             pre->right = node;
175         }
176 
177         pre = node;
178 
179         inOrderThread(node->right, pre);
180     }
181 }
182 
183 
184 template < typename T >
185 BTreeNode<T>* inOrderThread1(BTreeNode<T>* node)
186 {
187     BTreeNode<T>* pre = NULL;
188 
189     inOrderThread(node, pre);
190 
191     while( (node != NULL) && (node->left != NULL) )
192     {
193         node = node->left;
194     }
195 
196     return node;
197 }
198 
199 int main()
200 {
201     BTreeNode<int>* ns = createTree<int>();
202 
203     printInOrder(ns);
204 
205     cout << endl;
206 
207     delOdd2(ns);
208 
209     printInOrder(ns);
210 
211     cout << endl;
212 
213     ns = inOrderThread1(ns);
214 
215     printDualList(ns);
216 
217     return 0;
218 }

结果如下:

技术分享图片

 

以上是关于第七十课 二叉树经典面试题分析的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 简单 第七十一题 二叉树的所有路径

数据结构二叉树相关面试题 Java版 LeetCode题 ------- 二叉树

经典面试题二二叉树的递归与非递归遍历(前序中序后序)

Java数据结构 二叉树经典OJ面试题——刷题笔记+解题思路

经典面试题--二叉树的最近公共祖先

经典面试题(二十三)--二叉树与双向链表