zoukankan      html  css  js  c++  java
  • c++二叉树

     1 #ifndef _TREE_H_
     2 #define _TREE_H_
     3 //此类用shared_ptr来管理节点内存,所以要包含<memory>头文件,不需要手动释放内存
     4 #include <memory>
     5 #include <iostream>
     6 
     7 using namespace std;
     8 
     9 struct Node{
    10     int key;
    11     shared_ptr<Node> parent;
    12     shared_ptr<Node> left;
    13     shared_ptr<Node> right;
    14     Node(int k = 0) :key(k), parent(), left(), right() {}
    15 };
    16 
    17 typedef shared_ptr<Node> Pnode;
    18 
    19 class Tree
    20 {
    21 private:
    22     Pnode root;
    23     //返回以current为根节点的所有节点个数
    24     size_t __nodeSize(Pnode current) const;
    25     //返回以current为根节点的叶节点(没有左右节点)个数
    26     size_t __leafSize(Pnode current) const;
    27     //返回以current为根节点树的深度
    28     size_t __depth(Pnode current) const;
    29     //返回k值节点的地址
    30     const Pnode * __getNodeAddress(int k) const;
    31     //返回current节点下的最大值的节点
    32     Pnode __maxNode(Pnode current) const;
    33     //返回current节点下的最小值节点
    34     Pnode __minNode(Pnode current) const;
    35     void showNode(Pnode current) const;
    36 public:
    37     Tree() :root() {}
    38     //将k插入树
    39     void insert(int k);
    40     //删除值为k的节点
    41     void delNode(int k);
    42     //判断是否存在值为k的节点
    43     bool isExist(int k);
    44     //树中节点个数
    45     size_t nodeSize() const;
    46     //树中叶节点的个数
    47     size_t leafSize() const;
    48     //树的深度
    49     size_t depth() const;
    50     //树的宽度
    51     size_t width() const;
    52     //树的最大值
    53     int maxVal() const;
    54     //树的最小值
    55     int minVal() const;
    56     //打印所有节点
    57     void showAll() const;
    58 };
    59 
    60 
    61 #endif
    tree.h
      1 #include "Tree.h"
      2 
      3 //求树的宽度要用到队列
      4 #include <queue>
      5 
      6 using namespace std;
      7 
      8 //遍历节点
      9 //void static showNode(Pnode current);
     10 
     11 void Tree::showNode(Pnode current) const
     12 {
     13     if (current.get() == NULL)
     14         return;
     15     showNode(current->left);
     16     cout << current->key << " ";
     17     showNode(current->right);
     18 }
     19 
     20 void Tree::showAll() const
     21 {
     22     showNode(root);
     23     cout << endl;
     24 }
     25 
     26 void Tree::insert(int k)
     27 {
     28     //智能指针shared_ptr变量的初始化方式
     29     Pnode new_node(new Node(k));
     30     Pnode current = root;
     31     Pnode save = root;    
     32     while (current)
     33     {
     34         save = current;
     35         if (k < current->key)
     36             current = current->left;
     37         else current = current->right;
     38     }
     39     new_node->parent = save;
     40     if (!save)
     41         root = new_node;
     42     else if (k < save->key)
     43         save->left = new_node;
     44     else save->right = new_node;
     45 }
     46 
     47 void Tree::delNode(int k)
     48 {
     49     //__getNodeAddress返回的是带有顶层const类型的指针,
     50     //后面要改变指针指向的值,所以要先解除const限制.
     51     Pnode * pdel = const_cast<Pnode *>(__getNodeAddress(k));
     52     if (!pdel)
     53     {
     54         cout << k << " is not exist!
    ";
     55         return;
     56     }
     57     //save保存被删节点的父节点
     58     Pnode save = (*pdel)->parent;
     59     //被删节点没有子树
     60     if (!(*pdel)->left.get() && !(*pdel)->right.get())
     61         *pdel = NULL;
     62     //被删节点左子树为空
     63     else if (!(*pdel)->left.get())
     64     {
     65         *pdel = (*pdel)->right;
     66         (*pdel)->parent = save;
     67     }
     68     //被删节点右子树为空
     69     else if (!(*pdel)->right.get())
     70     {
     71         *pdel = (*pdel)->left;
     72         (*pdel)->parent = save;
     73     }
     74     //被删节点有左右子树
     75     else {
     76         //successor为被删节点的后继
     77         Pnode successor = __minNode((*pdel)->right);
     78         successor->left = (*pdel)->left;
     79         *pdel = (*pdel)->right;
     80         (*pdel)->parent = save;
     81     }
     82 }
     83 
     84 bool Tree::isExist(int k)
     85 {
     86     return __getNodeAddress(k) != NULL;
     87 }
     88 
     89 size_t Tree::__nodeSize(Pnode current) const
     90 {
     91     if (!current)
     92         return 0;
     93     return 1 + __nodeSize(current->left) + __nodeSize(current->right);
     94 }
     95 
     96 size_t Tree::nodeSize() const
     97 {
     98     return __nodeSize(root);
     99 }
    100 
    101 size_t Tree::__leafSize(Pnode current) const
    102 {
    103     if (current.get() == NULL)
    104         return 0;
    105     if (current->left.get() == NULL && current->right.get() == NULL)
    106         return 1;
    107     return __leafSize(current->left) + __leafSize(current->right);
    108 }
    109 
    110 size_t Tree::leafSize() const
    111 {
    112     return __leafSize(root);
    113 }
    114 
    115 size_t Tree::__depth(Pnode current) const
    116 {
    117     if (!current)
    118         return 0;
    119     size_t leftSize = 1 + __depth(current->left);
    120     size_t rightSize = 1 + __depth(current->right);
    121     return leftSize > rightSize ? leftSize: rightSize;
    122 }
    123 
    124 size_t Tree::depth() const
    125 {
    126     return __depth(root);
    127 }
    128 
    129 size_t Tree::width() const
    130 {
    131     if (!root)
    132         return 0;
    133     Pnode current = root;
    134     int maxNode = 1;
    135     int ct = 0;
    136     queue<Pnode> qu;
    137     qu.push(current);
    138     while (qu.size() != 0)
    139     {
    140         ct = qu.size();
    141         for (int i = 0; i < ct; i++)
    142         {
    143             current = qu.front();
    144             qu.pop();
    145             if (current->left.get() != NULL)
    146                 qu.push(current->left);
    147             if (current->right.get() != NULL)
    148                 qu.push(current->right);
    149         }
    150         maxNode = maxNode > qu.size() ? maxNode : qu.size();
    151     }
    152     return maxNode;
    153 }
    154 
    155 /*
    156 * 此处返回指针是考虑到方便delNode调用,内存本身的地址和内存指向的值会带来很大困惑,
    157 * 要仔细品味,此前写delNode方法从节点本身来考虑,反复建立节点关系,写下的代码长度
    158 * 大概是现在delNode长度的2倍,效率也会打折扣.
    159 */
    160 const Pnode  * Tree::__getNodeAddress(int k) const
    161 {
    162     Pnode ret = root;
    163     Pnode save = {};
    164     if (root->key == k)
    165         return &root;
    166     while (1)
    167     {
    168         save = ret;
    169         if (k < ret->key)
    170         {
    171             if (!(ret = ret->left).get())
    172                 break;
    173             if (ret->key == k)
    174                 return &(save->left);
    175         }
    176         else {
    177             if(!(ret = ret->right).get())
    178                 break;
    179             if (ret->key == k)
    180                 return &(save->right);
    181         }
    182     }
    183     return NULL;
    184 }
    185 
    186 Pnode Tree::__maxNode(Pnode current) const
    187 {
    188     
    189     while (current->right.get() != NULL)
    190         current = current->right;
    191     return current;
    192 }
    193 
    194 Pnode Tree::__minNode(Pnode current) const
    195 {
    196     while (current->left.get() != NULL)
    197         current = current->left;
    198     return current;
    199 }
    200 
    201 int Tree::maxVal() const
    202 {
    203     if (root.get() == NULL)
    204         return 0x80000000;
    205     return __maxNode(root)->key;
    206 }
    207 
    208 int Tree::minVal() const
    209 {
    210     if (root.get() == NULL)
    211         return 0x7FFFFFFF;
    212     return __minNode(root)->key;
    213 }
    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: 
    ";
    15     showArray(arr, ASIZE);
    16     Tree t;
    17     loadArrayToTree(t, arr, ASIZE);
    18     cout << "show Tree: 
    ";
    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测试代码
  • 相关阅读:
    HDU 2023题解分析
    Java中常见的几种类型转换
    Software Version --hdu1976
    单词数
    Usaco 2.3 Zero Sums(回溯DFS)--暴搜
    9的余数
    mongodb学习(一)
    svg学习(九)path
    svg学习(八)polyline
    qunit学习(一)
  • 原文地址:https://www.cnblogs.com/endenvor/p/7682733.html
Copyright © 2011-2022 走看看