[数据结构]二叉树之二叉链表的类模板实现

该类模板实现了一个二叉树的模板类,采用二叉链表实现。

定义二叉树节点类,采用二叉链表实现。

/////////////////////////
#include <iostream>
#include <cstdlib>
#include <stack>
#include <deque>
using namespace std;

template<class T>
struct BinTreeNode  //二叉树节点类的定义,使用二叉链表
{
    T data;
    BinTreeNode<T> *leftChild, *rightChild;
    BinTreeNode():leftChild(NULL),rightChild(NULL){}
    BinTreeNode(T x,BinTreeNode<T> *l=NULL,BinTreeNode<T> *r=NULL):data(x),leftChild(l),rightChild(r){}
};

二叉树的模板类实现如下:可进行相应的功能扩展。

接口部分:

template<class T>
class BinaryTree//二叉树的模板类
{
public:
    BinaryTree():root(NULL){}
    BinaryTree(char x):root(NULL),RefValue(x){}
    BinaryTree(const BinaryTree<T>& rhs){root=copy(rhs.root);}//copy构造函数
    BinaryTree<T>& operator=(const BinaryTree<T>& rhs);//copy 赋值运算符;析构+copy构造函数
    ~BinaryTree(){destroy(root);}//析构函数

    bool isEmpty()const{return root!=NULL?false:true;}
    BinTreeNode<T>* leftChild(BinTreeNode<T>* current)const{return current!=NULL?current->leftChild:NULL;}
    BinTreeNode<T>* rightChild(BinTreeNode<T>* current)const{return current!=NULL?current->rightChild:NULL;}
    BinTreeNode<T>* parent(BinTreeNode<T>* current)const{return (root==NULL || current==root)?NULL:parent(root,current);}//寻找其父节点
    BinTreeNode<T>* getRoot()const{return root;}

    void inOrder(void (*visit)(BinTreeNode<T> *p)){inOrder(root,visit);}//中序递归遍历
    void preOrder(void (*visit)(BinTreeNode<T> *p)){preOrder(root,visit);}//前序递归
    void postOrder(void (*visit)(BinTreeNode<T> *p)){postOrder(root,visit);}//后序递归
    void levelOrder(void (*visit)(BinTreeNode<T> *p));//使用队列的层次遍历

    int size()const {return size(root);}//使用后序递归遍历求节点个数
    int height()const {return height(root);}//使用后序递归遍历求二叉树的高度

protected:
    BinTreeNode<T> *root;
    char RefValue;//数据输入停止标志

    void destroy(BinTreeNode<T>* subTree);//递归删除二叉树节点,后序遍历删除
    BinTreeNode<T>* copy(const BinTreeNode<T> *orignode);//copy构造;前序

    BinTreeNode<T>* parent(BinTreeNode<T>* subTree,BinTreeNode<T>* current)const;//返回父节点
    void traverse(BinTreeNode<T>* subTree,ostream& out)const;//按前序方式遍历输出每个节点的值
    void createBinTree(istream& in,BinTreeNode<T>* & subTree);//采用广义表表示的二叉树创建方法

    void inOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p));//中序遍历
    void preOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p));//前序遍历
    void postOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p));//后序遍历

    int size(BinTreeNode<T> *subTree)const;//使用后序递归遍历求节点个数
    int height(BinTreeNode<T> *subTree)const;//使用后序递归遍历求二叉树的高度

    friend ostream& operator<< <T>(ostream& out,const BinaryTree<T>& rhs);//add <T> 前序输出二叉树
    friend istream& operator>> <T>(istream& in, BinaryTree<T>& rhs);      //add <T> 采用广义表表示方式创建二叉树

};

相应成员函数的具体实现:

template<class T>
void BinaryTree<T>::destroy(BinTreeNode<T>* subTree)
{
    if(subTree!=NULL){
        destroy(subTree->leftChild);
        destroy(subTree->rightChild);
        delete subTree;
    }
}

template<class T>
BinTreeNode<T>* BinaryTree<T>::parent(BinTreeNode<T>* subTree,BinTreeNode<T>* current)const
{
    if(subTree==NULL) return NULL;
    if(subTree->leftChild==current || subTree->rightChild==current) return subTree;

    BinTreeNode<T>* p;
    if((p=parent(subTree->leftChild,current))!=NULL)
        return p
    else
        return parent(subTree->rightChild,current);
}

template<class T>
void BinaryTree<T>::traverse(BinTreeNode<T>* subTree,ostream& out)const
{
    if(subTree!=NULL){
        out<<subTree->data<<" ";
        traverse(subTree->leftChild,cout);
        traverse(subTree->rightChild,out);
    }
}

template<class T>
void BinaryTree<T>::createBinTree(istream& in,BinTreeNode<T>* & subTree)
{
    stack<BinTreeNode<T>* > s;
    subTree=NULL;
    BinTreeNode<T> *p,*t;
    unsigned int k;
    T ch;
    in>>ch;//虽然是模板类,但是目前只支持字符型,不然会报错
    while(ch!=RefValue){
        switch(ch){
        case ‘(‘: s.push(p);k=1;break;
        case ‘)‘: s.pop();break;
        case ‘,‘: k=2;break;
        default:
            p=new BinTreeNode<T>(ch);
            if(subTree==NULL)
                subTree=p;
            else if(k==1)
                {t=s.top();t->leftChild=p;}
            else
                {t=s.top();t->rightChild=p;}
        }
        in>>ch;
    }
}

template<class T>
ostream& operator<<(ostream& out,const BinaryTree<T>& rhs)
{
    rhs.traverse(rhs.root,out);
    out<<endl;
    return out;
}

template<class T>
istream& operator>>(istream& in, BinaryTree<T>& rhs)
{
    rhs.createBinTree(in,rhs.root);
    return in;
}

template<class T>
void BinaryTree<T>::inOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p))
{
    if(subTree!=NULL){
        inOrder(subTree->leftChild,visit);
        visit(subTree);
        inOrder(subTree->rightChild,visit);
    }
}

template<class T>
void BinaryTree<T>::preOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p))
{
    if(subTree!=NULL){
        visit(subTree);
        inOrder(subTree->leftChild,visit);
        inOrder(subTree->rightChild,visit);
    }
}

template<class T>
void BinaryTree<T>::postOrder(BinTreeNode<T> *subTree,void (*visit)(BinTreeNode<T> *p))
{
    if(subTree!=NULL){
        inOrder(subTree->leftChild,visit);
        inOrder(subTree->rightChild,visit);
        visit(subTree);
    }
}

template<class T>
int BinaryTree<T>::size(BinTreeNode<T> *subTree)const
{
    if(subTree==NULL)  return 0;
    else
        return 1+size(subTree->leftChild)+size(subTree->rightChild);
}

template<class T>
int BinaryTree<T>::height(BinTreeNode<T> *subTree)const
{
    if(subTree==NULL) return 0;
    else{
        int i=height(subTree->leftChild);
        int j=height(subTree->rightChild);
        return (i>j)?i+1:j+1;
    }
}

template<class T>
BinTreeNode<T>* BinaryTree<T>::copy(const BinTreeNode<T> *orignode)
{
    if(orignode==NULL) return NULL;
    BinTreeNode<T> *temp=new BinTreeNode<T>;
    temp->data=orignode->data;
    temp->leftChild=copy(orignode->leftChild);
    temp->rightChild=copy(orignode->rightChild);
    return temp;
}

template<class T>
BinaryTree<T>& BinaryTree<T>::operator=(const BinaryTree<T>& rhs)
{
    this->destroy(this->root);
    this->root=copy(rhs.root);
    return *this;
}

template<class T>
void BinaryTree<T>::levelOrder(void (*visit)(BinTreeNode<T> *p))
{
    deque<BinTreeNode<T>* > dq;
    BinTreeNode<T> *p=root;
    dq.push_back(p);
    while(!dq.empty()){
        p=dq.front();
        visit(p);
        dq.pop_front();

        if(p->leftChild!=NULL) dq.push_back(p->leftChild);
        if(p->rightChild!=NULL) dq.push_back(p->rightChild);
    }
}

测试函数:

int main(int argc, char* argv[])
{

    BinaryTree<char> b(‘#‘);
    cin>>b;
    cout<<b<<endl;

    //b.levelOrder(NULL);

    //BinaryTree<char> a(‘#‘);
    //cin>>a;
    //cout<<a<<endl;
    // b=a;
    //cout<<b<<endl;

    //BinaryTree<char> a=b;
    //cout<<a<<endl;

    //cout<<b.size()<<endl;
    //cout<<b.isEmpty()<<endl;
    //cout<<b.height()<<endl;

    system("pause");
    return 0;

}

测试结果:

a(b(c,d),e(f,g))#
a b c d e f g

请按任意键继续. . .

版权声明:本文为【借你一秒】原创文章,转载请标明出处。

时间: 2024-10-11 20:36:38

[数据结构]二叉树之二叉链表的类模板实现的相关文章

数据结构之---C语言实现二叉树的二叉链表存储表示

//二叉树的二叉链表存储表示 //杨鑫 #include <stdio.h> #include <stdlib.h> #define max(a, b) a > b ? a : b //自定义max()函数 typedef char TELemType; //定义结二叉树的构体 typedef struct BTree { TELemType data; struct BTree *lChild; struct BTree *rChild; }BinTree; //二叉树的创

二叉树的二叉链表存储结构及C++实现

前言:存储二叉树的关键是如何表示结点之间的逻辑关系,也就是双亲和孩子之间的关系.在具体应用中,可能要求从任一结点能直接访问到它的孩子. 一.二叉链表 二叉树一般多采用二叉链表(binary linked list)存储,其基本思想是:令二叉树的每一个结点对应一个链表结点链表结点除了存放与二叉树结点有关的数据信息外,还要设置指示左右孩子的指针.二叉链表的结点结构如下图所示: 二叉树结点结构 lchild data rchild 其中,data为数据域,存放该结点的数据信息: lchild为左指针域

二叉树的二叉链表表示和实现

二叉树的二叉链表存储结构 typedef struct BiTNode { TElemType data; BiTNode * lchild, *rchild;//左右孩子指针 }BiTNode, * BiTree; 二叉链表的22个基本操作 #define ClearBiTree DestroyBiTree//清空二叉树和销毁二叉树的操作一样 void InitBiTree(BiTree &T){ T = NULL; } void DestroyBiTree(BiTree &T){ if

二叉树的二叉链表存储

1. 版本信息 (1)CentOS 6.4发行版64位,uname -a 显示如下: Linux localhost.localdomain 3.11.6 #1 SMP Sat Nov 2 23:25:40 KST 2013 x86_64 x86_64 x86_64 GNU/Linux (2)Eclipse: Version: Kepler Service Release 2 (3)Tomcat: apache-tomcat-7.0.53 (4)Mysql:      mysql-server-

二叉树的二叉链表存储结构

一.二叉树的二叉链表存储结构 二叉树的二叉链表存储结构及其操作应用广泛,各大IT公司面试的时候都很喜欢考察二叉树的奇异操作,但是万变不离其宗,只要熟练掌握二叉树的二叉链表存储结构及其基本操作,其它奇异操作根据需要进行变换即可.如下所示: typedef char TElemType; TElemType Nil = ' '; typedef struct BiTNode { TElemType data; // 结点的值 BiTNode *lchild, *rchild; // 左右孩子指针 }

二叉树的二叉链表存储及其Java实现

二叉链表存储的思想是让每个节点都记住它的左.右两个子节点,为每个节点增加left.right两个指针,分别引用该节点的左.右两个子节点,如图所示: 其中,每个节点大致有如下定义: class Node{ T data; Node left; Node right; } 对于这种二叉链表存储的二叉树,如果程序需要,为指定节点添加子节点也非常容易,让父节点的left.right引用指向新节点即可. Java实现代码: package com.liuhao.DataStructures; public

_DataStructure_C_Impl:二叉树的二叉链表存储结构

// _DataStructure_C_Impl: #include<stdio.h> #include<stdlib.h> #define MaxSize 100 typedef char DataType; typedef struct Node{ //二叉链表存储结构类型定义 DataType data; //数据域 struct Node *lchild; //指向左孩子结点 struct Node *rchild; //指向右孩子结点 }*BiTree,BitNode;

建立二叉树(二叉链表存储)

#include<stdio.h> #include<stdlib.h> //二叉链表 //typedef struct BitLink { // int data; // struct BitLink* leftChild; //左指针 // struct BitLink* rightChild; //右指针 //}bitlink; //用二叉链表存储方式建树 typedef struct BitTree { int data; struct BitTree* LChild; /

[数据结构]线性表之单链表的类模板实现

类的具体实现如下: ///////////////////////// #include"LinearList.h" #include <iostream> #include <cstdlib> using namespace std; template<class T> struct LinkNode //链表节点类 { T data; LinkNode<T>* link; LinkNode(LinkNode<T>* ptr