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

二元树:

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

节点结构:

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函数,黑线为初始进入函数,函数为函数返回路线。

方法二:

对二叉树进行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;
}

运行一次结果为:

时间: 2024-11-13 08:12:35

二元树的生成、遍历、以及最短路径查询的相关文章

IT公司100题-16-层遍历二元树

问题描述: 层遍历二叉树,同一层从左往右打印. 定义二元查找树的结点为: typedef struct BSTreeNode { int data; BSTreeNode *left; BSTreeNode *right; } Node; 例如输入二叉树: 6 /   \ 4    12/ \    / \2 5 8  16 输出:6 4 12 2 5 8 16. 分析: 二叉树的广度优先遍历. 代码实现: 1 // 16.cc 2 #include <deque> 3 #include &l

12.从上往下遍历二元树

http://zhedahht.blog.163.com/blog/static/2541117420072199173643/ 题目:输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印. 例如输入 8    /  \   6    10  /\     /\ 5  7   9  11 输出8   6   10   5   7   9   11. 分析:这曾是微软的一道面试题.这道题实质上是要求遍历一棵二元树,只不过不是我们熟悉的前序.中序或者后序遍历. 我们从树的根结

【每日算法】图算法(遍历&amp;MST&amp;最短路径&amp;拓扑排序)

图有邻接矩阵和邻接表两种存储方法,邻接矩阵很简单,这里不讨论,下面我们先看看常用的邻接表表示方法. 邻接表常用表示方法 指针表示法 指针表示法一共需要两个结构体: struct ArcNode //定义边表结点 { int adjvex: //邻接点域 ArcNode* next; }; struct VertexNode //定义顶点表结点 { int vertex; ArcNode* firstedge; }; 每个节点对应一个VertexNode,其firstedge指向边表(与当前节点邻

16.输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印

转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4261605.html 声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明.谢谢. 题目:输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印. 题目分析:可以用一个LinkedList的数据结构模拟队列来完成此操作.传入树

笔试算法题(25):复制拥有多个指针的链表 &amp; 判断二元树B是否为A的子树

出题:定义一个复杂链表:在单向链表的基础上,每个节点附加一个指向链表中其他任意节点的指针sibling,实现CNode* Clone(Cnode *head)函数复制这个复杂链表: 分析: 解法1:将head复制到CHead中,第一次遍历创建CHead中对应head的各个节点(next),第二次遍历创建CHead中对应head各个节 点的sibling链接,由于需要在CHead中找到对应head中的sibling节点,所以需要遍历CHead链表,但是可以用空间换时间的方法:使 用Hash Tab

作业 树和森林 遍历(递归/非递归先序,递归/非递归后序,递归层次)

1 #include <iostream> 2 #include"queue.h"//之前写的类 3 #include"stack.h" //之前写的类 4 using namespace std; 5 6 template <class T> 7 class Tree; 8 9 //======================================== 10 // 树节点类声明 11 template <class T>

JavaScript基础 使用for循环遍历数组 并 查询 数组中是否存在指定的值

镇场诗: 清心感悟智慧语,不着世间名与利.学水处下纳百川,舍尽贡高我慢意. 学有小成返哺根,愿铸一良心博客.诚心于此写经验,愿见文者得启发.------------------------------------------ code: 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=ut

树的深度优先遍历和广度优先遍历非递归实现.

注:树的深度优先遍历就是二叉树的先序遍历. 下面是代码. 1 package tooffer; 2 3 import java.util.LinkedList; 4 import java.util.Stack; 5 6 public class TreeNode { 7 int val = 0; 8 TreeNode left = null; 9 TreeNode right = null; 10 11 public TreeNode(int val) { 12 this.val = val;

树的递归遍历

树是一个由n个有限节点组成并具有层次关系的集合,是一种非线性的数据结构.树是由跟节点和它的子树构成,所以树的定义是递归的.二叉树是树的一种,它的特点是至多有两颗字树,并且二叉树的子树也有左右之分,不能互相颠倒. 二叉树常用的遍历方式有三种,即:前序遍历,中序遍历,后序遍历,这三遍历方式的主要却别是访问根结点和遍历左子树.右子树的先后关系不一样. 访问顺序: 前序遍历:根->左->右 中序遍历:左->根->右 后序遍历:左->右->根 下面由树的递归建立和对树进行递归遍历