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

【数据结构】二叉树

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

二叉树节点

#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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java中文输出乱码_java汉字乱码解决办法

    java中文输出乱码_java汉字乱码解决办法自从接触Java和JSP以来,就不断与Java的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。一、Java中文问题的由来Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交互产生的乱码问题。首先Java(包括J…

    2022年7月9日
    135
  • volatile指令重排[通俗易懂]

    volatile指令重排[通俗易懂]什么时候会发生指令重排?先来一个测试指令重排现象,下面这段代码会发生指令重排,也就是JVM优化了执行顺序。/***指令重排测试*/publicclassCommandDisorder{//当使用volatile关键词修饰变量时,则不会出现指令重排现象privatestatic/*volatile*/inta=0,b=0,c=0,d=0;/***测试方式:一次开启两个线程,同时修改变量*/

    2022年10月10日
    0
  • GridView删除事件

    GridView删除事件首先:转摘一段GridView删除的文章RowDeleting和RowDeleted事件RowDeleting发生在删除数据之前,RowDeleted发生在删除数据之后。使用RowDeletin

    2022年7月3日
    20
  • XAMPP最详细的安装及使用教程(图文)

    XAMPP最详细的安装及使用教程(图文)安装过程中遇到的问题:按照文章配置好后,打开phpMyAdmin修改用户密码时,提示Youdonothaveprivilegestomanipulatewiththeusers!,但是我已经是root用户登录的,后来谷歌了一下需要在phpMyAdmin目录下的的的config.inc.php文件中添加一行代码见下,我添加了死活还是不行,后来发现必须把浏览器的…

    2022年5月21日
    33
  • JAVA中ResourceBundle使用详解

    JAVA中ResourceBundle使用详解JAVA中ResourceBundle使用详解这个类主要用来解决国际化和本地化问题。国际化和本地化可不是两个概念,两者都是一起出现的。可以说,国际化的目的就是为了实现本地化。比如对于“取消”,中文中

    2022年7月4日
    26
  • SpringBoot线程池的创建、@Async配置步骤及注意事项

    SpringBoot线程池的创建、@Async配置步骤及注意事项前言:最近在做订单模块,用户购买服务类产品之后,需要进行预约,预约成功之后分别给商家和用户发送提醒短信。考虑发短信耗时的情况所以我想用异步的方法去执行,于是就在网上看见了Spring的@Async了。但是遇到了许多问题,使得@Async无效,也一直没有找到很好的文章去详细的说明@Async的正确及错误的使用方法及需要注意的地方,这里简单整理了一下遇见的问题,Sring是以配置文件的形式来开启…

    2022年6月24日
    31

发表回复

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

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