二叉树的各种遍历

/*
二叉树的各种遍历,先,中,后,层次,递归与非递归。
*/
#include <iostream>
#include <stack>
#include <queue>
using namespace std;

typedef struct  Bi_Node
{
    char data;
	struct Bi_Node *lchild,*rchild;
}Bit_Node,*Bit_Tree;

/*因为你的BiTree类型本身就是指向结构体的指针类型  所以在传递参数的过程中
不会发生深拷贝  如果你传递一个对象参数 而且这个对象里面还有指针如果不加引用
就会发生浅拷贝  但是这样发生析构的时候就会使两个指针指向同一块内存
所以必须自己写拷贝构造函数实现深拷贝 但是如果加上引用他就不会去调用拷贝构造函数去构造临时对象
而是直接引用了你的实参对象 所以类里面有指针也不会崩掉
*/
void creat_node(Bit_Tree &T)   //不加&,确实没有对指针赋值,从而成为野指针
{
	char data;
    cin>>data;
	if (data == '#')
	{
		T = NULL;
	}
	else
	{
		T = (Bit_Tree)malloc(sizeof(Bi_Node));
		T->data = data;
		creat_node(T->lchild);
		creat_node(T->rchild);
	}
}

void print_node(Bit_Tree T)
{
    if (T->data != '#')
    {
		cout<<T->data<<" ";
    }
}

void pref_order(Bit_Tree T)   //先序遍历  递归    根-左-右
{
    if (T != NULL)
    {
		print_node(T);
        pref_order(T->lchild);
		pref_order(T->rchild);
    }
}

void _pref_order(Bit_Tree T)   //先序遍历  非递归
{
	stack<Bit_Tree> s;
	Bit_Tree p = T;
    while(p || !s.empty())
    {
	    if (p != NULL)
	    {
			s.push(p);
			cout<<p->data<<" ";
			p = p->lchild;
	    }
        else
		{
            p=s.top();
            s.pop();
			p = p->rchild;
		}
    }
}

void in_order(Bit_Tree T)   //中序遍历  递归   左-根-右
{
    if (T != NULL)
    {
		in_order(T->lchild);
		print_node(T);
		in_order(T->rchild);
    }
}

void _in_order(Bit_Tree T)   //中序遍历  非递归
{
	stack<Bit_Tree> s;
	Bit_Tree p = T;
    while(p || !s.empty())
    {
		if (p != NULL)
		{
			s.push(p);
			//cout<<p->data<<" ";
			p = p->lchild;
		}
        else
		{
            p=s.top();
			cout<<p->data<<" ";
            s.pop();
			p = p->rchild;
		}
    }
}

void post_order(Bit_Tree T)   //后序遍历  递归   左-右-根
{
    if (T != NULL)
    {
		post_order(T->lchild);
		post_order(T->rchild);
		print_node(T);
    }
}

typedef struct Bit_Node_Post
{
    char tag;
    Bit_Tree bit_tree;
}*_Bit_Node_Post;

void _post_order(Bit_Tree T)   //后序遍历  非递归
{
	stack<_Bit_Node_Post> s;
	Bit_Tree p = T;
	_Bit_Node_Post bt;
    while(p || !s.empty())
    {
		while (p != NULL)
		{
            bt = (_Bit_Node_Post)malloc(sizeof(Bit_Node_Post));
            bt->tag = 'L';
			bt->bit_tree = p;
			s.push(bt);
			p = p->lchild;
		}
        while(!s.empty() && ((s.top())->tag == 'R'))
		{
            bt = s.top();
            s.pop();
			cout<<bt->bit_tree->data<<" ";
		}
		if (!s.empty())
		{
			bt = s.top();
			bt->tag = 'R';
			p = bt->bit_tree;
			p = p->rchild;
		}
    }
}

void level_order(Bit_Tree T)   //层次遍历 (good)   一层一层,从左到右
{
    queue<Bit_Tree> q;
	Bit_Tree p = T;
	q.push(p);
	while (!q.empty())
	{
        p = q.front();
        cout<<p->data<<" ";
		q.pop();
		if (p->lchild != NULL)
		{
			q.push(p->lchild);
		}
		if (p->rchild != NULL)
		{
			q.push(p->rchild);
		}
	}
}

int main()
{
    Bit_Tree T;	  //这里指向根节点的指针被初始化,后面的T就不用&再引用了。
	creat_node(T);

	cout<<"先序遍历(递归)"<<endl;
	pref_order(T);
    cout<<endl;

    cout<<"先序遍历(非递归)"<<endl;
	_pref_order(T);
	cout<<endl;

	cout<<"中序遍历(递归)"<<endl;
	in_order(T);
    cout<<endl;

	cout<<"中序遍历(非递归)"<<endl;
	_in_order(T);
	cout<<endl;

	cout<<"后序遍历(递归)"<<endl;
	post_order(T);
    cout<<endl;

	cout<<"后序遍历(非递归)"<<endl;
	_post_order(T);
	cout<<endl;

	cout<<"层次遍历"<<endl;
	level_order(T);
	cout<<endl;
	return 0;
}

Bitree T -> 定义Bitree一个实例对象:T;

Bitree &T -> 定义Bitree的实例对象的引用,就是一个已经定义的对象的别名,需要初始化;
/*
摘自<<高质量C++/C编程指南>>
引用是C++中的概念,初学者容易把引用和指针混淆一起。一下程序中,n是m的一个引用(reference),m是被引用物(referent)。

    int m;

    int &n = m;

n相当于m的别名(绰号),对n的任何操作就是对m的操作。例如有人名叫王小毛,他的绰号是“三毛”。说“三毛”怎么怎么的,其实就是对王小毛说三道四。所以n既不是m的拷贝,也不是指向m的指针,其实n就是m它自己。

*/
Bitree *T -> 定义Bitree的实例对象指针,指向一个实例对象;

代码参考:

Bitree T;

Bitree &T = T;

Bitree *T = &T; //&是取地址.
时间: 2024-11-06 02:45:01

二叉树的各种遍历的相关文章

LeetCode 145 Binary Tree Postorder Traversal(二叉树的后续遍历)+(二叉树、迭代)

翻译 给定一个二叉树,返回其后续遍历的节点的值. 例如: 给定二叉树为 {1, #, 2, 3} 1 2 / 3 返回 [3, 2, 1] 备注:用递归是微不足道的,你可以用迭代来完成它吗? 原文 Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3}, 1 2 / 3 return [3,2,1]. Note: Recur

3143 二叉树的序遍历——http://codevs.cn/problem/3143/

第一部分:题目 题目描述 Description 求一棵二叉树的前序遍历,中序遍历和后序遍历 输入描述 Input Description 第一行一个整数n,表示这棵树的节点个数. 接下来n行每行2个整数L和R.第i行的两个整数Li和Ri代表编号为i的节点的左儿子编号和右儿子编号. 输出描述 Output Description 输出一共三行,分别为前序遍历,中序遍历和后序遍历.编号之间用空格隔开. 样例输入 Sample Input 5 2 3 4 5 0 0 0 0 0 0 样例输出 Sam

根据二叉树的前序遍历和中序遍历重建二叉树

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 1 /** 2 * Definition for binary tree 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(

二叉树建立和遍历

二叉树创建遍历规则: 1.先序:根-左-右 2.中序:左-根-右 3.后序:左-右-根 二叉树定义和辅助函数如下: struct node { int data; struct node* left; struct node* right; }; void visit(int data) { printf("%d ", data); } int indata() { int data; scanf("%d",&data); return data; } 先序

二叉树三种遍历(递归以及非递归实现)

package com.shiyeqiang.tree; import java.util.Stack; public class BiTree { public static void main(String[] args) { // 首先构造叶子节点 BiTree leafA1 = new BiTree(4); BiTree leafA2 = new BiTree(5); BiTree leafB1 = new BiTree(6); BiTree leafB2 = new BiTree(7)

二叉树的递归遍历 Tree UVa548

题意:给一棵点带权的二叉树的中序和后序遍历,找一个叶子使得他到根的路径上的权值的和最小,如果多解,那该叶子本身的权值应该最小 解题思路:1.用getline()输入整行字符,然后用stringstream获得字符串中的数字 2.用数组in_oder[]和post_order[]分别表示中序遍历和后序遍历的顺序,用数组rch[]和lch[]分别表示结点的左子树和右子树 3.用递归的办法根据遍历的结果还原二叉树(后序遍历的最后一个树表示的是根节点,中序遍历的中间一个表示根节点) 4.二叉树构造完成后

重建二叉树与二叉树的层次遍历

数据结构实验之求二叉树后序遍历和层次遍历 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描写叙述 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历. 输入 输入数据有多组,第一行是一个整数t (t<1000).代表有t组測试数据.每组包含两个长度小于50 的字符串,第一个字符串表示二叉树的先序遍历序列,第二个字符串表示二叉树的中序遍历序列. 输出 每组第一行输出二叉树的后序遍历序列,第二行输出二叉树的层次遍历序列 演示样例输

数据结构之 二叉树---求二叉树后序遍历和层次遍历(先建树,再遍历)

数据结构实验之求二叉树后序遍历和层次遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历. 输入 输入数据有多组,第一行是一个整数t (t<1000),代表有t组测试数据.每组包括两个长度小于50 的字符串,第一个字符串表示二叉树的先序遍历序列,第二个字符串表示二叉树的中序遍历序列. 输出 每组第一行输出二叉树的后序遍历序列,第二行输出二叉树的层次遍历序列 示例输入 2 abdegcf dbgeaf

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

问题描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 思路: 在二叉树的前序遍历序列中,第一个数字总是树的根结点的值.但在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边.因此我们需要扫描中序遍历序列,才能找到根结点的值. 如下图所示,

二叉树的深度优先遍历和广度优先遍历

1. 二叉树的深度优先遍历,使用栈Stack, DFS(Depth First Search) function DFS(root){ var stack = []; stack.push(root); var node = null; while(stack.length){ node = stack.pop(); //visit node.data; if(node.right){ stack.push(node.right); } if(node.left){ stack.push(nod