二叉树遍历一般有先序遍历、中序遍历、后序遍历以及层次遍历。
//先序遍历的实现
void preorder(node *root){
if(root == NULL){
return;//到达空树,递归边界
}
//访问根结点root
printf("%d\n",root->data);
//访问左子树
preorder(root->lchild);
//访问右子树
preorder(root->rchild);
}
//中序遍历的实现
void inorder(node *root){
if(root == NULL){
return;//到达空树
}
inorder(root->lchild);
//访问根结点
printf("%d\n",root->data);
inorder(root->rchild);
}
//后序遍历的实现
void postorder(node *root){
if(root == NULL){
return;//到达空树
}
inorder(root->lchild);
inorder(root->rchild);
//访问根结点
printf("%d\n",root->data);
}
//层次遍历的实现
void Layerorder(node *root){
queue<node*> q;//注意队列里存地址
root->layer = 1;//根结点的层号为1
q.push(root);//将根结点地址入队
while(!q.empty()){
node *now = q.front();//取出队首元素
q.pop();
printf("%d",now->data);//访问队首元素
if(now->lchild != NULL){
now->lchild->layer = now->layer + 1;//左孩子的层号为当前层号+1
q.push(now->lchild);//左子树非空
}
if(now->rchild != NULL){
now->rchild->layer = now->layer + 1;//右孩子的层号为当前层号+1
q.push(now->rchild);//右子树非空
}
}
}
#include <iostream>
#include <cstdio>
using namespace std;
#include <queue>
typedef elemtype int;
//二叉树的存储结构
struct node{
typename data;//数据域
node *lchild;//指向左子树根结点的指针
node *rchild;//指向右子树根结点的指针
int layer;//层次
};
//二叉树的遍历
//先序遍历的实现
void preorder(node *root){
if(root == NULL){
return;//到达空树,递归边界
}
//访问根结点root
printf("%d\n",root->data);
//访问左子树
preorder(root->lchild);
//访问右子树
preorder(root->rchild);
}
//中序遍历的实现
void inorder(node *root){
if(root == NULL){
return;//到达空树
}
inorder(root->lchild);
//访问根结点
printf("%d\n",root->data);
inorder(root->rchild);
}
//后序遍历的实现
void postorder(node *root){
if(root == NULL){
return;//到达空树
}
inorder(root->lchild);
inorder(root->rchild);
//访问根结点
printf("%d\n",root->data);
}
//层次遍历的实现
void Layerorder(node *root){
queue<node*> q;//注意队列里存地址
root->layer = 1;//根结点的层号为1
q.push(root);//将根结点地址入队
while(!q.empty()){
node *now = q.front();//取出队首元素
q.pop();
printf("%d",now->data);//访问队首元素
if(now->lchild != NULL){
now->lchild->layer = now->layer + 1;//左孩子的层号为当前层号+1
q.push(now->lchild);//左子树非空
}
if(now->rchild != NULL){
now->rchild->layer = now->layer + 1;//右孩子的层号为当前层号+1
q.push(now->rchild);//右子树非空
}
}
}
//PATA-1020-Tree-Traversals
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 50;
struct node{
int data;
node *lchild;
node *rchild;
};
int pre[maxn],in[maxn],post[maxn];//先序、中序、后序
int n;//结点个数
//当前二叉树的后序序列区间为[postL,postR],中序序列区间为[inL,inR]
//create函数返回构建出的二叉树的根结点地址
node *create(int postL,int postR,int inL,int inR){//根据后序和中序序列前序重构树
if(postL > postR){
return NULL;//后序序列长度小于等于0时,直接返回
}
node *root = new node;//新建一个新的结点,用来存放当前二叉树的根结点
root->data = post[postR];//新结点的数据域为根结点的值
int k;
for(k = inL;k <= inR;k++){
if(in[k] == post[postR]){//在中序序列中找到in[k] == pre[L]的结点
break;
}
}
int numLeft = k - inL;//左子树的结点个数
//返回左子树的根结点地址,赋值给root的左指针
root->lchild = create(postL,postL+numLeft - 1,inL,k - 1);
//返回右子树的根结点地址,赋值给root的右指针
root->rchild = create(postL+numLeft,postR - 1,k + 1,inR);
return root;//返回根结点地址
}
int num = 0;//已输出的结点个数
void BFS(node *root){
queue<node*> q;//注意队列里是存地址
q.push(root);//将根结点地址入队
while(!q.empty()){
node *now = q.front();//取出队首元素
q.pop();
printf("%d",now->data);//访问队首元素
num++;
if(num < n) printf(" ");
if(now->lchild != NULL) q.push(now->lchild);//左子树非空
if(now->rchild != NULL) q.push(now->rchild);//右子树非空
}
}
int main(){
scanf("%d",&n);
for(int i=0;i < n;i++){
scanf("%d",&post[i]);
}
for(int i=0;i < n;i++){
scanf("%d",&in[i]);
}
node *root = create(0,n-1,0,n-1);//建树
BFS(root);//层序遍历
return 0;
}
#include <iostream>
#include <cstdio>
using namespace std;
#include <queue>
typedef int elemtype;
#define maxn 1000
//二叉树的静态实现
struct node{
elemtype data;//数据域
int lchild;
int rchild;
}Node[maxn];
//新建结点
int index = 0;
int newNode(int v){//分配一个Node数组中的结点给新的结点,index为其下标
Node[index].data = v;//数据域为v
Node[index].lchild = -1;//以-1或maxn表示空,因为数组范围是0~maxn-1
Node[index].rchild = -1;
return index++;
}
//查找,root为根结点在数组中的下标
void search(int root,int x,int newdata){
if(root == -1){//用-1代替NULL
return;//空树,死胡同
}
if(Node[root].data == x){//找到数据域为x的结点,把它修改成newdata
Node[root].data = newdata;
}
search(Node[root].lchild,x,newdata);//往左子树搜索x(递归式)
search(Node[root].rchild,x,newdata);//往右子树搜索x(递归式)
}
//插入,root为根结点在数组中的下标
void insert(int &root,int x){//记得加引用
if(root == -1){//空树,说明查找失败,也即插入位置(递归边界)
root = newNode(x);//给root赋以新的结点
return;
}
if(Node[root].data > x){
insert(Node[root].lchild,x);//往左子树搜索(递归式)
}
else
{
insert(Node[root].rchild,x);//往右子树搜索(递归式)
}
}
//二叉树的建立,函数返回根结点root的下标
int Create(int data[],int n){
int root = -1;//新建根结点
for(int i=0;i<n;i++){
insert(root,data[i]);//将data[0]~data[n-1]插入二叉树中
}
return root;
}
//静态二叉树的遍历
//先序遍历
void preorder(int root){
if(root == -1){
return;//到达空树,递归边界
}
//访问根结点root,例如将其数据域输出
printf("%d\n",Node[root].data);
preorder(Node[root].lchild);
preorder(Node[root].rchild);
}
//中序遍历
void inorder(int root){
if(root == -1){
return;//到达空树,递归边界
}
inorder(Node[root].lchild);
//访问根结点root,例如将其数据域输出
printf("%d\n",Node[root].data);
inorder(Node[root].rchild);
}
//后序遍历
void postorder(int root){
if(root == -1){
return;//到达空树,递归边界
}
postorder(Node[root].lchild);
postorder(Node[root].rchild);
//访问根结点root,例如将其数据域输出
printf("%d\n",Node[root].data);
}
//层序遍历
void LayerOrder(int root){
queue<int> q;//此队列里存放结点下标
q.push(root);//将根结点地址入队
while(!q.empty()){
int now = q.front();//取出队首元素
q.pop();
printf("%d ",Node[now].data);//访问队首元素
if(Node[now].lchild != -1) q.push(Node[now].lchild);//左子树非空
if(Node[now].rchild != -1) q.push(Node[now].rchild);//右子树非空
}
}
链接:http://codeup.cn/contest.php?cid=100000611
链接: http://codeup.cn/problem.php?cid=100000611&pid=0
//问题A-复原二叉树
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
string pre,in;//输入前序和中序字符串
struct BiTNode{
char data;
BiTNode *lchild;
BiTNode *rchild;
};
BiTNode *Create(int preL,int preR,int inL,int inR){
if(preL > preR) return NULL;
BiTNode *root = new BiTNode;
root->data = pre[preL];
int k;
for(k=inL;k < inR;k++){
if(pre[preL] == in[k]) break;
}
int leftNum = k - inL;
root->lchild = Create(preL + 1,preL + leftNum,inL,k - 1);
root->rchild = Create(preL + leftNum + 1,preR,k + 1,inR);
}
void postOrder(BiTNode *root){
if(root == NULL){
return;
}
postOrder(root->lchild);
postOrder(root->rchild);
printf("%c",root->data);
}
int main(){
while(cin>>pre>>in){
BiTNode *root = Create(0,pre.length()-1,0,in.length()-1);
postOrder(root);
cout<<endl;
}
return 0;
}
链接: http://codeup.cn/problem.php?cid=100000611&pid=1
//问题B-二叉树
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main(){
int m,n;
while(cin>>m>>n && (m!=0 || n!=0)){
int sum = 1;
int left = 2 * m;
int right = 2 * m + 1;
while(right < n){// 数除最后一层的子树中结点数
sum += right - left + 1;
left *= 2;
right = 2 * right + 1;
}
if(left <= n){//计数n结点所在层子树上结点数
sum += n - left + 1;
}
cout<<sum<<endl;
}
return 0;
}
由前序、中序求后序
链接: http://codeup.cn/problem.php?cid=100000611&pid=2
//问题C-二叉树遍历
//由前序中序输出后序遍历序列
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
//char str[110];
string pre,in;
struct BiTNode{
char data;
struct BiTNode *lchild;
struct BiTNode *rchild;
};
BiTNode *Create(int preL,int preR,int inL,int inR){//由前序中序还原二叉树
if(preL > preR) return NULL;
BiTNode *root = new BiTNode;
root->data = pre[preL];
int k;
for(k=inL;k< inR;k++){
if(in[k] == pre[preL]) break;//在中序序列中找到当前树的树根
}
int numLeft = k - inL;
//前序的第一个数为树根,numLeft为左子树结点数,
//用前序的子树树根逐渐将中序的序列进行划分
root->lchild = Create(preL + 1,preL + numLeft,inL,k - 1);
root->rchild = Create(preL + numLeft + 1,preR,k + 1,inR);
}
void postorder(BiTNode *root){
if(root == NULL) return;
postorder(root->lchild);
postorder(root->rchild);
printf("%c",root->data);
}
int main(){
while(cin>>pre>>in){
BiTNode *root = Create(0,pre.length()-1,0,in.length()-1);//注意此处pre.length错误,它本身是一个函数而不是成员变量
postorder(root);
cout<<endl;
}
return 0;
}
由先序求中序
链接: http://codeup.cn/problem.php?cid=100000611&pid=3
//问题 D: 二叉树遍历
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
struct node{
char data;
node *lchild;
node *rchild;
};
char str[110];
node *create(int &index){//根据先序遍历构造二叉树
int len = strlen(str);
if(str[index] == '#'){
return NULL;
}
node *root = new node;
root->data = str[index];
root->lchild = create(++index);
root->rchild = create(++index);
return root;
}
void inorder(node *root){//中序输出
if(root == NULL) return;
inorder(root->lchild);
printf("%c ",root->data);
inorder(root->rchild);
}
int main(){
while(scanf("%s",str) != EOF){
int x = 0;
node *root = create(x);
inorder(root);
printf("\n");
}
return 0;
}
二叉树的可以根据前序+中序或后序+中序或层次+中序还原二叉树,遍历多用递归形式,毕竟二叉树的定义就是递归形式的。