【数据结构】二叉树[通俗易懂]

【数据结构】二叉树

大家好,又见面了,我是全栈君。

二叉树节点

#pragma once
#include <stdlib.h>
template<class T>class BinaryTreeNode
{
public:
	T data;
	BinaryTreeNode<T>* leftchild;
	BinaryTreeNode<T>* rightchild;
	BinaryTreeNode():leftchild(NULL),rightchild(NULL){}
	BinaryTreeNode(T d):data(d),leftchild(NULL),rightchild(NULL){}
};

二叉树的全部操作:建树。销毁树,先序后序中序便利的递归和非递归方式层序遍历

#include "BinaryTreeNode.h"
#include <queue>
#include <stack>
#include <iostream>
using namespace std;

/*
void CreatePreOrder(BinaryTreeNode<T>** root)
void LevelOrderTraverse()//层序遍历
void PreOrderTraverse(BinaryTreeNode<T>* root)//先序遍历递归
void PreOrderTraverse()//先序遍历非递归算法
void InOrderTraverse()//中序遍历的非递归方法
void PostOrderTraverse()//后序遍历非递归方法
int depth()//树深度
BinaryTreeNode<T>* Parent(BinaryTreeNode<T>*root,BinaryTreeNode<T>*node)//返回节点的双亲
BinaryTreeNode<T>* SiblingNode(BinaryTreeNode<T>*node)//返回兄弟节点
*/

template<class T>class BinaryTree
{
public:
	BinaryTreeNode<T>* root;
	BinaryTree():root(NULL){}//空树
/********************************先序创建链表****************************************/
	void CreatePreOrder(BinaryTreeNode<T>** root)//或者BinaryTreeNode<T>* &root以下依次改变
	{
		char d;
		cin>>d;
		if (d=='#')
			(*root) = NULL;
		else
		{
			*root = new BinaryTreeNode<T>(d);
			CreatePreOrder(&(*root)->leftchild);
			CreatePreOrder(&(*root)->rightchild);		
		}
 	}
/********************************层序遍历****************************************/
	void LevelOrderTraverse()
	{
		if (root==NULL)
			return;
		BinaryTreeNode<T>* p;
		queue<BinaryTreeNode<T>*> myQueue;
		myQueue.push(root);
		myQueue.push(NULL);
		while (!myQueue.empty())
		{
			p=myQueue.front();
			myQueue.pop();
			if (p==NULL)
			{
				if (myQueue.empty())
					break;
				cout<<endl;
				myQueue.push(NULL);
			}
			else
			{
				cout<<p->data;
				if (p->leftchild)
					myQueue.push(p->leftchild);
				if (p->rightchild)
				myQueue.push(p->rightchild);
			}		
		}	
	}
/********************************先序遍历递归****************************************/
	void PreOrderTraverse(BinaryTreeNode<T>* root)
	{
		if (root)
		{
			cout<<root->data;
			PreOrderTraverse(root->leftchild);
			PreOrderTraverse(root->rightchild);
		}
	}
/********************************中序遍历递归****************************************/
	void InOrderTraverse(BinaryTreeNode<T>* root)
	{
		if (root)
		{
			InOrderTraverse(root->leftchild);
			cout<<root->data;
			InOrderTraverse(root->rightchild);
		}
	}
	/********************************后序遍历递归****************************************/
	void PostOrderTraverse(BinaryTreeNode<T>* root)
	{
		if (root)
		{
			PostOrderTraverse(root->leftchild);
			PostOrderTraverse(root->rightchild);
			cout<<root->data;
		}
	}
/********************************先序遍历非递归****************************************/
	void PreOrderTraverse()
	{
		if (root)
		{
			BinaryTreeNode<T>* p;
			stack<BinaryTreeNode<T>*> myStack;
			myStack.push(root);
			while (!myStack.empty())
			{
				p=myStack.top();
				myStack.pop();
				cout<<p->data;
				if (p->rightchild)
					myStack.push(p->rightchild);
				if (p->leftchild)
					myStack.push(p->leftchild);
			}
		}
	}
/********************************中序遍历非递归****************************************/
	void InOrderTraverse()
	{
		if (root==NULL)
			return;
		BinaryTreeNode<T>* p;
		stack<BinaryTreeNode<T>*> myStack;
		myStack.push(root);
		while (!myStack.empty())
		{
			while (myStack.top())
				myStack.push(myStack.top()->leftchild);
			myStack.pop();
			if (!myStack.empty())
			{
				p=myStack.top();
				myStack.pop();
				cout<<p->data;
				myStack.push(p->rightchild);
			}
		}
	}
/********************************后序遍历非递归****************************************/	
	void PostOrderTraverse()
	{
		if (root==NULL)
			return;
		stack<BinaryTreeNode<T>*> myStack1;
		stack<BinaryTreeNode<T>*> myStack2;
		BinaryTreeNode<T> * p;
		myStack1.push(root);
		while (!myStack1.empty())
		{
			p=myStack1.top();
			myStack1.pop();
			myStack2.push(p);
			if (p->leftchild)
				myStack1.push(p->leftchild);
			if(p->rightchild)
				myStack1.push(p->rightchild);
		}
		while (!myStack2.empty())
		{
			p=myStack2.top();
			myStack2.pop();
			cout<<p->data;
		}
	}
/********************************树的深度****************************************/
	int depth(BinaryTreeNode<T>* root)
	{
		int dep;
		if (root==NULL)
			dep=0;
		else
		{
			dep=1+(depth(root->leftchild)>depth(root->rightchild)?depth(root->leftchild):depth(root->rightchild));
		}
		return dep;
	}
/********************************返回双亲节点****************************************/
	BinaryTreeNode<T>* Parent(BinaryTreeNode<T>*root,BinaryTreeNode<T>*node)
	{
		if (root==NULL || root==node)
			return NULL;
		if (root->leftchild==node||root->rightchild==node)
		{
			return root;
		}
		else if(Parent(root->leftchild,node))
		{
			return Parent(root->leftchild,node);
		}
		else
			return Parent(root->rightchild,node);
	}
/********************************返回双亲节点(重载)****************************************/
	BinaryTreeNode<T>* ParentPre(BinaryTreeNode<T>*root,BinaryTreeNode<T>*node)//通过遍历树来搜索
	{
		if (root==node||root==NULL)
			return NULL;
		if(root)
		{
			if (root->leftchild==node||root->rightchild==node)
				return root;
			if (ParentPre(root->leftchild,node))
				return	ParentPre(root->leftchild,node);
			else
				return ParentPre(root->rightchild,node);
		}
	}
/********************************返回兄弟节点****************************************/
	BinaryTreeNode<T>* SiblingNode(BinaryTreeNode<T>*node)
	{
		BinaryTreeNode<T>*p=Parent(root,node);
		if (p)
		{
			if (p->leftchild==node)
				return p->rightchild;
			else
				return p->leftchild;
		}
		return NULL;
		
	}
/********************************销毁树****************************************/
	void DestroyTree(BinaryTreeNode<T>*root)
	{
		if (root!=NULL)
		{
			DestroyTree(root->leftchild);
			DestroyTree(root->rightchild);
			delete root;
		}
		root=NULL;
	}
};

【数据结构】二叉树[通俗易懂]

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115881.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • python缩进错误提示(python缩进讲解)

    参考链接:Python语句,缩进和注释广告关闭腾讯云11.11云上盛惠,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元!学习python与其他语言最大的区别就是,python的代码块不使用大括号{}来控制类,函数以及其他逻辑判断。python最具特色的就是用缩进来写模块。缩进…有时候,你觉得两行代码的缩进是一样的,但编译器仍然报错。这可能是因为一个地方使用空格来缩进,而另一个地方使用了tab键来缩进。碰到这种情况要统一…..

    2022年4月10日
    251
  • vue实现上传文件[通俗易懂]

    vue实现上传文件[通俗易懂]Vue实现上传文件

    2022年8月16日
    9
  • ASP.NET知识点总结[通俗易懂]

    ASP.NET知识点总结[通俗易懂]ASP.NET知识点总结1、ASP.Net的特色与优势2、几对概念3、解决方案构成4、系统对象与状态管理5、控件的分类6、站点地图7、系统导航8、母版页9、系统框架10、数据绑定11、数据源控件12、数据绑定控件GridView数据查询与展示、删除DetailsView展示多选光棒效果13、数据验证控件14、文件上载15、其他服务器控件DataList查询与展示16、基于SQL语句分页17…

    2022年7月11日
    16
  • HTML占位符_怎么使用占位符

    HTML占位符_怎么使用占位符HTML空格位占位符&amp;#32;——普通的英文半角空格;&amp;#160;、&amp;nbsp;、&amp;#xAO;、no-breakspace——普通的英文半角空格但不换行&amp;#160;——中文全角空格(一个中文宽度)&amp;#8194;、&amp;ensp——en空格(半个中文宽度)&amp;#8195;、&amp;emsp…

    2022年9月27日
    2
  • string转map_中将转业可以任省长吗

    string转map_中将转业可以任省长吗暴力的直接Map对象toString()存,后面取出是就是用再转换为MapString转Map:JSONObjectjsonobject=JSONObject.fromObject(str);rMap=(Map<String,Object>)jsonobject;但很多时候并不能直接将Map对象的toString()而是应该转换为JsonObject后再调用toString()后存入就正常了Map<String,Object>map=newHashMa

    2025年8月31日
    5
  • JEPLUS之项目环境布署——JEPLUS软件快速开发平台

    JEPLUS之项目环境布署——JEPLUS软件快速开发平台

    2021年6月8日
    89

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号