C++实现二叉树

    介绍两种实现二叉树的方法,数组和链表,例如实现下面这颗树

                                 

C++实现二叉树_第1张图片

   

一 基于数组

  头文件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;
}

      以上就是二叉树的两种实现方,推荐使用链表的形式。 

你可能感兴趣的:(#,数据结构)