美文网首页
二叉树实现

二叉树实现

作者: krislyy_ | 来源:发表于2018-11-27 16:39 被阅读0次

1.层次遍历可以用于寻找叶子节点,寻找路径,寻找树的最短最大高度的非递归实现。
2.中序遍历搜索二叉树后是升序的序列。这个特性可以判断搜索二叉树的有效性。
3.使用双向的递归可以遍历每个分支的每个节点。

/*
 * Created by krislyy on 2018/11/23.
 * 作为图的特殊形式,二叉树的基本组成单元是节点与边;
 * 作为数据结构,其基本的组成实体是二叉树节点,而边则
 * 对应于节点之间的相互引用
 */

#pragma once

#include<iostream>
#include<queue>
#include<stack>

using namespace std;

template <class T>  //树的结构体
struct BinaryTreeNode
{
public:
    T _data;
    BinaryTreeNode<T>* _leftChild;
    BinaryTreeNode<T>* _rightChild;

public:
    BinaryTreeNode(const T& data)
            :_data(data)
            , _leftChild(NULL)
            , _rightChild(NULL)
    {}

    ~BinaryTreeNode()
    {}
};

template <class T>
class BinaryTree //树的封装
{
public:
    BinaryTreeNode<T>* _root;

public:
    BinaryTree()
            :_root(NULL)
    {}

    BinaryTree( T*a, size_t size)
    {
        size_t index = 0;
        _root = _CreateBiTree(a, index, size);
    }

    BinaryTree(const BinaryTree& tmp)
            :_root(NULL)
    {
        _root=_Copy(tmp._root);

    }
    ~BinaryTree()
    {
        Destory();
    }

    BinaryTree<T>& operator=( BinaryTree<T> tmp)
    {
        swap(_root, tmp._root);
        return *this;

    }

    void InOrder()//中序遍历递归方法
    {
        _InOrder(_root);
        cout << endl;
    }

    void PreOrder()//前序遍历递归方法
    {
        _PreOrder(_root);
        cout << endl;
    }

    void PosOrder()//后序遍历递归方法
    {
        _PosOrder(_root);
        cout << endl;
    }

    void LevelOrder()//层序遍历
    {
        queue<BinaryTreeNode<T>*> s ;
        s.push(_root);
        while (!s.empty())
        {
            BinaryTreeNode<T>* cur = s.front();
            cout<<cur->_data<<' ';
            if (cur->_leftChild)
                s.push(cur->_leftChild);
            if (cur->_rightChild)
                s.push(cur->_rightChild);
            s.pop();
        }
        cout << endl;
    }

    void Size()//节点数
    {
        int size = 0;
        cout<<_Size(_root,size)<<endl;

    }

    void Hight()//深度  /高度
    {
        cout << _Hight(_root) << endl;
    }

    void Destory()//销毁
    {
        _Destory(_root);
        _root=NULL;
    }

    void LeafNum()//叶子节点数
    {
        int num = 0;
        _LeafNum(_root, num);
        cout <<num<<endl;

    }

    void PreOrderNonR()//前序 非递归  (借用栈)
    {
        if (_root == NULL)
            return;
        stack<BinaryTreeNode<T>*> s ;
        s.push(_root);
        while (!s.empty())
        {
            BinaryTreeNode<T>* cur;
            cur=s.top();
            s.pop();
            cout << cur->_data << ' ';
            if (cur->_rightChild)
                s.push(cur->_rightChild);
            if (cur->_leftChild)
                s.push(cur->_leftChild);
        }
        cout << endl;
    }

    void InOrderNonR() //中序 非递归
    {
        if (_root == NULL)
            return;
        stack<BinaryTreeNode<T>*> s;
        s.push(_root);
        BinaryTreeNode<T>* prev=NULL;
        BinaryTreeNode<T>* cur=NULL;
        while (!s.empty())
        {
            cur = s.top();
            if(prev != cur&&cur->_leftChild) //左不空 压左
            {
                s.push(cur->_leftChild);
            }
            else //左空   出栈 输出
            {
                cout << cur->_data << ' ';
                s.pop();
                if (!s.empty())
                    prev = s.top();//prev始终为出栈后的栈顶
                if (cur->_rightChild)//  cur右不空  压右
                {

                    s.push(cur->_rightChild);

                }
            }
        }
        cout << endl;
    }

    void PosOrderNonR()  //后续  非递归
    {
        if (_root == NULL)
            return;
        stack<BinaryTreeNode<T>*> s;
        BinaryTreeNode<T>* cur = NULL;
        BinaryTreeNode<T>* prev = NULL;
        BinaryTreeNode<T>* tmp = NULL;
        s.push(_root);
        while (!s.empty())
        {
            cur = s.top();
            if (prev != cur&&cur->_leftChild != NULL)//1.左不空且prev!=cur 压左
                s.push(cur->_leftChild);
            else//左空
            {
                if (cur->_rightChild!=tmp  &&cur->_rightChild)//右不空 且 cur->right!=tmp 压右
                {
                    s.push(cur->_rightChild);
                }

                else             //右空  输出 cur
                {
                    cout << cur->_data << ' ';
                    tmp = s.top();    //tmp(判断是否压右)始终为出栈前的栈顶
                    s.pop();
                    if (!s.empty())
                    {
                        prev = s.top();//prev(判断是否压右)始终为出栈后栈顶

                    }
                }
            }
        }
        cout << endl;
    }

protected://以下为递归的调用函数

    BinaryTreeNode<T>* _CreateBiTree(const T* tmp, size_t& index, size_t size)
    {
        BinaryTreeNode<T>* root = NULL;
        if (index < size&&tmp[index]!='#')
        {
            root = new BinaryTreeNode<T>(tmp[index]);
            root->_leftChild = _CreateBiTree(tmp, ++index, size);
            root->_rightChild = _CreateBiTree(tmp, ++index, size);
        }
        return root;
    }

    void _InOrder(BinaryTreeNode<T>* &node)
    {
        if (node == NULL)
            return;
        _InOrder(node->_leftChild);
        cout << node->_data << ' ';
        _InOrder(node->_rightChild);
    }

    void _PreOrder(BinaryTreeNode<T>* &node)
    {
        if (node == NULL)
            return;
        cout << node->_data<<' ';
        _PreOrder(node->_leftChild);
        _PreOrder(node->_rightChild);

    }

    void _PosOrder(BinaryTreeNode<T>* &node)
    {
        if (node == NULL)
            return;
        _PosOrder(node->_leftChild);
        _PosOrder(node->_rightChild);
        cout << node->_data << ' ';
    }

    int _Size(BinaryTreeNode<T>* root,int & size)
    {
        if (root == NULL)
            return 0;
        size++;
        _Size(root->_leftChild, size);
        _Size(root->_rightChild, size);
        return size;
    }

    int _Hight(BinaryTreeNode<T>* root)
    {
        int hight = 1;
        if (root == NULL)
            return 0;
        hight += _Hight(root->_leftChild);
        int ritHight = 0;
        ritHight+= _Hight(root->_rightChild);
        if (hight < ritHight)
            hight = ritHight;
        return hight;


    }
    void _Destory(BinaryTreeNode<T>* root)
    {
        if (root == NULL)
            return;
        BinaryTreeNode<T>* del = root;

        _Destory(del->_leftChild);
        _Destory(del->_rightChild);
        delete root;

        return;
    }

    void _LeafNum(BinaryTreeNode<T>* root,int& num)
    {
        if (root == NULL)
            return ;
        if (root->_leftChild == NULL&&root->_rightChild == NULL)
            ++num;
        _LeafNum(root->_leftChild,num);
        _LeafNum(root->_rightChild,num);
        return ;
    }

    BinaryTreeNode<T>* _Copy(BinaryTreeNode<T>* root)
    {
        if (root == NULL)
            return NULL;
        BinaryTreeNode<T>* newRoot = NULL;
        newRoot = new BinaryTreeNode<T>(root->_data);
        newRoot->_leftChild = _Copy(root->_leftChild);
        newRoot->_rightChild = _Copy(root->_rightChild);
        return newRoot;

    }
};

测试代码

void CheckBinaryTree(){
    int l[j] = { 1, 2, 3,'#', '#', 4, '#', '#', 5, 6 };
    int s[18] = { 1, 2, 3, 4, '#', '#', 5, '#', '#', 6,'#','#' ,7, 8, '#', '#', 9, 10 };
    BinaryTree<int> t1;
    BinaryTree<int> t2(s, 18);
    BinaryTree<int> t3(t2);
    t1 = t2;
    t2.PreOrder();
    t2.InOrder();
    t2.PosOrder();
    t2.LevelOrder();
    t2.Size();
    t2.Hight();
    t2.Destory();
    t3.InOrder();
    t1.InOrder();
    t3.LeafNum();
    t3.PreOrderNonR();
    t3.InOrderNonR();
    t3.PosOrderNonR();
}

构造后形成的树如下结构

                         1
                        /  \
                      2     7
                     / \   /  \
                   3    6  8   9
                  / \         /
                4    5       10

输出:

pre    : 1 2 3 4 5 6 7 8 9 10
in     :  4 3 5 2 6 1 8 7 10 9
post   : 4 5 3 6 2 8 10 9 7 1
level  : 1 2 7 3 6 8 9 4 5 10

相关文章

  • python实现二叉树

    递归实现二叉树 堆实现二叉树前序遍历

  • 算法之二叉树

    二叉树之C++实现 创建二叉树 复制二叉树 先序遍历 递归实现 非递归实现 中序遍历 递归实现 非递归实现 后序遍...

  • 数据结构之树的相关问题

    实验要求 实现二叉树的抽象数据类型 实现二叉树的建立的运算 实现二叉树的遍历运算 实现创建哈夫曼树的算法 实验代码...

  • 2. 二叉树 BinTree

    二叉树的实现 BinNode : 二叉树结点 二叉树结点结构代码 : 二叉树常用接口实现 将新结点作为左/右孩子插...

  • 力扣算法 - 翻转二叉树

    翻转二叉树 翻转一棵二叉树。 示例: 输入: 输出: 思路: Java实现 Swift实现

  • 二叉树的实现

    二叉树的节点 二叉树的实现 测试

  • 面试算法--递归/循环实现二叉树的前丶中丶后序遍历

    一丶利用二叉树前序顺序构建二叉树 "#" 代表空结点 二丶递归实现二叉树前中后序遍历 三丶循环实现二叉树前中后序遍...

  • 数据结构之二叉树

    数据结构之二叉树 递归构造二叉树 二叉树节点: 递归构造: 图示: 递归遍历 递归实现先序遍历 图示: 递归实现中...

  • Java二叉树的遍历

    Java二叉树的遍历 利用递归和非递归实现二叉树的先序,中序,后序遍历以及使用队列实现二叉树的层次遍历

  • 二叉树查找与节点删除的javascript实现

    前言 紧接前面说过的 二叉树的实现 和 二叉树的遍历,今天来说一下用javascript实现二叉树的查找和节点删除...

网友评论

      本文标题:二叉树实现

      本文链接:https://www.haomeiwen.com/subject/sjtnqqtx.html