二叉树的建立及遍历(先序遍历、中序遍历、后续遍历、层次遍历)

数据结构学过有一段时间了,太长时间没有写代码,基本上都忘个差不多了,最近用到了,今天重新复习了一下,写个二叉树小汇总


注:我这里节点是字符类型,所以如果节点要是储存大于9的数字的值的话,需要将其改一下,部分功能代码也要随之改变,但是只要思想弄懂了,那么无论改成什么样的数据类型,都应该是没有问题的!

大家也可以自己写一个试试!!!!


二叉树的建立①:(用扩展先序遍历序列创建二叉树)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef struct Node{
	char data;
	struct Node * LChild;
	struct Node * RChild;
}BitNode,* BiTree; 


void Creat(BiTree &T){  //  &T  这点是一个引用,是一个指针的引用  在这里面对指针的修改也就是对原指针的修改 
	char ch;
	cin >> ch;
	if(ch == '#')         //  创建树的时候输入为 # 时说明该分支为NULL
	 	T = NULL;
	else{
		T = new BitNode;
		T->data = ch;
		Creat(T->LChild);
		Creat(T->RChild);
	}
}

int main()
{
	BiTree T;    //   创建一个指向二叉树根节点的指针
	cout << "建树 :(请输入树的结构(abd##e##cf###)也就是扩展前序遍历)" << endl; 
	Creat(T);
	cout << "二叉树已建立好!!!!!!!!!!!!!!!!!" << endl;
	return 0;
} 


二叉树建立②:(根据先序遍历和中序遍历创建二叉树)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef struct Node{
	char data;
	struct Node * LChild;
	struct Node * RChild;
}BitNode,* BiTree; 


BitNode * Creat(string pre,string mid)
{
	BiTree T = NULL;
	if(pre.length() > 0)
	{
		T = new BitNode;
		T->data = pre[0];
		/*  查找pre[0] 在中序遍历中的位置,*/
		int index = mid.find(pre[0]);   
		/*有中序遍历可以推出,前序遍历中1-index个都是左子树的,
		  index + 1 到 pre.length 是右子树的*/
		
		//  前 1 - index个是左子树,建立左子树 
		T->LChild = Creat(pre.substr(1,index),mid.substr(0,index)); 
		// 从  index 结束为右子树,建立右子树 
		T->RChild = Creat(pre.substr(index + 1),mid.substr(index + 1));
		/*    std::string::substr
		 *    string substr (size_t pos = 0, size_t len = npos)   
		 *    pos : 开始的位置(默认为 0)        
		 *    len : 偏移量,即从开始的位置数 len 长度个字符 (默认到字符串的结束) 
		 */
	}
	return T;
}

int main()
{
	string pre,mid,post;  // 前序遍历 、中序遍历、后序遍历
	cout << "根据输入的前序和中序建树" << endl;
	cout << "请输入前序遍历(字符串,中间不要用空格之类的符号 例:4312657):";
	cin >> pre;
	cout << endl << "请输入中序遍历(字符串,中间不要用空格之类的符号 例:1234567):";
	cin >> mid;
	
	BiTree T = Creat(pre,mid);
	cout << "二叉树已建立好!!!!!!!!!!!!!!!!!" << endl; 
	return 0;
}



二叉树建立③:(根据后序遍历和中序遍历创建二叉树)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;

typedef struct Node{
	char data;
	struct Node * LChild;
	struct Node * RChild;
}BitNode,* BiTree; 


BitNode * Creat(string post,string mid)
{
	BiTree T = NULL;
	if(post.length() > 0)
	{
		T = new BitNode;
		T->data = post[post.length() - 1];
		//  查找pre[0] 在中序遍历中的位置,
		int index = mid.find(post[post.length() - 1]);  
		/*有中序遍历可以得到后序遍历中1-index个都是左子树的,
		  index + 1 到 pre.length 是右子树的  */
		
		//  前 1 - index个是左子树,建立左子树 
		T->LChild = Creat(post.substr(0,index)
		,mid.substr(0,index)); 
		// 从  index 结束为右子树,建立右子树 
		T->RChild = Creat(post.substr(index
		,mid.length() - 1 - index),mid.substr(index+1));
		/*    std::string::substr
		 *    string substr (size_t pos = 0, size_t len = npos)   
		 *    pos : 开始的位置(默认为 0)        
		 *    len : 偏移量,即从开始的位置数 len 长度个字符 (默认到字符串的结束) 
		 */
	}
	return T;
}

int main()
{
	string pre,mid,post;  // 前序遍历 、中序遍历、后序遍历

	cout << "根据输入的后序和中序建树" << endl;
	cout << "请输入后序遍历(字符串,中间不要用空格之类的符号 例:2315764):";
	cin >> post;
	cout << endl << "请输入中序遍历(字符串,中间不要用空格之类的符号 例:1234567):";
	cin >> mid;   //  输入后续和中序建立二叉树 
	BiTree T = Creat(post,mid);
	cout << "二叉树已建立好!!!!!!!!!!!!!!!!!" << endl;
	return 0;
} 




二叉树的遍历:(前、中、后 及 层次遍历)

/*
 *   在遍历的过程中,前中后都是针对父亲来说的,输出的时候,每个节点都是作为父亲节点输出的 
 */

// 前序遍历      先父亲节点先遍历 ,即先父亲,再左儿子,最后是右儿子  
void preorder(BiTree T)
{
	if(T)
	{
		cout << T->data << " ";
		preorder(T->LChild);
		preorder(T->RChild);
	}
}
// 中序遍历      父亲节点在中间遍历, 即先左儿子,再父亲,最后是右儿子 
void midorder(BiTree T)
{
	if(T)
	{
		midorder(T->LChild);
		cout << T->data << " ";
		midorder(T->RChild); 
	}
}
// 后续遍历      父亲节点在最后遍历, 即先左儿子,再右儿子,最后是父亲 
void postorder(BiTree T)
{
	if(T)
	{
		postorder(T->LChild);
		postorder(T->RChild);
		cout << T->data << " ";
	}
}

/*
 *  层次遍历,利用队列进行层次遍历,遍历到某个节点,
 *  如果该节点有左孩子,右孩子,那么就将其孩子放入队列中 
 */
void Levelorder(BiTree T)
{
	queue<BiTree>Q;
	BiTree t;
	Q.push(T);
	while(!Q.empty())
	{
		t = Q.front();
		Q.pop();
		cout << t->data << " ";
		if(t->LChild)
		{
			Q.push(t->LChild);
		}
		if(t->RChild)
		{
			Q.push(t->RChild);
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值