二元树的生成、遍历、以及最短最长路径查询

本文介绍了二元树的基本概念,包括每个节点拥有两个子节点的特性。详细讨论了如何使用递归算法生成二元树,并探讨了二元树的遍历方法。此外,还提及了在二元树中查询最短路径的问题。

二元树:

每个节点有两个子节点,左子节点和右子节点。

节点结构:

typedef struct NODE
{
char val;
NODE *left;
NODE *right;
} NODE ;

生成二元树:

利用递归算法,不断生成新的节点,并加入树中,‘#’代表空节点

NODE* TreeConstructor()
{
	char ch;
	cin>>ch;
	NODE *root;
	if (ch=='#')
	{
		return NULL;
	}
	else
	{
		root=new NODE;
		root->val=ch;
		root->left=TreeConstructor();
		root->right=TreeConstructor();
		return root;
	}
}

遍历二元树:

深度遍历二元树:利用stl容器stack实现,节点先进后出,先入右节点,后入左节点,即先进后出、先右后左;
步骤:
1,入根节点;
2,出栈顶元素;
3,若栈顶元素右孩子非空,入栈;
4,若栈顶元素左孩子非空,入栈;
5,若栈非空,转向2.
void depthFirstSearch(NODE *root)
{
stack<NODE*> NODE_stack;
NODE_stack.push(root);
NODE *node;
while(!NODE_stack.empty())
{
node=NODE_stack.top();
NODE_stack.pop();
cout<<node->val<<"  ";
if (node->right!=NULL)
{
NODE_stack.push(node->right);
}
if (node->left!=NULL)
{
NODE_stack.push(node->left);
}
}
}

广度遍历二元树:利用stl容器queue实现,节点先进先出,先入左节点,后入右节点,即先进先出、先左后右;
步骤:
1,入根节点;
2,出队首元素;
3,若队首元素左孩子非空,加入队尾;
4,若队首元素右孩子非空,加入队尾;
5,若队非空,转向2.
void breadFirstSearch(NODE *root)
{
queue<NODE*> NODE_queue;
NODE_queue.push(root);
NODE *node;
while(!NODE_queue.empty())
{
node=NODE_queue.front();
NODE_queue.pop();
cout<<node->val<<"  ";
if (node->left!=NULL)
{
NODE_queue.push(node->left);
}
if (node->right!=NULL)
{
NODE_queue.push(node->right);
}
}
}
先序、中序、后序遍历:均采用递归算法;

最短路径:

方法一:利用递归算法
int minDepth(NODE *root)
{
	if (root==NULL) return 0;
	if (root->left==NULL&&root->right==NULL) return 1;
	int leftDepth=minDepth(root->left);
	int rightDepth=minDepth(root->right);
	if (leftDepth==0)
	{
		return rightDepth+1;
	}
	if (rightDepth==0)
	{
		return leftDepth+1;
	}
	return min(leftDepth,rightDepth)+1;
}

假设有如下树:

       
递归演示图如下:


其中1,2,3,4,5,6指的是运行的步骤,由左向右依次调用minDepth函数,黑线为初始进入函数,函数为函数返回路线。
那么同理,求最长路径也可用递归的方法,代码如下:
 int maxDepth(TreeNode* root) {
        if(root==NULL) return 0;
        if(root->left==NULL&&root->right==NULL) return 1;
        int left=maxDepth(root->left);
        int right=maxDepth(root->right);
        if(left==0) return right+1;
        if(right==0) return left+1;
        return max(left,right)+1;
    }


方法二:
对二叉树进行BFS,由于是按层遍历的,因此如果在某一层发现了一个叶子节点,那么就找到了最小深度,此时返回当前深度即可。
代码如下:
int minDepth1(NODE *root) 
 {
	        if (root == NULL) return 0;
             int depth = 1;
	        int currentLevel = 1;
	         int nextLevel = 0;
			 queue<NODE*> NODE_queue;
			NODE_queue.push(root);
         while (!NODE_queue.empty()) {
		             NODE *node = NODE_queue.front();
					 NODE_queue.pop();
		             currentLevel--;
		             if (node->left == NULL && node->right == NULL) {
			                 return depth;
			             }
		             if (node->left != NULL) {
			             NODE_queue.push(node->left);    
		                  nextLevel++;
			             }
		             if (node->right != NULL) {
						 NODE_queue.push(node->right);    
						 nextLevel++;
			             }
		             if (currentLevel == 0) {
			                 if (nextLevel != 0) {
				                     depth++;
				                 }
			                currentLevel = nextLevel;
			                 nextLevel = 0;
			             }
		         }
	         return depth;
	     }
完整代码如下:
binary_tree.h
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <algorithm>
using namespace std;

typedef struct NODE
{
	char val;
	NODE *left;
	NODE *right;
} NODE ;
enum ORDER_MODE 
{ 
	ORDER_MODE_PREV = 0, 
	ORDER_MODE_MID, 
	ORDER_MODE_POST 
};//枚举,代表遍历树的方式(前序,中序,后序)

NODE* TreeConstructor();
void depthFirstSearch(NODE *root);
void breadFirstSearch(NODE *root);
int minDepth(NODE *root);
 int minDepth1(NODE *root);
 void printTree(ORDER_MODE method,NODE *root);
 void printTreeInPre(NODE *root) ;
 void printTreeInMid(NODE *root) ;
 void printTreeInPost(NODE *root) ;


main.cpp:
#include "binary_tree.h"
int index=0;
NODE* TreeConstructor()
{
	char ch;
	cin>>ch;
	NODE *root;
	if (ch=='#')
	{
		return NULL;
	}
	else
	{
		root=new NODE;
		root->val=ch;
		root->left=TreeConstructor();
		root->right=TreeConstructor();
		return root;
	}
}

void depthFirstSearch(NODE *root)
{
	stack<NODE*> NODE_stack;
	NODE_stack.push(root);
	NODE *node;
	while(!NODE_stack.empty())
	{
		node=NODE_stack.top();
		NODE_stack.pop();
		cout<<node->val<<"  ";
		if (node->right!=NULL)
		{
			NODE_stack.push(node->right);
		}
		if (node->left!=NULL)
		{
			NODE_stack.push(node->left);
		}
	}
}
void breadFirstSearch(NODE *root)
{
	queue<NODE*> NODE_queue;
	NODE_queue.push(root);
	NODE *node;
	while(!NODE_queue.empty())
	{
		node=NODE_queue.front();
		NODE_queue.pop();
		cout<<node->val<<"  ";
		if (node->left!=NULL)
		{
			NODE_queue.push(node->left);
		}
		if (node->right!=NULL)
		{
			NODE_queue.push(node->right);
		}
	}
}

int minDepth(NODE *root)
{
	if (root==NULL) return 0;
	if (root->left==NULL&&root->right==NULL) return 1;
	int leftDepth=minDepth(root->left);
	int rightDepth=minDepth(root->right);
	if (leftDepth==0)
	{
		return rightDepth+1;
	}
	if (rightDepth==0)
	{
		return leftDepth+1;
	}
	return min(leftDepth,rightDepth)+1;
}

 int minDepth1(NODE *root) 
 {
	        if (root == NULL) return 0;
             int depth = 1;
	        int currentLevel = 1;
	         int nextLevel = 0;
			 queue<NODE*> NODE_queue;
			NODE_queue.push(root);
         while (!NODE_queue.empty()) {
		             NODE *node = NODE_queue.front();
					 NODE_queue.pop();
		             currentLevel--;
		             if (node->left == NULL && node->right == NULL) {
			                 return depth;
			             }
		             if (node->left != NULL) {
			             NODE_queue.push(node->left);    
		                  nextLevel++;
			             }
		             if (node->right != NULL) {
						 NODE_queue.push(node->right);    
						 nextLevel++;
			             }
		             if (currentLevel == 0) {
			                 if (nextLevel != 0) {
				                     depth++;
				                 }
			                currentLevel = nextLevel;
			                 nextLevel = 0;
			             }
		         }
	         return depth;
	     }

 void printTree(ORDER_MODE method,NODE *root)
 {
	 if (ORDER_MODE_PREV==method)
	 {
		 printTreeInPre(root);
	 }
	 if (ORDER_MODE_MID==method)
	 {
		 printTreeInMid(root);
	 }
	 if (ORDER_MODE_POST==method)
	 {
		 printTreeInPost(root);
	 }
 };
void printTreeInPre(NODE *root) 
{
	if (root)
	{
		cout<<root->val<<" ";
		printTreeInPre(root->left);
		printTreeInPre(root->right);
	}
}
void printTreeInMid(NODE *root)
{
	if (root)
	{
		printTreeInMid(root->left);
		cout<<root->val<<" ";
		printTreeInMid(root->right);
	}
}
void printTreeInPost(NODE *root) 
{
	if (root)
	{
		
		printTreeInPost(root->left);
		printTreeInPost(root->right);
		cout<<root->val<<" ";
	}
}
void main()
{
	NODE *root;
	root=TreeConstructor();
	cout<<"深度遍历:";
	depthFirstSearch(root);
	cout<<endl<<"广度遍历:";
	breadFirstSearch(root);
	cout<<endl<<"先序遍历:";
	printTree(ORDER_MODE_PREV,root);
	cout<<endl<<"中序遍历:";
	printTree(ORDER_MODE_MID,root);
	cout<<endl<<"后序遍历:";
	printTree(ORDER_MODE_POST,root);
	cout<<endl<<"最小路径:";
	int min1= minDepth(root);
	cout<<min1<<"  ";
	int min2=minDepth1(root);
	cout<<min2;
}
运行一次结果为:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值