【数据结构】树形结构

一 树的逻辑特征

非线性结构

重要点

  1. 树中的节点,只有一个直接前驱,有若干后继
  2. 根节点没有前驱,叶节点没有后继
  3. 有序树和无序树,同一个节点下,它的兄弟之间是否存在长幼之分

二 树型结构概述

一 树型结构的基本术语

  1. 节点的度:一个节点儿子的个数被称为该节点的度
  2. 树的度:一棵树中,儿子最多的节点的度称为树的度
  3. 叶节点:度为0的节点
  4. 分支节点:度不为0的节点
  5. 节点的层:从根开始定义,根为第一层
  6. 树的高度或深度:树中节点的最大层次
  7. 森林:有若干个不相交的树的集合被称为森林
  8. 有序树和无序树:树中任意节点的子节点有顺序关系,这种树被称为有序树。反之被称为无序树

三 树的递归性

一棵非空树是由若干子树组成,子树又可以由若干子树组成

一 树形结构示意图

树形结构示意图

二 实例

1 定义类去封装

template<typename Type>
class CTree_List{
public:
	CTree_List();
	~CTree_List()
	{
		this->clear(); //都写了clear了,析构函数调用它就行了
	}
private:
	struct TreeNode{
		Type data;
		TreeNode* pFront;
		TreeNode* pBehind;
		TreeNode* pSide;
	};
	TreeNode* pRoot;
public:
	void clear();
	bool find(Type const& target);
	void insert(Type const& Data, Type const& Reference, bool isBehind);
	void pop(Type const& Reference, bool isSonFinal);
private:
	void _clear(TreeNode*& root);
	TreeNode* _find(TreeNode* root, Type const& target)
	{
		if (root)
		{
			if (root->data == target)
			{
				return root;
			}
			TreeNode* temp = _find(root->pSide, target);
			if (temp)
			{
				return temp;
			}
			return _find(root->pBehind, target);
		}
		return nullptr;
	}
	void _pop(TreeNode* p, TreeNode* pTemp)
	{
		if ((!pTemp->pSide))
		{
			if (pTemp->pBehind)
			{
				p->pBehind = pTemp->pBehind;
				pTemp->pBehind->pFront = p;
			}
			else
			{
				p->pBehind = nullptr;
			}
		}		
		int num = 0;
		while (pTemp->pSide)
		{
			pTemp = pTemp->pSide;
			if (!num)
			{
				p = p->pBehind;
				++num;
				continue;
			}
			p = p->pSide;
		}
		p->pSide = nullptr;
		delete pTemp;
		pTemp = nullptr;
	}
};

2 初始化

template<typename Type>
CTree_List<Type>::CTree_List()
{
	this->pRoot = nullptr;
}

3 清除函数

template<typename Type>
void CTree_List<Type>::clear()
{
	this->_clear(this->pRoot);
}
template<typename Type>
void CTree_List<Type>::_clear(TreeNode*& root)
{
	if (this->pRoot && root->pSide && root->pBehind)
	{
		_clear(root->pSide);
		_clear(root->pBehind);
		delete root;
		root = nullptr;
	}
}

4 查询节点

template<typename Type>
bool CTree_List<Type>::find(Type const& target)
{
	if (_find(this->pRoot, target))
		return true;
	return false;
}
//此时的TreeNode要加上类名限定
template<typename Type>
CTree_List<Type>::TreeNode* CTree_List<Type>::_find(TreeNode* root, Type const& target)
{
    if (root)
    {
        if (root->data == target)
        {
            return root;
        }
        TreeNode* temp = _find(root->pSide, target);
        if (temp)
        {
            return temp;
        }
        return _find(root->pBehind, target);
    }
    return nullptr;
}

5 插入节点

template<typename Type>
void CTree_List<Type>::insert(Type const& Data, Type const& Reference, bool isBehind)
{
    //创建一个新的节点
	TreeNode* pInsert = new TreeNode;
	pInsert->data = Data;
	pInsert->pFront = nullptr;
	pInsert->pSide = nullptr;
	pInsert->pBehind = nullptr;

	if (this->pRoot)
	{
		TreeNode* findNode = _find(this->pRoot, Reference);
		if (findNode)
		{
			if (isBehind)
			{
				if (findNode->pBehind)
				{
					TreeNode* tempNode = findNode->pBehind;
					while (tempNode->pSide)
					{
						tempNode = tempNode->pSide;
					}
					tempNode->pSide = pInsert;
					pInsert->pFront = findNode;
				}
				else
				{
					findNode->pBehind = pInsert;
					pInsert->pFront = findNode;
				}
			}
			else
			{
				TreeNode* pTemp = findNode;
				while (pTemp->pSide)
				{
					pTemp = pTemp->pSide;
				}
				pTemp->pSide = pInsert;
				pInsert->pFront = findNode->pFront;
			}
		}
		else
		{
			TreeNode* pTemp = this->pRoot;
			while (pTemp->pBehind)
			{
				pTemp = pTemp->pBehind;
			}
			pTemp->pBehind = pInsert;
			pInsert->pFront = pTemp;
		}
	}
	else
	{
		this->pRoot = pInsert;
	}
}

6 删除节点

//pop
template<typename Type>
void CTree_List<Type>::pop(Type const& Reference, bool isSonFinal)
{
	if (!find(Reference))
	{
		return;
	}
	if (this->pRoot)
	{
		TreeNode* pTemp = _find(this->pRoot, Reference);
		TreeNode* p = _find(this->pRoot, Reference);
		
		if (isSonFinal)    //kill his youngest son
		{
			if (pTemp->pBehind)
			{
				pTemp = pTemp->pBehind;
				_pop(p, pTemp);
			}
		}
		else if (pTemp->pBehind)   //kill his grandson
		{
			int num = 0;
			pTemp = pTemp->pBehind;

			while (pTemp->pBehind)
			{
				pTemp = pTemp->pBehind;
				if (!num)
				{
					p = p->pBehind;
					++num;
					continue;
				}
				p = p->pBehind;
			}
			_pop(p, pTemp);
		}
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

维他命C++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值