(004)二叉树操作

(004)二叉树操作
                                                         2014/12/11 jxlijunhao
这些代码是从网上收集过来的,包含了二叉树的创建,遍历,二叉树分层结点数,叶子结点数,总的结点数,判断
二叉树是否为满二叉树,完全二叉树
#ifndef BINARYTREE_H
#define BINARYTREE_H

#include
#include 
#include 
using namespace std;


template
struct BiNode
{
	T data;
	BiNode *Lchild;
	BiNode *Rchild;
};


//创建二叉树
//template
BiNode* CreateTree()
{
	BiNode *root;
	char data;
	cin>>data;
	if (data=='#')
		return NULL;
	root =new BiNode;
	root->data=data;
	root->Lchild=CreateTree();
	root->Rchild=CreateTree();
	return root;	
}





//先序遍历,递归方法
template
void DLR(BiNode*root)
{
	if (root!=NULL)
	{
		cout<data<<" ";
		DLR(root->Lchild);
		DLR(root->Rchild);
	}
}

//先序遍历,非递归方法
//思想:先访问每个结点,将该结点的右孩子入栈,再将该结点的左孩子入栈,(取栈顶--- 右孩子入栈--左孩子入栈)
//这个栈是动态变化的,这样好理解一点
template
void DLR_NonRecursive(BiNode*root)
{
	if (root==NULL)
		return;
	stack*> s;
	s.push(root);

	while (!s.empty())
	{
		BiNode *node=s.top();//取出栈顶元素
		s.pop();
		cout<data<<" ";
		if (node->Rchild)       //右孩子入栈
			s.push(node->Rchild);
		if (node->Lchild)       //左孩子入栈
			s.push(node->Lchild);
	}
}


//中序遍历,递归
template
void LDR(BiNode*root)
{
	if (root!=NULL)
	{		
		LDR(root->Lchild);
		cout<data<<" ";
		LDR(root->Rchild);
	}
}

//中序遍历,非递归
//中序遍历非递归的思想就是将节点的沿着左子树的方向一直入栈,直到左子树为空,
//然后弹出栈里的元素进行访问,如果该节点存在右子树,则重复执行上述操作。
template
void LDR_NonRecursive(BiNode*root)
{
	if (root==NULL)
		return;
	stack*> s;
	BiNode* node=root;

	while (node!=NULL||!s.empty())
	{
		if (node!=NULL)
		{
			s.push(node);
			node=node->Lchild;
		}
		else
		{
			node=s.top();
			s.pop();
			cout<data<<" ";
			node=node->Rchild;
		}
	}
}


//后序遍历
template
void LRD(BiNode*root)
{
	if (root!=NULL)
	{
		DLR(root->Lchild);
		DLR(root->Rchild);
		cout<data;
	}
}


//层次遍历

//二叉树的层次遍历就是按照节点的深度从上往下,从左往右依次访问树中的每一个节点。
//下面这种方法是通过队列来完成的,首先将根节点入队列,然后重复进行如下操作:
//读取队头节点元素,并将节点的左右孩子写入队列,直到队列为空
template
void LevelOrder(BiNode*root)
{
	if (root==NULL)
		return;
	queue*> Queue;
	Queue.push(root);

	while (!Queue.empty())
	{
		BiNode* node;
		node=Queue.front(); //取队头元素
		Queue.pop();
	    cout<data<<" ";

		if (node->Lchild)
			Queue.push(node->Lchild);
		if (node->Rchild)
			Queue.push(node->Rchild);
	}

}


//二叉树的高度
//二叉树的高度可以通过后序遍历的思想,递归的统计节点的左子树和右子树的高度,
//然后取左右子树高度的最高值,然后加1,就是该层节点的高度

template
int getBinaryTreeHeight(BiNode*root)
{
	if (root==NULL)
		return 0;
	int lHeight=getBinaryTreeHeight(root->Lchild);
	int rHeight=getBinaryTreeHeight(root->Rchild);
	return lHeight>rHeight?lHeight+1:rHeight+1;
}

//二叉树第K层节点的个数

//也是通过后序遍历的思想,分别求节点左右子树在第K层的节点个数,然后求和。
//这里对传入的k,随着递归深度的加深,逐渐减1,直到k为1。
template
int getNodeCountKthLevel(BiNode*root,int k)
{
	if(root==NULL||k<1||k>getBinaryTreeHeight(root))
		return 0;
	if (k==1)
		return 1;
	return getNodeCountKthLevel(root->Lchild,k-1)+getNodeCountKthLevel(root->Rchild,k-1);
}

//二叉树叶子结点的个数
template
int getLevesCounts(BiNode* root)
{
	if (root==NULL)
		return 0;
	if (root->Lchild==NULL&&root->Rchild==NULL)
		return 1;
	return getLevesCounts(root->Lchild)+getLevesCounts(root->Rchild);
}

//二叉树结点的个数

template
int getCounts(BiNode*root)
{
	if (root==NULL)
		return 0;
	return getCounts(root->Lchild)+getCounts(root->Rchild)+1;
}




//满二叉树的判断
//可以通过判断每个节点的左右子树的高度是否相同来实现,满二叉树的所以节点的左右子树的高度都是一样的
template
bool isFullBinaryTree(BiNode*root)
{
	if (root==NULL)
		return true;
	int height;
	return SubIsFullBinaryTree(root,height);
}

template
bool SubIsFullBinaryTree(BiNode*root,int &height)
{
	if (root==NULL)
	{
		height=0;
		return true;
	}
	int lH,rH;
	if (SubIsFullBinaryTree(root->Lchild,lH)&&SubIsFullBinaryTree(root->Rchild,rH))
	{
		if (lH==rH)
		{
			height=lH+1;
			return true;
		}
	}
	return false;
}
//完全二叉树的判断

//通过广度遍历即层次遍历的思想,将各个节点入队列,对于存在空洞的节点(左右孩子的节点存在NULL),
//把它的两个孩子也入队列,当访问到队列中为NULL的节点,根据完全二叉树的定义,
//此时二叉树已经结束,即队列中的其他元素全部为NULL,否则该树不是完全二叉树

template
bool isCompletedBinaryTree(BiNode*root)
{
	if (root==NULL)
		return true;
	queue*> Queue;
	Queue.push(root);

	while (!Queue.empty())
	{
		BiNode*node=Queue.front();
		Queue.pop();
		
		if (node==NULL)
		{
			while (!Queue.empty())
			{
				if (Queue.front()!=NULL)
					return false;
				Queue.pop();
			}
			return true;
		}

		Queue.push(node->Lchild);
		Queue.push(node->Rchild);
	}
	return true;
}

#endif

#include "BinaryTree.h"


int main()
{
	BiNode*root=NULL;
	root=CreateTree();
	cout<<"前序遍历(递归):   ";
	DLR(root);
	cout<




你可能感兴趣的:(数据结构与算法)