介绍两种实现二叉树的方法,数组和链表,例如实现下面这颗树
头文件TreeArray.h
/*
用数组实现二叉树
*/
#pragma once
//节点的插入方向
enum DIRECTION
{
LEFT,
RIGHT
};
class TreeArray
{
public:
TreeArray(int size, int *pRoot); //构造创建树
~TreeArray(); //销毁树
int *SearchNode(int nodeIndex);
bool AddNode(int nodeIndex, DIRECTION dirc, int *pNode);
bool DeleteNode(int nodeIndex, int *pNode);
void TreeTraverse(); //遍历树
private:
int *m_pTree;
int m_iSize; //树的容量
};
TreeArray.cpp
#include "TreeArray.h"
#include
using namespace std;
TreeArray::TreeArray(int size,int *pRoot)
{
if (size > 0)
{
m_iSize = size;
m_pTree = new int[size];
for (int i = 0; i < size; i++)
{
m_pTree[i] = 0;
}
m_pTree[0] = *pRoot;
}
else
{
m_iSize = 0;
m_pTree = nullptr;
}
}
TreeArray::~TreeArray()
{
if (m_pTree != nullptr)
{
delete[] m_pTree;
m_pTree = nullptr;
}
}
int * TreeArray::SearchNode(int nodeIndex)
{
if (nodeIndex < m_iSize && m_pTree >= 0)
{
if (m_pTree[nodeIndex] == 0) //0表示空节点
{
return nullptr;
}
}
else
{
return nullptr;
}
return &m_pTree[nodeIndex];
}
bool TreeArray::AddNode(int nodeIndex, DIRECTION dirc, int * pNode)
{
if (nodeIndex < 0 || nodeIndex >= m_iSize)
{
return false;
}
if (m_pTree[nodeIndex] == 0)
{
return false;
}
if (dirc == LEFT)
{
int insertId = nodeIndex * 2 + 1;
if (insertId >= m_iSize)
{
return false;
}
if (m_pTree[insertId] != 0)
{
return false;
}
m_pTree[insertId] = *pNode;
}
else if (dirc == RIGHT)
{
int insertId = nodeIndex * 2 + 2;
if (insertId >= m_iSize)
{
return false;
}
if (m_pTree[insertId] != 0)
{
return false;
}
m_pTree[insertId] = *pNode;
}
return true;
}
bool TreeArray::DeleteNode(int nodeIndex, int * pNode)
{
if (nodeIndex < 0 || nodeIndex >= m_iSize)
{
return false;
}
if (m_pTree[nodeIndex] == 0)
{
return false;
}
*pNode = m_pTree[nodeIndex];
m_pTree[nodeIndex] = 0;
return true;
}
void TreeArray::TreeTraverse()
{
for (int i = 0; i
main函数测试
#include
#include "TreeArray.h"
using namespace std;
int main()
{
int root = 666;
TreeArray *pTree = new TreeArray(10, &root);
int node1 = 500;
int node2 = 800;
pTree->AddNode(0, LEFT, &node1);
pTree->AddNode(0, RIGHT, &node2);
int node3 = 200;
int node4 = 600;
pTree->AddNode(1, LEFT, &node3);
pTree->AddNode(1, RIGHT, &node4);
int node5 = 900;
int node6 = 700;
pTree->AddNode(2, LEFT, &node5);
pTree->AddNode(2, RIGHT, &node6);
//遍历
pTree->TreeTraverse();
//查找
int *pValue = pTree->SearchNode(3);
cout << "index = 3的节点值是" << *pValue << endl;
//删除
int dValue = 0;
pTree->DeleteNode(6, &dValue);
//遍历
pTree->TreeTraverse();
delete pTree;
return 0;
}
运行结果
用链表实现二叉树,得先定义好二叉树的节点类型,根据二叉树的性质,节点得有5个属性:索引、数据 、左孩子指针、右孩子指针 、父结点指针 。如下所示:
struct Node
{
int index;
int data;
Node *pLChild; //左子树
Node *pRChild; //右字数
Node *pParent; //父节点
};
还得实现3种遍历方式,使用递归遍历是比较方便的。具体代码如下
Tree.h
#ifndef TREE_H
#define TREE_H
#include
using namespace std;
//数的节点
struct Node
{
Node(int _data = 0);
Node *SearchNode(int nodeIndex);
void DeleteNode();
void PreOrderTraversal();
void MiddleOrderTraversal();
void LastOrderTraversal();
int index;
int data;
Node *pLChild; //左子树
Node *pRChild; //右字数
Node *pParent; //父节点
};
//节点的插入方向
enum DIRECTION
{
LEFT,
RIGHT
};
//二叉树
class Tree
{
public:
Tree(int data = 0); //创建树
~Tree(); //销毁树
Node *SearchNode(int nodeIndex); //搜索结点
bool AddNode(int nodeIndex, DIRECTION direction, Node *pNode); //添加结点
bool DeleteNode(int nodeIndex, Node *pNode); //删除结点
void PreOrderTraversal(); //前序遍历
void MiddleOrderTraversal(); //中序遍历
void LastOrderTraversal(); //后序遍历
private:
Node *m_pRoot;
};
#endif
Tree.cpp
#include "Tree.h"
Node::Node(int _data)
{
index = 0;
data = _data;
pLChild = NULL;
pRChild = NULL;
pParent = NULL;
}
Node *Node::SearchNode(int nodeIndex)
{
if (this->index == nodeIndex)
{
return this;
}
Node *temp = NULL;
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::MiddleOrderTraversal()
{
if (this->pLChild != NULL)
{
this->pLChild->MiddleOrderTraversal();
}
cout << this->index << " " << this->data << endl;
if (this->pRChild != NULL)
{
this->pRChild->MiddleOrderTraversal();
}
}
void Node::LastOrderTraversal()
{
if (this->pLChild != NULL)
{
this->pLChild->LastOrderTraversal();
}
if (this->pRChild != NULL)
{
this->pRChild->LastOrderTraversal();
}
cout << this->index << " " << this->data << endl;
}
Tree::Tree(int data)
{
m_pRoot = new Node(data);
}
Tree::~Tree()
{
//DeleteNode(0, NULL);
m_pRoot->DeleteNode();
}
Node *Tree::SearchNode(int nodeIndex)
{
return m_pRoot->SearchNode(nodeIndex);
}
bool Tree::AddNode(int nodeIndex, DIRECTION 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 == LEFT)
{
temp->pLChild = node;
}
if(direction == RIGHT)
{
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::MiddleOrderTraversal()
{
m_pRoot->MiddleOrderTraversal();
}
void Tree::LastOrderTraversal()
{
m_pRoot->LastOrderTraversal();
}
main方法测试:
#include
#include "Tree.h"
int main(void)
{
Node *node1 = new Node();
node1->index = 1;
node1->data = 500;
Node *node2 = new Node();
node2->index = 2;
node2->data = 800;
Node *node3 = new Node();
node3->index = 3;
node3->data = 200;
Node *node4 = new Node();
node4->index = 4;
node4->data = 600;
Node *node5 = new Node();
node5->index = 5;
node5->data = 900;
Node *node6 = new Node();
node6->index = 6;
node6->data = 700;
Tree *tree = new Tree(666);
tree->AddNode(0, LEFT, node1);
tree->AddNode(0, RIGHT, node2);
tree->AddNode(1, LEFT, node3);
tree->AddNode(1, RIGHT, node4);
tree->AddNode(2, LEFT, node5);
tree->AddNode(2, RIGHT, node6);
//tree->DeleteNode(6, NULL);
//tree->DeleteNode(5, NULL);
tree->DeleteNode(2, NULL);
tree->PreOrderTraversal();
//tree->MiddleOrderTraversal();
//tree->LastOrderTraversal();
delete tree;
system("pause");
return 0;
}
以上就是二叉树的两种实现方,推荐使用链表的形式。