c++二叉樹
阿新 • • 發佈:2017-10-17
wall hide esp new 改變 左右 ostream 最小 ace
1 #ifndef _TREE_H_ 2 #define _TREE_H_ 3 4 //此類用shared_ptr來管理節點內存,所以要包含<memory>頭文件,不需要手動釋放內存 5 #include <memory> 6 #include <iostream> 7 8 using namespace std; 9 10 struct Node{ 11 int key; 12 shared_ptr<Node> parent; 13 shared_ptr<Node> left; 14 shared_ptr<Node> right;tree.h15 Node(int k = 0) :key(k), parent(), left(), right() {} 16 }; 17 18 19 typedef shared_ptr<Node> Pnode; 20 21 //遍歷節點 22 void showNode(Pnode current); 23 24 25 class Tree 26 { 27 private: 28 Pnode root; 29 //返回以current為根節點的所有節點個數 30 size_t __nodeSize(Pnode current) const; 31 //返回以current為根節點的葉節點(沒有左右節點)個數32 size_t __leafSize(Pnode current) const; 33 //返回以current為根節點樹的深度 34 size_t __depth(Pnode current) const; 35 //返回k值節點的地址 36 const Pnode * __getNodeAddress(int k) const; 37 //返回current節點下的最大值的節點 38 Pnode __maxNode(Pnode current) const; 39 //返回current節點下的最小值節點 40 Pnode __minNode(Pnode current) const; 41 public: 42 Tree() :root() {} 43 //將k插入樹 44 void insert(int k); 45 //刪除值為k的節點 46 void delNode(int k); 47 //判斷是否存在值為k的節點 48 bool isExist(int k); 49 //樹中節點個數 50 size_t nodeSize() const; 51 //樹中葉節點的個數 52 size_t leafSize() const; 53 //樹的深度 54 size_t depth() const; 55 //樹的寬度 56 size_t width() const; 57 //樹的最大值 58 int maxVal() const; 59 //樹的最小值 60 int minVal() const; 61 //打印所有節點 62 void showAll() const; 63 }; 64 65 #endif
1 #include "tree.h" 2 3 //求樹的寬度要用到隊列 4 #include <queue> 5 6 using namespace std; 7 8 void showNode(Pnode current) 9 { 10 if (current.get() == NULL) 11 return; 12 showNode(current->left); 13 cout << current->key << " "; 14 showNode(current->right); 15 } 16 17 void Tree::showAll() const 18 { 19 showNode(root); 20 cout << endl; 21 } 22 23 void Tree::insert(int k) 24 { 25 //智能指針shared_ptr變量的初始化方式 26 Pnode new_node(new Node(k)); 27 Pnode current = root; 28 Pnode save = root; 29 while (current) 30 { 31 save = current; 32 if (k < current->key) 33 current = current->left; 34 else current = current->right; 35 } 36 new_node->parent = save; 37 if (!save) 38 root = new_node; 39 else if (k < save->key) 40 save->left = new_node; 41 else save->right = new_node; 42 } 43 44 void Tree::delNode(int k) 45 { 46 //__getNodeAddress返回的是帶有頂層const類型的指針, 47 //後面要改變指針指向的值,所以要先解除const限制. 48 Pnode * pdel = const_cast<Pnode *>(__getNodeAddress(k)); 49 if (!pdel) 50 { 51 cout << k << " is not exist!\n"; 52 return; 53 } 54 //save保存被刪節點的父節點 55 Pnode save = (*pdel)->parent; 56 //被刪節點沒有子樹 57 if (!(*pdel)->left.get() && !(*pdel)->right.get()) 58 *pdel = NULL; 59 //被刪節點左子樹為空 60 else if (!(*pdel)->left.get()) 61 { 62 *pdel = (*pdel)->right; 63 (*pdel)->parent = save; 64 } 65 //被刪節點右子樹為空 66 else if (!(*pdel)->right.get()) 67 { 68 *pdel = (*pdel)->left; 69 (*pdel)->parent = save; 70 } 71 //被刪節點有左右子樹 72 else { 73 //successor為被刪節點的後繼 74 Pnode successor = __minNode((*pdel)->right); 75 successor->left = (*pdel)->left; 76 *pdel = (*pdel)->right; 77 (*pdel)->parent = save; 78 } 79 } 80 81 bool Tree::isExist(int k) 82 { 83 return __getNodeAddress(k) != NULL; 84 } 85 86 size_t Tree::__nodeSize(Pnode current) const 87 { 88 if (!current) 89 return 0; 90 return 1 + __nodeSize(current->left) + __nodeSize(current->right); 91 } 92 93 size_t Tree::nodeSize() const 94 { 95 return __nodeSize(root); 96 } 97 98 size_t Tree::__leafSize(Pnode current) const 99 { 100 if (current.get() == NULL) 101 return 0; 102 if (current->left.get() == NULL && current->right.get() == NULL) 103 return 1; 104 return __leafSize(current->left) + __leafSize(current->right); 105 } 106 107 size_t Tree::leafSize() const 108 { 109 return __leafSize(root); 110 } 111 112 size_t Tree::__depth(Pnode current) const 113 { 114 if (!current) 115 return 0; 116 size_t leftSize = 1 + __depth(current->left); 117 size_t rightSize = 1 + __depth(current->right); 118 return leftSize > rightSize ? leftSize: rightSize; 119 } 120 121 size_t Tree::depth() const 122 { 123 return __depth(root); 124 } 125 126 size_t Tree::width() const 127 { 128 if (!root) 129 return 0; 130 Pnode current = root; 131 int maxNode = 1; 132 int ct = 0; 133 queue<Pnode> qu; 134 qu.push(current); 135 while (qu.size() != 0) 136 { 137 ct = qu.size(); 138 for (int i = 0; i < ct; i++) 139 { 140 current = qu.front(); 141 qu.pop(); 142 if (current->left.get() != NULL) 143 qu.push(current->left); 144 if (current->right.get() != NULL) 145 qu.push(current->right); 146 } 147 maxNode = maxNode > qu.size() ? maxNode : qu.size(); 148 } 149 return maxNode; 150 } 151 152 153 //此處返回指針是考慮到方便delNode調用,內存本身的地址和內存指向的值會帶來很大困惑,要仔細品味, 154 //此前寫delNode方法從節點本身來考慮,反復建立節點關系,寫下的代碼長度大概 155 //是現在delNode長度的2倍,效率也會打折扣. 156 const Pnode * Tree::__getNodeAddress(int k) const 157 { 158 Pnode ret = root; 159 Pnode save = {}; 160 if (root->key == k) 161 return &root; 162 while (1) 163 { 164 save = ret; 165 if (k < ret->key) 166 { 167 if (!(ret = ret->left).get()) 168 break; 169 if (ret->key == k) 170 return &(save->left); 171 } 172 else { 173 if(!(ret = ret->right).get()) 174 break; 175 if (ret->key == k) 176 return &(save->right); 177 } 178 } 179 return NULL; 180 } 181 182 Pnode Tree::__maxNode(Pnode current) const 183 { 184 185 while (current->right.get() != NULL) 186 current = current->right; 187 return current; 188 } 189 190 Pnode Tree::__minNode(Pnode current) const 191 { 192 while (current->left.get() != NULL) 193 current = current->left; 194 return current; 195 } 196 197 int Tree::maxVal() const 198 { 199 if (root.get() == NULL) 200 return 0x80000000; 201 return __maxNode(root)->key; 202 } 203 204 int Tree::minVal() const 205 { 206 if (root.get() == NULL) 207 return 0x7FFFFFFF; 208 return __minNode(root)->key; 209 }tree.cpp
1 #include <iostream> 2 #include "Tree.h" 3 4 using namespace std; 5 6 void showArray(int * arr, int n); 7 void loadArrayToTree(Tree & t, int * arr, int n); 8 9 const int ASIZE = 13; 10 11 int main() 12 { 13 int arr[ASIZE] = { 54,19,18,39,76,15,80,70,25,41,83,79,71 }; 14 cout << "show array: \n"; 15 showArray(arr, ASIZE); 16 Tree t; 17 loadArrayToTree(t, arr, ASIZE); 18 cout << "show Tree: \n"; 19 t.showAll(); 20 cout << "nodeSize() = " << t.nodeSize() << endl; 21 cout << "leafSize() = " << t.leafSize() << endl; 22 cout << "depth() = " << t.depth() << endl; 23 cout << "width() = " << t.width() << endl; 24 cout << "isExist(41) = " << t.isExist(41) << endl; 25 t.delNode(41); 26 t.showAll(); 27 cout << "nodeSize() = " << t.nodeSize() << endl; 28 cout << "isExist(41) = " << t.isExist(41) << endl; 29 cout << "isExist(80) = " << t.isExist(80) << endl; 30 31 32 return 0; 33 } 34 35 void showArray(int * arr, int n) 36 { 37 for (int i = 0; i < n; i++) 38 cout << arr[i] << " "; 39 cout << endl; 40 } 41 42 void loadArrayToTree(Tree & t, int * arr, int n) 43 { 44 for (int i = 0; i < n; i++) 45 t.insert(arr[i]); 46 }treeMain.cpp測試代碼
c++二叉樹