二叉树

二叉树的基本操作(C++)

1. 首先创建二叉树结构,以及二叉树的类,定义在BinaryTree.h中

 1 #ifndef _BINARYTREE_H
 2 #define _BINARYTREE_H
 3 #include "pch.h"
 4 #include <iostream>
 5 
 6 using namespace std;
 7 
 8 typedef struct TreeNode
 9 {
10     char val;            //节点的数据类型
11     TreeNode * left;     //左子树
12     TreeNode * right;    //右子树
13     TreeNode(char x):val(x), left(nullptr), right(nullptr) {}
14 
15 }TreeNode, *BiTree;
16 
17 class BinaryTree
18 {
19 public:
20     BinaryTree() {}
21     ~BinaryTree() {}
22     void TreeCreate();            //递归的创建二叉树的节点
23     int getSize();                //递归得到树的节点数目
24     int getHeight();              //递归得到树的高度
25     void preOrder();              //前序遍历
26     void inOrder();               //中序遍历
27     void postOrder();             //后序遍历
28     void distroy();               //删除二叉树
29 
30 private:
31     BiTree create();                        //递归的创建二叉树的节点
32     void preOrder(BiTree root);             //前序遍历
33     void inOrder(BiTree root);              //中序遍历
34     void postOrder(BiTree root);            //后序遍历
35     void distroy(BiTree root);              //摧毁树
36     int getHeight(BiTree root);             //递归得到树的高度
37     void AddNode(const char key, int direction, BiTree root);         //添加节点
38     BiTree m_root;                          //根节点
39     int size;                               //节点总数
40 };
41 
42 #endif

2. 具体实现    BinaryTree.cpp

# include "BinaryTree.h"

#pragma
region 私有成员函数 //添加节点 //key为要插入的值,direction是从左子树插入还是右子树插入,root为从哪个节点插入 void BinaryTree::AddNode(const char key, int direction, BiTree root) { if (direction == 0) { //从左子树插入 if (root->left == NULL) root->left = new TreeNode(key); else AddNode(key, direction, root->left); } else if (direction == 1) { //从右子树插入 if (root->right == NULL) root->right = new TreeNode(key); else AddNode(key, direction, root->right); } } //二叉树的建立,按前序遍历(root->left->right)的方式建立二叉树 BiTree BinaryTree::create() { BiTree current = NULL; char val; cin >> val;//输入键值 if (val == '#')//标识当前子树为空,转向下一节点 { return NULL; } else { //递归的创建左右子树 size++;//记录节点数 current = new TreeNode(val); current->left = create(); current->right = create(); return current; } } //删除二叉树 void BinaryTree::distroy(BiTree root) { if (root) { distroy(root->left); distroy(root->right); delete root; root = NULL; size = 0; } } //递归得到树的高度 int BinaryTree::getHeight(BiTree root) { if (root == NULL) return 0; int left_height = getHeight(root->left); int right_height = getHeight(root->right); return (left_height > right_height) ? (left_height + 1) : (right_height + 1); } //前序遍历 root->left->right void BinaryTree::preOrder(BiTree root) { if (root == NULL) return; else { cout << root->val << " --> "; //首先打印根节点 preOrder(root->left); //接着遍历左子树 preOrder(root->right); //接着遍历右子树 } } //中序遍历 left->root->right void BinaryTree::inOrder(BiTree root) { if (root == NULL) return; else { inOrder(root->left); //首先遍历左子树 cout << root->val << " --> "; //接着打印根节点 inOrder(root->right); //接着遍历右子树 } } //后序遍历 left->right->root void BinaryTree::postOrder(BiTree root) { if (root == NULL) return; else { postOrder(root->left); //首先遍历左子树 postOrder(root->right); //接着遍历右子树 cout << root->val << " --> "; //接着打印根节点 } } #pragma endregion #pragma region 公有成员函数 //二叉树的建立 void BinaryTree::TreeCreate() { size = 0; m_root =create(); } //删除二叉树 void BinaryTree::distroy() { distroy(m_root); } //递归得到树的高度 int BinaryTree::getHeight() { return getHeight(m_root); } //前序遍历 void BinaryTree::preOrder() { cout << "前序遍历的结果如下:" << endl; preOrder(m_root); cout << endl; } //中序遍历 void BinaryTree::inOrder() { cout << "中序遍历的结果如下:" << endl; inOrder(m_root); cout << endl; } //后序遍历 void BinaryTree::postOrder() { cout << "后序遍历的结果如下:" << endl; postOrder(m_root); cout << endl; } //获取大小 int BinaryTree::getSize() { //这里是创建时候直接进行了计数 //也可以利用遍历的方式获取,当节点有值,就加1 return size; } #pragma endregion

3.主函数调用

int main()
{
    BinaryTree tree;
    cout << "按前序遍历方式创建树" << endl;
    //"ABDG##H###CE#I##F##";
    tree.TreeCreate();
    cout << "树的高度为:" << tree.getHeight() << endl;
    cout << "树的节点为:" << tree.getSize() << endl;
    tree.preOrder();            //前序遍历
    tree.inOrder();             //中序遍历
    tree.postOrder();           //后序遍历
    tree.distroy();             //摧毁树
    system("pause");
}

 ------------------------------------------------------------------------------------------------------分割线-----------------------------------------------------------------------------------------------------

输入的树的结构图如下:

前序遍历:ABDGHCEIF(先是根结点,再前序遍历左子树,再前序遍历右子树)

中序遍历:GDHBAEICF(先中序遍历左子树,再是根结点,再是中序遍历右子树)
后序遍历:GHDBIEFCA(先后序遍历左子树,再是后序遍历右子树,再是根结点)

以该二叉树的创建为例说明递归进行的过程:

BiTree BinaryTree::create()
{
    BiTree current = NULL;
    char val;
    cin >> val;//输入键值

    if (val == '#')//标识当前子树为空,转向下一节点
    {
        return NULL;
    }
    else
    {   //递归的创建左右子树  
        size++;//记录节点数
        current = new TreeNode(val);
        current->left = create();
        current->right = create();
        return current;
    }
}

树的建立过程先“递"再"归"。递归可以理解为一个人去楼上拿东西。他沿楼梯上到有东西的楼层,这个可以理解为“递”;拿了东西后,再沿来时的楼梯下来,这个过程叫“归”。

输入   ABDG##H###CE#I##F##  (前序遍历建树)   以A的左子树建立过程为例:

(1) “递”的过程:

在建立A后,以A为根节点开始建A的左子树B,然后再以B为根节点建立B的左子树D,按 A->B->D->G 的顺序依次建立。此时都在由左向右执行

                                                   current->left = create()

这条语句。但是current却不一样,按从顶层到底层的顺序  即,

  • A->left=create B    
  • B->left=create D
  • D->left=create G
  • G->left=create() 

(2) 当遇到“#”后就进入了“归”(底层到顶层的顺序 )的过程:

  • 遇到“#”后,就会return null给G->left(由右向左  return),G->left建立完成;
  • 接下来会进入G->right=create() 这条语句,然后遇到“#”后,就会return null给G->right,G->right建立完成;
  • 当G->left 、G->right都建立完成后,就会return G 给 D->left,D->left建立完成;
  • 接下来进入D->right=create H 这条语句,按照和建立G的过程一样建立完H,然后return H 给 D->right,D->right建立完成;
  • 当D->left 、D->right都建立完成后,就会return D 给 B->left,B->left建立完成;
  • 接下来会进入B->right=create() 这条语句,然后遇到“#”后,就会return null给B->right,B->right建立完成;
  • 当B->left 、B->right都建立完成后,就会return B 给 A->left,A->left建立完成

(3) A的右子树建立也是同样过程

 

总结:

整个树的建立过程如下列顺序

开始  A-1->B-3->D-7->G-13->#-13->G-14->#-14->G-7->D-8->H-15->#-15->H-16->#-16->H-8->D-3->B-4->#-4->B-1->

         A-2->C-5->E-9->#-9->E-10->I-17->#-17->I-18->#-18>I-10->E-5->C-6->F-11->#-11->F-12->#-12>F-6->C-2->A   结束

 

posted @ 2019-03-07 17:13  小果子啊  阅读(193)  评论(0编辑  收藏  举报