二叉树

本文介绍了满二叉树和完全二叉树的概念,并详细阐述了二叉树的三种遍历方式:前序遍历、中序遍历和后序遍历。通过递归定义解释了遍历过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(1)二叉树
基本特征:
每个结点最多只有两棵子树(不存在度大于2的结点)
② 左子树和右子树次序不能颠倒。下面是两棵不同的树:
l结点的层次:根结点的层数为0,根的孩子层数为1,依此类推。
l二叉树深度:树中结点的最大层次。
l二叉树的高度:层数最大的叶结点的层数加1。
满二叉树和完全二叉树

满二叉树:棵二叉树的任何结点,或者是树叶,或者恰有两棵非空子树,这样的二叉树称为满二叉树

完全二叉树:如果一棵深度为k,有n个结点的二叉树中各结点能够与深度为k的顺序编号的满二叉树从1n标号的结点相对应的二叉树称为完全二叉树。(只有最下两层结点可以度小于2

特点:

•叶子结点只可能在层次最大的两层上出现;
•前k-1层中的结点都是“满”的,且第k 层的结点都集中在左边。
(2)二叉树的遍历
•遍历
–按一定的规律走遍二叉树的每个结点使每个结点被访问一次,且只被访问一次
遍历方式
–深度优先遍历
按根、左子树、右子树三个部分进行访问
–广度优先遍历(逐层遍历)
•从根节点开始,向下逐层访问每个节点,在每一层次上,从左到右访问每个节点。
•基于二叉树的递归定义,这三种深度优先周游的递归定义         

     (1) 前序法(tLR次序,preorder traversal)。其递归定义是

            访问根结点;

            按前序周游左子树;

            按前序周游右子树。

     (2) 中序法(LtR次序,inorder traversal)。其递归定义是

           按中序周游左子树;

           访问根结点;

           按中序周游右子树。

     (3) 后序法(LRt次序,postorder traversal)。其递归定义是

           按后序周游左子树;

           按后序周游右子树;

           访问根结点。

 

BinaryTreeNode.h

#include<iostream>
using namespace std;

class BinaryTreeNode  
{
	friend class BinaryTree;
private:
	int  element;				//二叉树结点数据域
	BinaryTreeNode*  left;//二叉树结点指向左子树的指针
	BinaryTreeNode*  right;//二叉树结点指向左子树的指针
public:
	BinaryTreeNode();
	BinaryTreeNode(const int & ele);//给定数据的构造函数
	BinaryTreeNode(const int & ele,BinaryTreeNode* l, BinaryTreeNode* r);//给定数据的左右指针的构造函数
	int  value() const;			//返回当前结点的数据
	//BinaryTreeNode& operator= (const BinaryTreeNode& Node){this=Node;};//重载赋值操作符
	BinaryTreeNode*  leftchild() const;	//返回当前结点指向左子树的指针
	BinaryTreeNode*  rightchild() const;//返回当前结点指向右子树的指针
	void  setLeftchild(BinaryTreeNode*);	//设置当前结点的左子树
	void  setRightchild(BinaryTreeNode*);//设置当前结点的右子树

	void  setValue(const int & val);	//设置当前结点的数据域
	bool  isLeaf() const;	//判定当前结点是否为叶结点,若是返回true
};


BinaryTreeNode::BinaryTreeNode()
{
	left=right=NULL;
}

BinaryTreeNode::BinaryTreeNode(const int & ele)	//给定数据的构造函数
{
	element=ele;
	left=right=NULL;
}

BinaryTreeNode::BinaryTreeNode(const int & ele,BinaryTreeNode* l, BinaryTreeNode* r)//给定数据的左右指针的构造函数
{
	element=ele;
	left=l;
	right=r;
}

int  BinaryTreeNode::value() const
{
	return element; 
}	

BinaryTreeNode*  BinaryTreeNode::leftchild() const//返回当前结点指向左子树的指针
{
	return left;
}												

BinaryTreeNode*  BinaryTreeNode::rightchild() const//返回当前结点指向右子树的指针
{
	return right;								
}			

void  BinaryTreeNode::setLeftchild(BinaryTreeNode* subroot)//设置当前结点的左子树
{
	left=subroot;
}

void  BinaryTreeNode::setRightchild(BinaryTreeNode* subroot)//设置当前结点的右子树
{
	right=subroot;
}

void  BinaryTreeNode::setValue(const int & val)	//设置当前结点的数据域
{
	element = val; 
} 									

bool  BinaryTreeNode::isLeaf() const //判定当前结点是否为叶结点,若是返回true
{
	return (left == NULL) && (right == NULL); 
}



 

BinaryTree.cpp

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


class BinaryTree{
private:
	BinaryTreeNode * root;                                   //二叉树根节点
public:
	BinaryTree(){root=NULL;}                                 //构造函数
	~BinaryTree(){DeleteBinaryTree(root);}                   //析构函数
	bool isEmpty()const;                                    //判断二叉树是否为空
	BinaryTreeNode * Root(){return root;}                   //返回二叉树的根节点
	BinaryTreeNode * Parent(BinaryTreeNode * current);      //返回当前节点的父节点
	BinaryTreeNode * LeftSibling(BinaryTreeNode * current); //返回当前节点的左兄弟
	BinaryTreeNode * RightSibling(BinaryTreeNode * current);//返回当前节点的右兄弟
	void CreateTree(const int & info,BinaryTree &leftTree,BinaryTree & rightTree); //构造新数

	void PreOrder(BinaryTreeNode * root);            //递归前序周游
	void InOrder(BinaryTreeNode * root);              //递归中序周游                                             
	void PostOrder(BinaryTreeNode * root);             //递归后序周游
	void LevelOrder(BinaryTreeNode * root);            //广度优先周游
	void DeleteBinaryTree(BinaryTreeNode * root);      //删除给定的二叉树
	void Visit(int data){ cout<<data<<" "<<endl;};                                  

	void PreOrderWithoutRecursion(BinaryTreeNode * root);   //非递归前序周游
	void InOrderWithoutRecursion(BinaryTreeNode * root);   //非递归中序周游
	void PostOrderWithoutRecursion(BinaryTreeNode * root); //非递归后序周游
}

void BinaryTree::PreOrder(BinaryTreeNode * root){
	if (root!=NULL)
	{
		Visit(root->value());
		PreOrder(root->leftchild());
		PreOrder(root->rightchild());
	}
}

void BinaryTree::InOrder(BinaryTreeNode * root){
	if (root!=NULL)
	{
		InOrder(root->leftchild());
		Visit(root->value());
		InOrder(root->rightchild());
	}
}

void BinaryTree::PostOrder(BinaryTreeNode * root){
	if (root!=NULL)
	{
		PostOrder(root->leftchild());
		PostOrder(root->rightchild());
		Visit(root->value());
	}
}

void BinaryTree::PostOrderWithoutRecursion(BinaryTreeNode * root){
	using std::stack;                             //使用STL中的栈
	stack<BinaryTreeNode * > aStack;
	BinaryTreeNode * pointer=root;
	aStack.push(NULL);                 //栈底监视哨
	while (pointer)
	{
		Visit(pointer->value());
		if(pointer->rightchild()!=NULL)
			aStack.push(pointer->rightchild());
		if (pointer->leftchild()!=NULL)
			pointer=pointer->leftchild();
		else{
			pointer=aStack.top();            //获得栈顶元素
			aStack.pop();
		}
	}
}

void BinaryTree::InOrderWithoutRecursion(BinaryTreeNode * root){
	using std::stack;
	stack<BinaryTreeNode* > aStack;
	BinaryTreeNode * pointer;
	while (!aStack.empty() || pointer)
	{
		if (pointer){
			aStack.push(pointer);
			pointer=pointer->leftchild();
		}
		else{
			pointer=aStack.top();
			aStack.pop();
			Visit(pointer->value());
			pointer=pointer->rightchild();
		}
	}

}

enum Tags{Left,Right};      //定义枚举类型标志位

class StackElement{
public:
	BinaryTreeNode * pointer;
	Tags tag;
};

void BinaryTree::PostOrderWithoutRecursion(BinaryTreeNode * root){
	using std::stack;
	StackElement element;
	stack<StackElement> aStack;
	BinaryTreeNode * pointer;
	if (root==NULL)
		return;
	else
		pointer=root;
	while (!aStack.empty() || pointer){
		while (pointer!=NULL){
			element.pointer=pointer;
			element.tag=Left;               //标志位为Left表示进入左子树
			aStack.push(element);
			pointer=pointer->leftchild();
		}
		element=aStack.top();
		aStack.pop();
		pointer=element.pointer;
		if(element.tag==Left){                           //如果从左子树返回
			element.tag=Right;                         //标志位为Right表示进入右子树
			aStack.push(element);
			pointer=pointer->rightchild();
		}
		else{                                           //如果从右子树返回
			Visit(pointer->value());
			pointer=NULL;
		}
	}
}

void BinaryTree::LevelOrder(BinaryTreeNode * root){
	using std::queue;
	queue<BinaryTreeNode *> aQueue;
	BinaryTreeNode * pointer=root;
	if(pointer)
		aQueue.push(pointer);                                      //根节点入队列
	while (!aQueue.empty()){                                       //队列非空
		pointer=aQueue.front();                                    //获得列首节点
		aQueue.pop();                                              //列首节点出队列
		Visit(pointer->value());
		if(pointer->leftchild()!=NULL)
			aQueue.push(pointer->leftchild());
		if(pointer->rightchild()!=NULL)
			aQueue.push(pointer->rightchild());
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值