码迷,mamicode.com
首页 > 其他好文 > 详细

树与二叉树

时间:2017-12-16 14:49:01      阅读:101      评论:0      收藏:0      [点我收藏+]

标签:查找二叉树   遍历   二分   n+1   end   closed   str   pac   查找   

一 树的基本术语

  (1) 结点、叶子、父结点、子结点、祖父结点、兄弟结点、子孙结点

  (2) 结点的度:结点拥有的子树的数量

  (3) 树的度:树中结点最大的树

  (4) 树的高度:树中结点的最大层次

二 二叉树的性质

  (1) 二叉树第i层上的结点数目最多为 2{i-1} (i≥1)

  (2) 深度为k的二叉树至多有2{k}-1个结点(k≥1)

  (3)  包含n个结点的二叉树的高度至少为log2 (n+1)

  (4) 在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0=n2+1

三 二叉树类别

  (1) 满二叉树

  (2) 完全二叉树

  (3) 查找二叉树

  (4) 平衡二叉树

四 查找二叉树的C++代码实现

技术分享图片
  1 /*
  2 *    二分查找树
  3 */
  4 #pragma once
  5 #include <iostream>
  6 using namespace std;
  7 
  8 typedef int Type;
  9 
 10 typedef struct BSTreeNode{ 
 11     Type   key;                                // 关键字(键值)
 12     struct BSTreeNode *left;        // 左孩子
 13     struct BSTreeNode *right;        // 右孩子
 14     struct BSTreeNode *parent;    // 父结点
 15 
 16     BSTreeNode()
 17     {
 18         left = NULL;
 19         right = NULL;
 20         parent = NULL;
 21         key = -1;
 22     }
 23     BSTreeNode(Type keyval)
 24     {
 25         left = NULL;
 26         right = NULL;
 27         parent = NULL;
 28         key = keyval;
 29     }
 30 
 31 }Node;
 32 
 33 class BSTree
 34 {
 35 public:
 36     BSTree();
 37     ~BSTree();
 38 
 39     // 将结点插入到二叉树中,并返回根节点
 40     Node* insert_bstree(Type key);
 41     // 前序遍历"二叉树" 中左右
 42     void preorder_bstree(Node* tree);
 43     // 中序遍历"二叉树" 左中右
 44     void inorder_bstree(Node* tree);
 45     // 后序遍历"二叉树" 左右中
 46     void postorder_bstree(Node* tree);
 47     // 递归查找指定结点
 48     Node* bstree_search(Node* tree, Type key);
 49     // 非递归查找
 50     Node* iterative_bstree_search(Node* tree, Type key);
 51     // 找结点(x)的后继结点。即,查找"二叉树中数据值大于该结点"的"最小结点"。
 52     Node* bstree_successor(Node *tree);
 53     // 删除结点(key为节点的值),并返回根节点
 54     Node* delete_bstree(Node* tree, Type key);
 55     // 查找最大值并返回该结点
 56     Node* bstree_maximum(Node*  tree);
 57     // 查找最小值并返回该结点
 58     Node* bstree_minimum(Node* tree);
 59     // 销毁二叉树
 60     void destroy_bstree(Node* tree);
 61 
 62 private:
 63     Node* m_pTree; 
 64 };
 65 
 66 
 67 BSTree::BSTree()
 68 {
 69     m_pTree = NULL;
 70 }
 71 
 72 
 73 BSTree::~BSTree()
 74 {
 75     if (m_pTree)
 76     {
 77         destroy_bstree(m_pTree);
 78         m_pTree = NULL;
 79     }
 80     
 81 }
 82 
 83 // 将结点插入到二叉树中,并返回根节点
 84 Node* BSTree::insert_bstree(Type key)
 85 {
 86     Node *pNode = new Node(key);
 87     if (NULL == m_pTree) 
 88     {
 89         m_pTree = pNode;
 90     }
 91 
 92     else
 93     {
 94         Node *pTemp = m_pTree;
 95         Node *pNodePrev = NULL;
 96         while(pTemp)
 97         {
 98             pNodePrev = pTemp;
 99             if (key < pTemp->key)
100             {
101                 pTemp = pTemp->left;
102             }
103             else
104             {
105                 pTemp = pTemp->right;
106             }
107         }
108 
109         pNode->parent = pNodePrev;
110         if (pNodePrev == NULL)
111         {
112             m_pTree = pNode;
113         }
114         else
115         {
116             if (key > pNodePrev->key)
117             {
118                 pNodePrev->right = pNode;
119             }
120             else
121             {
122                 pNodePrev->left = pNode;
123             }
124         }
125         
126     }
127 
128     return m_pTree;
129 }
130 
131 void BSTree::preorder_bstree(Node* tree)
132 {
133     if (NULL == tree) return;
134     Node *pTemp = tree;
135     
136     if (pTemp) cout << pTemp->key << endl;
137     if (pTemp->left) preorder_bstree(pTemp->left);
138     if (pTemp->right) preorder_bstree(pTemp->right);
139 }
140 
141 void BSTree::inorder_bstree(Node* tree)
142 {
143     if (NULL == tree) return;
144     Node *pTemp = tree;
145 
146     if (pTemp->left) inorder_bstree(pTemp->left);
147     if (pTemp) cout << pTemp->key << endl;
148     if (pTemp->right) inorder_bstree(pTemp->right);
149 }
150 
151 void BSTree::postorder_bstree(Node* tree)
152 {
153     if (NULL == tree) return;
154     Node *pTemp = tree;
155 
156     if (pTemp->left) postorder_bstree(pTemp->left);
157     if (pTemp->right) postorder_bstree(pTemp->right);
158     if (pTemp) cout << pTemp->key << endl;
159 }
160 
161 // (递归实现)查找"二叉树x"中键值为key的节点
162 Node* BSTree::bstree_search(Node* tree, Type key)
163 {
164     if (NULL == tree || tree->key == key)
165     {
166         return tree;
167     }
168     if (key > tree->key)
169     {
170         return bstree_search(tree->right, key);
171     }
172     else
173     {
174         return bstree_search(tree->left, key);
175     }
176 }
177 
178 // (非递归实现)查找"二叉树x"中键值为key的节点
179 Node* BSTree::iterative_bstree_search(Node* tree, Type key)
180 {
181     if (NULL == tree) return NULL;
182     
183     Node *pNode = tree;
184     while(pNode && (key != pNode->key))
185     {
186         if (key > pNode->key)
187         {
188             pNode = pNode->right;
189         }
190         else 
191         {
192             pNode = pNode->left;
193         }
194     }
195 
196     return pNode;
197 }
198 
199 Node* BSTree::bstree_maximum( Node* tree )
200 {
201     if (tree == NULL) return NULL;
202     
203     Node* pNode = tree;
204     while (pNode && pNode->right)
205     {
206         pNode = pNode->right;
207     }
208 
209     return pNode;
210 }
211 
212 Node* BSTree::bstree_minimum( Node* tree )
213 {
214     if (tree == NULL) return NULL;
215 
216     Node* pNode = tree;
217     while (pNode && pNode->left)
218     {
219         pNode = pNode->left;
220     }
221 
222     return pNode;
223 }
224 
225 // 该函数调用的前提是该结点既有左子树又有右子树
226 // 找到结点的后继结点即该结点右树上的最小结点
227 Node* BSTree::bstree_successor( Node *tree )
228 {
229     if (tree == NULL || tree->right == NULL) return NULL;
230     
231     return bstree_minimum(tree->right);
232 }
233 
234 /*删除单个结点思路
235 若要删除一个BST的一个结点,需要考虑如下三种情况:
236 1.需要删除的节点下并没有其他子节点
237 2.需要删除的节点下有一个子节点(左或右)
238 3.需要删除的节点下有两个子节点(既左右节点都存在)
239 
240 对这三种情况分别采取的措施是:
241 1.直接删除此结点
242 2.删除此结点,将此结点父节点连接到此结点左(右)子树
243 3.找出此结点右子树中的最小结点,用以代替要删除的结点,然后删除此最小结点*/
244 Node* BSTree::delete_bstree( Node* tree, Type key )
245 {
246     // 根据key找到当前结点
247     Node* pCurNode = bstree_search(tree, key);
248     Node *pSuccessorNode=NULL;
249 
250     if ((pCurNode->left == NULL) || (pCurNode->right == NULL) )
251         pSuccessorNode = pCurNode;
252     else
253         pSuccessorNode = bstree_successor(pCurNode);
254 
255     // 判断后继结点是否含有子结点,若有则将子结点的父结点设为它的父节点
256     Node *pTempNode = (pSuccessorNode->left) ? pSuccessorNode->left : pSuccessorNode->right;
257     if (pTempNode != NULL)
258         pTempNode->parent = pSuccessorNode->parent;
259     if (pSuccessorNode->parent == NULL)
260         tree = pTempNode;
261     else if (pSuccessorNode == pSuccessorNode->parent->left) 
262         pSuccessorNode->parent->left = pTempNode;
263     else
264         pSuccessorNode->parent->right = pTempNode;
265 
266     if (pSuccessorNode != pCurNode) 
267         pCurNode->key = pSuccessorNode->key;
268 
269     if (pSuccessorNode!=NULL)
270         delete pSuccessorNode;
271         pSuccessorNode = NULL;
272 
273     return tree;
274 }
275 
276 void BSTree::destroy_bstree( Node* tree )
277 {
278     if (tree==NULL)
279         return ;
280 
281     if (tree->left != NULL)
282         destroy_bstree(tree->left);
283     if (tree->right != NULL)
284         destroy_bstree(tree->right);
285 
286     delete tree;
287     tree = NULL;
288 }
289 
290         
View Code

  测试代码

技术分享图片
#include "stdio.h"
#include "binarysearchTree.h"

#include <iostream>
using namespace std;

int main(void)
{
    BSTree *tree = new BSTree();
    tree->insert_bstree(5);
    tree->insert_bstree(2);
    tree->insert_bstree(3);
    tree->insert_bstree(1);
    tree->insert_bstree(4);
    tree->insert_bstree(8);
    tree->insert_bstree(6);
    Node *pNode = tree->insert_bstree(9);

    // 中序遍历打印节点
    tree->inorder_bstree(pNode);
    Node *pDelNode = tree->delete_bstree(pNode, 8);
    tree->inorder_bstree(pDelNode);
    return 0;
}
View Code

 

  

树与二叉树

标签:查找二叉树   遍历   二分   n+1   end   closed   str   pac   查找   

原文地址:http://www.cnblogs.com/xiaobingqianrui/p/8023960.html

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