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

【数据结构】二叉树

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

二叉树节点

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


相关推荐

  • adb安装TWRP

    adb安装TWRP1.刷入TWRPfastbootflashrecoverytwrp-3.0.2-0-hammerhead.imgadb进入fastbootadbrebootbootloader刷完TWRP后进入TWRPfastbootflashrecoveryrecovery.img

    2022年5月16日
    270
  • SVN常用命令之checkout

    SVN常用命令之checkout

    2021年10月21日
    53
  • strsep的作用

    strsep的作用在下面这个code中通过strsep将p表示的字符串一“,”分开,例如12,34,56.会先返回12,然后是34,最后是56while((id=strsep(&p,”,”)))我们看看strsep的实现char*strsep(char**s,constchar*ct){   char*sbegin=*s;   char*end;  

    2025年6月26日
    3
  • stata–异方差检验

    stata–异方差检验异方差检验有两种方法:1、残差图2、white检验1、残差图(一般不用这个,这个只是粗略)代码:regyfdirvfplot,yline(0)rvpplotfdi,yline(0)(1)对y和fdi回归:(2)画出残差与拟合值(ybar)散点图:(3)画出残差与fdi(自变量x)的散点图:2、white检验:代码:sscinstallwhitetstestatimtest,white…

    2025年7月6日
    7
  • 使用memset初始化数组

    使用memset初始化数组写在前面的ATTENTION:用memset初始化非char型(eg.int型、float型…)数组时,假如初始化值非0,可能导致错误的结果。先举个通常用法的栗子,将int型数组arr的元素初始化为0:intarr[5];memset(arr,0,sizeof(int)*5);假如初始值不为0,会如何呢?例如设置为1:使用memset(arr,1,sizeof(int…

    2022年10月21日
    4
  • 安卓app十大开发框架_web应用开发学什么

    安卓app十大开发框架_web应用开发学什么国内第一本基于Android2.0的经典著作,5大专业社区联袂推荐,权威性毋庸置疑!·Android开发与传统的J2ME开发有何相似与不同?·如何通过SharedPreferences、Files、Network和SQLite等方式高效实现Android数据的存储?又如何通过ContentProviders轻松地实现Android数据的共享?·如何使用OpenCore、MediaPlayer、MediaRecorder方便快速地开发出包含音频和视频等流媒体的丰富多媒体应用?·如何

    2022年5月3日
    45

发表回复

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

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