二叉树数组表示


Tree.h:

#ifndef _TREE_H_
#define _TREE_H_

#include <iostream>
using namespace std;

typedef int ElemType;   //元素类型

class CTree
{
public:
    CTree(int isize,ElemType* root);                                                            //创建树
    ~CTree();                                                                                               //销毁树
    ElemType* SearchNode(int nodeIndex);                                             //搜索结点
    bool AddNode(int nodeIndex,int direction,ElemType* node);           //添加(孩子)结点
    bool DelNode(int nodeIndex,ElemType* node);                              //删除结点
    void Traverse();                                                                                  //遍历
private:
    ElemType *m_tree;
    int m_isize;
};

#endif

Tree.cpp:

#include "Tree.h"

//创建树 size-元素个数 root-根
CTree::CTree(int isize,ElemType* root)
{
    m_isize = isize;
    m_tree = new ElemType[m_isize];
    for (int i = 0 ; i < m_isize ; i++)
    {
        m_tree[i] = 0;
    }
    m_tree[0] = *root;      //确定根结点 
}

//销毁树
CTree::~CTree()
{
    delete []m_tree;
    m_tree = NULL;      //养成习惯,delte之后,将野指针赋值为空
}

//根据节点序号搜索结点
ElemType* CTree::SearchNode(int nodeIndex)
{
    if(nodeIndex < 0 || nodeIndex > m_isize)
    {
        return NULL;
    }
    if (m_tree[nodeIndex] == 0)
    {
        return NULL;
    }
    return &m_tree[nodeIndex];

}

//添加指定结点的孩子结点 direction:0-左孩子 1-右孩子
bool CTree::AddNode(int nodeIndex,int direction,ElemType* node)
{
    if(nodeIndex < 0 || nodeIndex > m_isize)
    {
        return false;
    }
    if (m_tree[nodeIndex] == 0)
    {
        return false;
    }
    switch(direction)
    {
    case 0:
        m_tree[nodeIndex * 2 + 1] = *node;
        break;
    case 1:
        m_tree[nodeIndex * 2 + 2] = *node;
        break;
    default:
        cout<<"参数使用错误!"<<endl;
        return false;
    }
    return true;
}

//删除结点
bool CTree::DelNode(int nodeIndex,ElemType* node)
{
    if(nodeIndex < 0 || nodeIndex > m_isize)
    {
        return false;
    }
    if (m_tree[nodeIndex] == 0)
    {
        return false;
    }
    *node = m_tree[nodeIndex];
    m_tree[nodeIndex] = 0;
    return true;
}

//遍历--层次遍历
void CTree::Traverse()
{
    for (int i = 0 ;i < m_isize ; i++)
    {
        cout<<" "<<m_tree[i];
    }
}

TreeTest.cpp:

int main()
{
    ElemType root = 3;
    CTree *tree = new CTree(10,&root);

    //添加元素
    ElemType node1 = 7;
    ElemType node2 = 5;
    tree->AddNode(0,0,&node1);
    tree->AddNode(0,1,&node2);

    ElemType node3 = 11;
    ElemType node4 = 2;
    tree->AddNode(1,0,&node3);
    tree->AddNode(1,1,&node4);

    ElemType node5 = 0;
    ElemType node6 = 6;
    tree->AddNode(2,0,&node5);
    tree->AddNode(2,1,&node6);

    //遍历
    tree->Traverse();

    //删除1号元素
    ElemType delnode = 0;
    if (tree->DelNode(1,&delnode))
    {
        cout<<endl<<"删除元素:"<<delnode<<"后: ";
        tree->Traverse();
    }

    //查找6号元素
    ElemType *findnode = NULL;
    findnode = tree->SearchNode(6);
    cout<<endl<<"6号元素:"<<*findnode<<endl;

    return 0;
}

运行结果:

二叉树链表表示


先定义结点类型和属性:
Node.h:

#ifndef _NODE_H_
#define _NODE_H_

typedef int DataType;   //数据类型

class CNode
{
public:
    CNode();
    CNode(int index,DataType data);

    CNode * SearchNode(int nodeIndex);  //返回结点或其子结点
    void DelNode();     //删除结点
    void PreorderTraverse();    //前序遍历
    void InorderTraverse();     //中序遍历
    void PostorderTraverse();   //后序遍历

    int index;
    DataType data;
    CNode *pLChild;
    CNode *pRChild;
    CNode *pParent;

};

#endif

Node.cpp:

#include "Node.h"
#include <iostream>
using namespace std;

CNode::CNode()
{
    index = 0;
    data = 0;
    pLChild = NULL;
    pRChild = NULL;
    pParent = NULL;
}

CNode::CNode( int index , DataType data )
{
    this->index = index;
    this->data = data;
    pLChild = NULL;
    pRChild = NULL;
    pParent = NULL;
}

CNode * CNode::SearchNode( int nodeIndex )
{
    CNode *ptemp = new CNode();

    if (this->index == nodeIndex)
    {
        return this;
    }
    if (this->pLChild != NULL)
    {
        if(this->pLChild->index == nodeIndex)
        {
            return this->pLChild;
        }
        else
        {
            ptemp = this->pLChild->SearchNode(nodeIndex);
            if (ptemp != NULL)
            {
                return ptemp;
            }
        }
    }
    if (this->pRChild != NULL)
    {
        if(this->pRChild->index == nodeIndex)
        {
            return this->pRChild;
        }
        else
        {
            ptemp = this->pRChild->SearchNode(nodeIndex);
            if (ptemp != NULL)
            {
                return ptemp;
            }
        }
    }
    return NULL;    
}

void CNode::DelNode()
{
    //先判断孩子结点是否存在,如果存在,删除
    if (this->pLChild != NULL)
    {
        this->pLChild->DelNode();
    }
    if (this->pRChild != NULL)
    {
        this->pRChild->DelNode();
    }

    //找到父节点,将当前结点置为NULL
    if (this->pParent != NULL)
    {
        if (this->pParent->pLChild == this)
        {
            //如果是左孩子
            this->pParent->pLChild = NULL;
        }
        else //是右孩子
        {
            this->pParent->pRChild = NULL;
        }
    }
    delete this;
}

//前序遍历(递归实现),根左右
void CNode::PreorderTraverse()
{
    cout<<this->index<<": "<<this->data<<"  ";
    if (this->pLChild != NULL)
    {
        this->pLChild->PreorderTraverse();
    }
    if(this->pRChild != NULL)
    {
        this->pRChild->PreorderTraverse();
    }

}

//中序遍历(递归实现),左根右
void CNode::InorderTraverse()
{
    if (this->pLChild != NULL)
    {
        this->pLChild->InorderTraverse();
    }
    cout<<this->index<<": "<<this->data<<"  ";
    if(this->pRChild != NULL)
    {
        this->pRChild->InorderTraverse();
    }
}

//后序遍历(递归实现),左右根
void CNode::PostorderTraverse()
{
    if (this->pLChild != NULL)
    {
        this->pLChild->PostorderTraverse();
    }
    if(this->pRChild != NULL)
    {
        this->pRChild->PostorderTraverse();
    }
    cout<<this->index<<": "<<this->data<<"  ";
}

再定义树的相关属性和方法:
LinkTree.h:

#ifndef _LINKTREE_H_
#define _LINKTREE_H_

#include "Node.h"

class CTree
{
public:
    CTree();                                                        //创建树
    ~CTree();                                                       //销毁树
    CNode* SearchNode(int nodeIndex);                               //搜索结点
    bool AddNode(int nodeIndex,int direction,CNode* pNode);         //添加(孩子)结点
    bool DelNode(int nodeIndex,CNode* pNode);                       //删除结点
    void PreorderTraverse();                                        //先序遍历
    void InorderTraverse();                                         //中序遍历
    void PostorderTraverse();                                       //后序遍历
private:
    CNode *m_pRoot;
};

#endif

LinkTree.cpp:

#include "LinkTree.h"
#include <iostream>
using namespace std;

CTree::CTree()
{
    m_pRoot = new CNode();
}

CTree::~CTree()
{
    DelNode(0,NULL);
//  m_pRoot->DelNode();
}

//搜索结点
CNode* CTree::SearchNode( int nodeIndex )
{
    return m_pRoot->SearchNode(nodeIndex);
}

//添加结点
bool CTree::AddNode( int nodeIndex,int direction,CNode* pNode )
{
    CNode *pTemp = SearchNode(nodeIndex);
    if (pTemp == NULL)
    {
        return false;
    }

    CNode *newNode = new CNode(pNode->index,pNode->data);
    newNode->pParent = pTemp;
    if (newNode == NULL)
    {
        //申请空间失败
        return false;
    }

    if (direction == 0 )
    {
        pTemp->pLChild = newNode;
    }
    else if (direction == 1)
    {
        pTemp->pRChild = newNode;
    }
    return true;
}

//删除结点及其子孙节点 pNode取出要删除的结点(pNode=NULL 表示不取结点)
bool CTree::DelNode( int nodeIndex,CNode* pNode )
{
    CNode *pTemp = SearchNode(nodeIndex);
    if (pTemp == NULL)
    {
        return false;
    }

    if(pNode != NULL)
    {
        pNode->data = pTemp->data;
    }

    pTemp->DelNode();
    return true;
}

void CTree::PreorderTraverse()
{
    m_pRoot->PreorderTraverse();
}

void CTree::InorderTraverse()
{
    m_pRoot->InorderTraverse();
}

void CTree::PostorderTraverse()
{
    m_pRoot->PostorderTraverse();
}

LinkTreeTest.cpp:

int main()
{
    CNode *node1 = new CNode(1,5);
    CNode *node2 = new CNode(2,8);
    CNode *node3 = new CNode(3,2);
    CNode *node4 = new CNode(4,6);
    CNode *node5 = new CNode(5,9);
    CNode *node6 = new CNode(6,7);

    CTree* tree = new CTree();
    tree->AddNode(0,0,node1);
    tree->AddNode(0,1,node2);
    tree->AddNode(1,0,node3);
    tree->AddNode(1,1,node4);
    tree->AddNode(2,0,node5);
    tree->AddNode(2,1,node6);

    //前序遍历
    tree->PreorderTraverse();
    cout<<endl;
    //中序遍历
    tree->InorderTraverse();
    cout<<endl;
    //后序遍历
    tree->PostorderTraverse();
    cout<<endl;

    //删除第1个节点:5
    tree->DelNode(1,NULL);
    tree->PreorderTraverse();
    cout<<endl;

    delete tree;

    return 0;
}

运行结果:

以上的遍历都是通过递归的方式实现的,如果想不用递归,那也可以使用栈,来暂时存储结点。

    //先序遍历二叉树,非递归实现。
    void PreOrderNotRescure(pTNode T,void(*visit)(ElemType))
    {
        Stack<pTNode> S;
        pTNode p = T;
        while (p != NULL || !S.StackEmpty())
        {
            if (p != NULL)
            {
                S.Push(p);
                visit(p->data);
                p = p->lchild;     //沿着左子树一直往下走
            }
            else
            {
            S.Pop(p);
            p = p->rchild;
            }
        }
    }