您当前的位置: 首页 >  令狐掌门 c++

二叉树的定义与C++实现

令狐掌门 发布时间:2020-08-01 21:49:04 ,浏览量:1

        树,是有限节点的集合。生活中的树是树根在下面,数据结构中的树的根在顶部,如下图:

        公司的人员组织架构,董事长,总经理,副总。。。,这种模型可以用二叉树表示,还有一些压缩算法也用到了树结构。

树的几个概念

(1)度:有几个直接的孩子,例如,A的度是3,它有BCD三个孩子,B的度是2,它有EF两个孩子,度为0的节点也就是叶子节点(终端节点)

(2)祖先:E的祖先是B,A , 从当前节点一直往上找

(3)叶子节点:下面的一层称为叶子节点,也可以称为终端节点。

(4)根:非叶子节点。

(5)树的深度,如下图

 (6)森林:不交叉的几棵树在一起称为森林

二叉树

       所有节点的度都小于等于2的树称为二叉树。下面这几种都可以称为二叉树

1、二叉树的遍历

       3种遍历方式,根据根节点的位置,分为前序,中序,后序。

                                                                               前序:根左右,ABC

                                                                              中序 :左根右, BAC

                                                                        后序遍历:左右根, BCA

       例如下面这颗二叉树

          从根节点A在结果中的位置也可以看出是那种遍历方式。

2、二叉树的存储结构

     (1)顺序存储,类似于数组,例如下面这颗二叉树,在数组中的存储是:3561972

       数组存储时,如果节点不存在就用0表示,例如下面的,在数组中就是35019

        顺序存储可以作为一种特殊形式,有相关需求时可以采用,

     (2)链式存储,这是二叉树最好的存储形式,用一个结构体表示节点,有数据成员,指向左子树的指针,指向右子树的指针。

        

3、满二叉树与完全二叉树

       完全二叉树的定义:如果二叉树的深度为h, 除h层外,其它各层的节点数都达到最大数,且第h层的所有节点都连续集中在最左边,这种二叉树称为完全二叉树。

       

      

C++实现二叉树

     下面介绍如何用数组和链表,例如实现下面这颗树

  基于数组的二叉树实现 

  头文件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; iAddNode(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 == 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 index pLChild->PreOrderTraversal();
	}
	if (this->pRChild != NULL)
	{
		this->pRChild->PreOrderTraversal();
	}
}

void Node::MiddleOrderTraversal()
{

	if (this->pLChild != NULL)
	{
		this->pLChild->MiddleOrderTraversal();
	}

	cout index pRChild->MiddleOrderTraversal();
	}
}

void Node::LastOrderTraversal()
{
	if (this->pLChild != NULL)
	{
		this->pLChild->LastOrderTraversal();
	}

	if (this->pRChild != NULL)
	{
		this->pRChild->LastOrderTraversal();
	}

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

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

关注
打赏
1688896170
查看更多评论

令狐掌门

暂无认证

  • 1浏览

    0关注

    485博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0547s