树的建立和遍历
Posted zjsaipplp
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树的建立和遍历相关的知识,希望对你有一定的参考价值。
二叉树的建立
typedef struct node{
int data;
struct node *L, *R;
}*BiTree;
前中建树
//给出当前先序序列PreL, PreL+1, ..., Pre(L+numLeft), Pre(L+numLeft+1), ..., PreR
//给出当前中序序列InL, InL+1, ..., In(K-1), InK, In(k+1), ..., InR
BiTree PreInCreate(int preL, int preR, int inL, int inR){
if(preL > preR)
return NULL; //先序序列长度小于0
BiTree root = new node;
root->data = pre[preL];
int k = inL;
while(k <= inR && in[k] != pre[preL]) k++;//在中序序列中找到根节点
int numLeft = k - inL; //由中序序列得到左子树结点的个数
//左子树的先序区间为[preL+1, preL+numLeft], 左子树的中序区间为[inL, k-1];
root->L = PreInCreate(preL+1, preL+numLeft, inL, k-1);
//右子树的先序区间为[preL+numLeft+1, preR], 右子树的中序区间为[k+1, inR];
root->R = PreInCreate(preL+numLeft+1, preR, k+1, inR);
//printf("%d ", in[k]);
return root;
}
后中建树
//给出当前后序序列PostL, PostL+1, ..., Post(L+numLeft-1), Post(L+numLeft), ..., Pre(R-1), PreR
//给出当前中序序列InL, InL+1, ..., In(k-1), Ink, In(k+1), ..., InR
BiTree PostInCreate(int postL, int postR, int inL, int inR){
if(postL > postR)
return NULL;
BiTree root = new node;
root->data = post[postR];
int k = inL;
while(k <= inR && in[k] != post[postR]) k++;
int numLeft = k - inL;
//printf("%d ", in[k]);
root->L = PostInCreate(postL, postL+numLeft-1, inL, k-1);
root->R = PostInCreate(postL+numLeft, postR-1, k+1, inR);
return root;
}
层中建树
//给出当前中序序列InL, ..., In(k-1), Ink, In(k+1), ..., InR
//给出当前层次序列layerL, ..., layerR
BiTree LayerInCreate(int layerL, int layerR, int inL, int inR){
if(inL > inR) return NULL;
int i, j;
for(i = layerL; i <= layerR; i++){
bool flag = true;
for(j = inL; j <= inR; j++){
if(layer[i] == in[j]){
flag = false;
break;
}
}
if(!flag) break;
}
BiTree root = new node;
root->data = in[j];
root->L = LayerInCreate(layerL, layerR, inL, j-1);
root->R = LayerInCreate(layerL, layerR, j+1, inR);
return root;
}
二叉树的遍历
int n, m = 0;
递归算法
void Order(BiTree root){
if(root == NULL)
return;
//printf("%d%s", root->data, ++m == n ? "
" : " "); //visit(T);
Order(root->L);
//printf("%d%s", root->data, ++m == n ? "
" : " "); //visit(T);
Order(root->R);
//printf("%d%s", root->data, ++m == n ? "
" : " "); //visit(T);
}
先序非递归
void PreOrder(BiTree T){
stack<BiTree> s;
BiTree p = T;
while(p || !s.empty()){
if(p){
//printf("%d ", p->data);//visit(p);
s.push(p);
p = p->L;
}else{
p = s.top();
s.pop();
p = p->R;
}
}
}
中序非递归
void InOrder(BiTree T){
stack<BiTree> s;
BiTree p = T;
while(p || !s.empty()){
if(p){
s.push(p);
p = p->L;
}else{
p = s.top();
//printf("%d ", p->data);//visit(p);
s.pop();
p = p->R;
}
}
}
后序非递归
void PostOrder(BiTree T){
stack<BiTree> s;
BiTree p = T, r = NULL;
while(p || !s.empty()){
if(p){//走到最左边
s.push(p);
p = p->L;
}else{
p = s.top();
if(p->R && p->R != r){//右子树存在,未被访问
p = p->R;
s.push(p);
p = p->L;
}else{ //p出栈时,栈内为根节点到p的路径,以此可以求解公共结点等
printf("%d ", p->data);//visit(p);
s.pop();
r = p;//记录最近访问过的节点
p = NULL;//节点访问完后,重置p指针
}
}
}
}
层次遍历
void LevelOrder(BiTree T){
queue<BiTree> q; //队列中存放BiTnode变量的地址,这样就可以通过访问地址去修改原元素
T->Level = 1; //记录结点深度
q.push(T);
while(!q.empty()){
BiTree p = q.front();
q.pop();
//printf("%d ", p->data);//visit(p);
if(p->L){
p->L->Level = p->Level + 1; //计算各结点深度
q.push(p->L);
}
if(p->R){
p->R->Level = p->Level + 1;
q.push(p->R);
}
}
}
多叉树的静态表示
//存储结构:孩子表示法
#include <bits/stdc++.h>
using namespace std;
const int M = 1e3;
struct node{
int layer; //结点深度
int data;
vector<int> children;
}tree[M];
//若结点不涉及数据域,可以简化结点结构
vector<int> child[M];
//插入结点
int index=0;
int NewNode(int x){
tree[index].data = x;
tree[index].children.clear();
return index++;
}
//遍历
void PreOrder(int root){
printf("%d ", tree[root].data); //先根遍历
for(int i=0; i<tree[root].children.size(); i++)
PreOrder(tree[root].children[i]);
Printf("%d ", tree[root].data); //后根遍历
}
//层序遍历
#include <bits/stdc++.h>
using namespace std;
void LayerOrder(int root){
queue<int> q;
tree[root].layer = 0;
q.push(root);
while(!q.empty()){
root = q.front();
q.pop();
printf("%d ", tree[root].data);
for(int i=0; i<tree[root].children.size(); i++){
int child = tree[root].children[i];
tree[child].layer = tree[root].layer+1;
q.push(child);
}
}
}
以上是关于树的建立和遍历的主要内容,如果未能解决你的问题,请参考以下文章
二叉树的遍历方法之层序-先序-中序-后序遍历的简单讲解和代码示例
建立二叉树的二叉链表表示,实现二叉树的先序、中序、后序和按层次遍历,统计并输出结点个数。