码迷,mamicode.com
首页 > 编程语言 > 详细

c++二叉树

时间:2017-10-17 18:45:45      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:返回   inno   share   删除   max   res   个数   str   左右子树   

技术分享
 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;
15     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
tree.h

 

 

技术分享
  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++二叉树

标签:返回   inno   share   删除   max   res   个数   str   左右子树   

原文地址:http://www.cnblogs.com/endenvor/p/7682733.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!