数据结构学过有一段时间了,太长时间没有写代码,基本上都忘个差不多了,最近用到了,今天重新复习了一下,写个二叉树小汇总
注:我这里节点是字符类型,所以如果节点要是储存大于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);
}
}
}