在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2^{i-1}个结点;深度为k的二叉树至多有2^k-1个结点;对任何一棵二叉树T,如果其终端结点数为n_0,度为2的结点数为n_2,则n_0=n_2+1。
一棵深度为k,且有2^k-1个节点称之为满二叉树;深度为k,有n个节点的二叉树,当且仅当其每一个节点都与深度为k的满二叉树中,序号为1至n的节点对应时,称之为完全二叉树。
下面是顺序存储方式的二叉树实现代码:
#include <iostream>
using namespace std ;
class Tree
{
char* m_pTree;
int m_nSize; //数组大小
public:
Tree(int size, char* pRoot); //创建树
~Tree(); //销毁树
char SearchNode(int nodeindex); //根据索引寻找结点
bool AddNode(int nodeindex, int direction, char* pNode); //添加结点
bool DeleteNode(int nodeindex); //删除结点
void TreeTraverse();
};
Tree::Tree(int size,char *pRoot) //构造函数
{
m_nSize = size ;
m_pTree = new char[size] ;
for(int i=0;i<size;i++)
{
m_pTree[i] = ' ' ; //将二叉树数组所有内容赋为' ' 代表空
}
m_pTree[0] = *pRoot ;
}
Tree::~Tree() //析构函数
{
delete []m_pTree;
m_pTree = NULL;
}
char Tree::SearchNode(int nodeindex) //寻找数据 传入参数为节点位置
{
if(nodeindex < 0 || nodeindex >= m_nSize)
{
return NULL;
}
if(m_pTree[nodeindex] == ' ')
{
return NULL;
}
return m_pTree[nodeindex];
}
bool Tree::AddNode(int nodeindex, int direction, char* pNode) //添加数据 nodeindex为父结点位置
{
if(nodeindex < 0 || nodeindex >= m_nSize)
{
return false;
}
if(m_pTree[nodeindex] == 0)
{
return false;
}
if(direction == 0) //左子树
{
if(nodeindex*2+1 >= m_nSize)
{
return false;
}
if(m_pTree[nodeindex*2+1] != ' ') //该位置已有数据
{
return false;
}
m_pTree[nodeindex*2+1] = *pNode; //在该位置赋值
}
if(direction == 1) //右子树
{
if(nodeindex*2+2 >= m_nSize)
{
return false;
}
if(m_pTree[nodeindex*2+2] != ' ')
{
return false;
}
m_pTree[nodeindex*2+2] = *pNode;
}
return true;
}
bool Tree::DeleteNode(int nodeindex) //删除结点
{
if(nodeindex < 0 || nodeindex >= m_nSize)
{
return false;
}
if(m_pTree[nodeindex] == ' ') //该位置为空 无数据
{
return false;
}
//char Node = m_pTree[nodeindex];
//cout<<Node << endl ; //打印删除的结点数据
m_pTree[nodeindex] = ' '; //位置赋空
return true;
}
void Tree::TreeTraverse() //打印二叉树内容
{
for(int i = 0; i < m_nSize; i++)
{
cout<<m_pTree[i]<<" ";
}
cout<<endl ;
}
int main()
{
char Node = 'a' ;
Tree * mTree = new Tree(20,&Node) ;
char node1 = 'b';
char node2 = 'c';
mTree->AddNode(0, 0, &node1);
mTree->AddNode(0, 1, &node2);
mTree->TreeTraverse() ;
cout<<mTree->SearchNode(2)<<endl ;
mTree->DeleteNode(2);
mTree->TreeTraverse() ;
return 0 ;
}
下面是链表存储方式的二叉树实现代码:
#include <iostream>
using namespace std ;
class Node ;
class Tree
{
Node * m_pRoot;
public:
Tree(); //创建树
~Tree(); //销毁树
Node * SearchNode(int nodeindex); //根据索引寻找结点
bool AddNode(int nodeindex, int direction, Node* pNode); //添加结点
bool DeleteNode(int nodeindex, Node* pNode); //删除结点
void PreorderTraversal(); //前序遍历
void InorderTraversal(); //中序遍历
void PostorderTraversal(); //后序遍历
};
class Node
{
public:
Node();
Node* SearchNode(int nodeindex);
void DeleteNode();
void PreorderTraversal(); //前序遍历
void InorderTraversal(); //中序遍历
void PostorderTraversal(); //后序遍历
int index;
char data;
Node* pLChild;
Node* pRChild;
Node* pParent;
};
Tree::Tree() //初始化这棵树
{
m_pRoot = new Node();
}
Tree::~Tree()
{
//DeleteNode(0, NULL);
m_pRoot->DeleteNode();
}
Node* Tree::SearchNode(int nodeIndex)
{
return m_pRoot->SearchNode(nodeIndex);
}
bool Tree::AddNode(int nodeIndex, int direction, Node* pNode) //添加结点
{
Node* temp = SearchNode(nodeIndex); //根据索引寻找结点
if(temp == NULL)
{
return false;
}
Node* node = new Node();
if(node == NULL)
{
return false;
}
node->index = pNode->index;
node->data = pNode->data;
node->pParent = temp;
if(direction == 0)
{
temp->pLChild = node;
}
else if(direction == 1)
{
temp->pRChild = node;
}
return true;
}
bool Tree::DeleteNode(int nodeIndex, Node* pNode) //删除结点
{
Node* temp = SearchNode(nodeIndex);
if(temp == NULL)
{
return false;
}
if(pNode != NULL)
{
pNode->data = temp->data;
}
temp->DeleteNode();
return true;
}
void Tree::PreorderTraversal() //前序遍历
{
m_pRoot->PreorderTraversal();
}
void Tree::InorderTraversal() //中序遍历
{
m_pRoot->InorderTraversal();
}
void Tree::PostorderTraversal() //后序遍历
{
m_pRoot->PostorderTraversal();
}
Node::Node() //结点构造函数
{
index = 0;
data = ' ';
pLChild = NULL;
pRChild = NULL;
pParent = NULL;
}
Node* Node::SearchNode(int nodeindex)
{
if(this->index == nodeindex)
{
return this;
}
Node *temp;
if(this->pLChild != NULL)
{
if(this->pLChild->index == nodeindex)
{
return this->pLChild;
}
else
{
temp = this->pLChild->SearchNode(nodeindex);
if(temp != NULL)
{
return temp;
}
}
}
if(this->pRChild != NULL)
{
if(this->pRChild->index == nodeindex)
{
return this->pRChild;
}
else
{
temp = this->pRChild->SearchNode(nodeindex);
if(temp != NULL)
{
return temp;
}
}
}
return NULL;
}
void Node::DeleteNode()
{
if(this->pLChild != NULL)
{
this->pLChild->DeleteNode();
}
if(this->pRChild != NULL)
{
this->pRChild->DeleteNode();
}
if(this->pParent != NULL)
{
if(this->pParent->pLChild == this)
{
this->pParent->pLChild = NULL;
}
if(this->pParent->pRChild == this)
{
this->pParent->pRChild = NULL;
}
}
delete this;
}
void Node::PreorderTraversal()
{
cout<<this->index<<" "<<this->data<<endl;
if(this->pLChild != NULL)
{
this->pLChild->PreorderTraversal();
}
if(this->pRChild != NULL)
{
this->pRChild->PreorderTraversal();
}
}
void Node::InorderTraversal()
{
if(this->pLChild != NULL)
{
this->pLChild->InorderTraversal();
}
cout<<this->index<<" "<<this->data<<endl;
if(this->pRChild != NULL)
{
this->pRChild->InorderTraversal();
}
}
void Node::PostorderTraversal()
{
if(this->pLChild != NULL)
{
this->pLChild->PostorderTraversal();
}
if(this->pRChild != NULL)
{
this->pRChild->PostorderTraversal();
}
cout<<this->index<<" "<<this->data<<endl;
}
int main()
{
Tree *tree = new Tree();
Node* node1 = new Node;
node1->index = 1;
node1->data = 'a';
Node* node2 = new Node;
node2->index = 2;
node2->data = 'b';
Node* node3 = new Node;
node3->index = 3;
node3->data = 'c';
tree->AddNode(0, 0, node1);
tree->AddNode(0, 1, node2);
tree->AddNode(1, 0, node3);
//tree->DeleteNode(2, NULL);
//tree->PreorderTraversal();
//tree->InorderTraversal();
tree->PostorderTraversal();
delete tree;
return 0;
}