数据结构二叉树的基本编码(原创)

先建立二叉树类的相关代码如下:

#include <iostream>
#include <math.h>
#include <stdlib.h>
using namespace std;

template <typename T>
struct bintreenode
{
    T date;
    bintreenode<T> *leftchild,*rightchild;
    bintreenode()
    {
        leftchild = NULL;
        rightchild = NULL;
    }
    bintreenode(T x, bintreenode<T> *l = NULL,bintreenode<T> *r = NULL)
    {
        date = x;
        leftchild = l;
        rightchild = r;
    }
};

template <class T>
class binarytree
{
private:
    bintreenode<T> *root;//根为非空节点,保存有数据
    T refvalue;//标示空节点的字符
public:
    friend istream& operator >> (istream&, binarytree<T>&);
    friend ostream& operator << (ostream &out, binarytree<T> &tree)
    {
        out<<"二叉树前序遍历结果为:"<<endl;
        bintreenode<T> *p = tree.getroot();
        tree.Traverse(p);
        out<< endl;
        return out;
    }
    binarytree()
    {
        root = NULL;
    }
    binarytree(T value)
    {
        refvalue = value;
        root = NULL;
    }
    binarytree(const binarytree<T> &s);//复制构造函数
    bintreenode<T>* copy(bintreenode<T>*);//复制函数
    ~binarytree(){destroy(root);}//析构函数
    void destroy(bintreenode<T>*);//删除二叉树
    bool IsEmpty(){return root == NULL ? true : false;}//判断是否为空树
    void Createbintree(bintreenode<T>* &subtree);//创建二叉树
    void Traverse(bintreenode<T>* subtree);//前序遍历
    bintreenode<T>* getroot() const{ return root;}//取根节点
    int size(bintreenode<T>* subtree)const;//计算节点个数
    int height(bintreenode<T>* subtree)const;//求树的高度
    int leaves(bintreenode<T>* subtree) const;//计算叶子节点个数
    bintreenode<T>* parent(bintreenode<T>*, T);//求指定点的父节点
    bintreenode<T>* find(bintreenode<T>* subtree,const T &t) const;//查找节点信息
    bool equal(bintreenode<T>* t1,bintreenode<T>* t2)const;//判断两棵树是否相等

};

template<typename T>
istream& operator >> (istream& in,binarytree<T>& tree)
{
    bintreenode<T> *p = tree.getroot();
    tree.Createbintree(p);
    return in;
}
/*
template<typename T>
ostream& operator<<(ostream& out, binarytree<T>& tree)
{
    out<<"二叉树前序遍历结果为:"<<endl;
    bintreenode<T> *p = tree.getroot();
    tree.Traverse(p);
    out<< endl;
    return out;
}
*/
template<typename T>
binarytree<T>::binarytree(const binarytree<T> &s)
{
    root = copy(s.root);
}

template<typename T>
bintreenode<T>* binarytree<T>::copy(bintreenode<T>* orignode)
{
    if(orignode == NULL)
        return NULL;
    bintreenode<T>* temp = new bintreenode<T>;
    temp->date = orignode->date;
    temp->leftchild = copy(orignode->leftchild);
    temp->rightchild  = copy(orignode->rightchild);
    return temp;
}

template<typename T>
void binarytree<T>::destroy(bintreenode<T> * subtree)
{
    if(subtree != NULL)
    {
        destroy(subtree->leftchild);
        destroy(subtree->rightchild);
        delete subtree;
    }
}

template<typename T>
void binarytree<T>::Createbintree(bintreenode<T>* &subtree)
{
    T item;
    if(!cin.eof())
    {
        cin >> item;
        if(item != refvalue)
        {
            subtree = new bintreenode<T>(item);
            if(subtree == NULL)
            {
                cout << "储存分配出错!"<< endl;
                exit(1);
            }
            if(root == NULL)
                root = subtree;
            Createbintree(subtree->leftchild);
            Createbintree(subtree->rightchild);
        }
        else
            subtree == NULL;
    }
}

template<typename T>
void binarytree<T>::Traverse(bintreenode<T>* subtree)
{
    if(subtree != NULL)
    {
        cout << subtree->date << " ";
        Traverse(subtree->leftchild);
        Traverse(subtree->rightchild);
    }
}

template<typename T>
int binarytree<T>::size(bintreenode<T>* subtree)const
{
    if(subtree == NULL)
        return 0;
    else
        return 1 + size(subtree->leftchild) + size(subtree->rightchild);
}

template<typename T>
int binarytree<T>::height(bintreenode<T>* subtree)const
{
    int dep1,dep2;
    if(subtree == NULL)
        return 0;
    else
    {
        dep1 = height(subtree->leftchild);
        dep2 = height(subtree->rightchild);
        return dep1 > dep2 ? dep1+1 : dep2+1;
    }
}

template<typename T>
int binarytree<T>::leaves(bintreenode<T> *subtree)const
{
    if(subtree == NULL)
        return 0;
    else
    {
        if(subtree->leftchild == NULL && subtree->rightchild == NULL)
            return 1;
        else
            return leaves(subtree->leftchild) + leaves(subtree->rightchild);
    }
}
template<typename T>
bintreenode<T>* binarytree<T>::parent(bintreenode<T>* subtree, T current)
{
    if(subtree == NULL)
        return NULL;
    if((subtree->leftchild != NULL && subtree->leftchild->date == current) || (subtree->rightchild != NULL &&subtree->rightchild->date == current))
        return subtree;

    bintreenode<T>* p;
    if((p = parent(subtree->leftchild,current)) != NULL)
        return p;
    else
        return parent(subtree->rightchild,current);
}

template<typename T>
bintreenode<T>* binarytree<T>::find(bintreenode<T>* subtree,const T &x)const
{
    if(subtree == NULL)
        return NULL;
    if(subtree->date == x)
        return subtree;

    bintreenode<T>* p;
    if((p = find(subtree->leftchild,x)) != NULL)
        return p;
    else
        return find(subtree->rightchild,x);
}
//先处理都为空的情况为相等
//再处理只有一个为空的情况
//最后处理两个都不是空的时候的情况,子树的的判断
template<typename T>
bool binarytree<T>::equal(bintreenode<T>* t1, bintreenode<T>* t2)const
{
    if(t1 == NULL && t2 == NULL)
        return true;
    else if(t1 == NULL || t2 == NULL)
        return false;
    else
    {
        if(t1->date == t2->date)
            return true;
        bool l_equal = equal(t1->leftchild,t2->leftchild);
        bool r_equal = equal(t1->rightchild,t2->rightchild);
        if(l_equal && r_equal)
            return true;
        else
            return false;
    }
}

 再建立一个主文件如下:

#include <iostream>
#include "tree.h"

using namespace std;

int main()
{
    binarytree<char> P('#');
    binarytree<char> P1(P);
    cout << "请按照前序遍历输入:"<< endl;
    bintreenode<char>* Q = P.getroot();
    P.Createbintree(Q);
    cout << "前序遍历为:"<< endl;
    P.Traverse(Q);
    cout << endl <<"节点个数为:";
    cout << P.size(Q) << endl;
    cout << "树高度为:" << P.height(Q) << endl;
    cout << "树种叶子数为:" << P.leaves(Q)<< endl;
    /*
    cout << "节点F的父节点为:";
    bintreenode<char> *node = P.parent(Q,'A');
    if(node != NULL)
        cout << node->date;
    else
        cout <<"不存在父节点!";
    cout << "查找信息为:" << P.find(Q,'G')->date << endl;
    */
    if(P.equal(Q,Q))
        cout << "xiangdeng"<<endl;
    else
        cout<<"bd"<< endl;

    return 0;
}

 在编码的过程中最容易出问题的是:查找指定元素的位置和父节点,还有两个二叉树是否相等的判断,在这三个函数中要用到递归的思想,在判断到找出准确位置时可以中断递归。但处理的过程不同,最主要还是要由清晰的思路和递归的思想。

原文地址:https://www.cnblogs.com/wyqx/p/2267677.html