二叉树数组表示

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;
			}
		}
	}