二叉树数组表示
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;
}
}
}