DS实验题 Order 已知父节点和中序遍历求前、后序
题目:

思路:
这题是比较典型的树的遍历问题,思路就是将中序遍历作为位置的判断依据,假设有个节点A和它的父亲Afa,那么如果A和Afa的顺序在中序遍历中是先A后Afa,则A是Afa的左儿子,否则是右儿子。
用for遍历一遍所有的节点,让每一个节点都连接到它的父亲,最后从根节点开始访问即可。
代码:
//
//  main.cpp
//  Tree
//
//  Created by wasdns on 16/12/19.
//  Copyright ? 2016年 wasdns. All rights reserved.
//  
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;  
struct Node
{
    int num;  
    Node *lnext, *rnext;
};  
int fa[10005];                  //父亲
Node* node[100005];             //节点
int midorder[100005];           //中序
int preorder[100005];           //先序               
int aftorder[100005];           //后序
int tot = 0;    
/*
    Ininode函数:初始化各个节点
 */
void Ininode(int n)
{
    for (int i = 1; i <= n; i++)
    {
        Node *p = new Node;  
        p -> num = i;
        p -> lnext = NULL;
        p -> rnext = NULL;  
        node[i] = p;
    }
}  
/*
    isleft函数:判断儿子是左儿子还是右儿子
 */
bool isleft(int n, int num, int f)
{
    bool ans = true;  
    for (int i = 1; i <= n; i++)
    {
        if (midorder[i] == num || midorder[i] == f)
        {
            if (midorder[i] == f) {
                ans = false;
            }  
            break;
        }
    }  
    return ans;
}  
/*
    CreatTree:建树
 */
Node* CreatTree(int n)
{
    int i;  
    int fanum;  
    for (i = 2; i <= n; i++)
    {
        fanum = fa[i];  
        if (isleft(n, i, fanum)) {
            node[fanum] -> lnext = node[i];
        }  
        else {
            node[fanum] -> rnext = node[i];
        }
    }  
    return node[1];
}
/*
    CalPreorder函数:计算先序
 */
void CalPreorder(Node *p)
{
    if (p -> lnext == NULL && p -> rnext == NULL) {  
        preorder[tot++] = p -> num;  
        return ;
    }  
    preorder[tot++] = p -> num;  
    if (p -> lnext != NULL) CalPreorder(p -> lnext);  
    if (p -> rnext != NULL) CalPreorder(p -> rnext);
}  
/*
    CalAftorder函数:计算后序
 */
void CalAftorder(Node *p)
{
    if (p -> lnext == NULL && p -> rnext == NULL) {  
        aftorder[tot++] = p -> num;  
        return ;
    }  
    if (p -> lnext != NULL) CalAftorder(p -> lnext);  
    if (p -> rnext != NULL) CalAftorder(p -> rnext);  
    aftorder[tot++] = p -> num;
}  
/*
    PrintTree函数:中序遍历(queue思想)输出树
 */
void PrintTree(Node *head)
{
    queue<Node*> q;  
    q.push(head);  
    Node *p;  
    while (!q.empty())
    {
        p = q.front();  
        q.pop();  
        cout << p -> num << " ";  
        if (p -> lnext != NULL) {
            q.push(p -> lnext);
        }  
        if (p -> rnext != NULL) {
            q.push(p -> rnext);
        }
    }  
    cout << endl;
}  
/*
    Print函数:输出结果
 */
void Print(int n)
{
    int i;  
    for (i = 0; i < n; i++) {
        cout << preorder[i] << " ";
    }  
    cout << endl;  
    for (i = 0; i < n; i++) {
        cout << aftorder[i] << " ";
    }  
    cout << endl;
}  
int main()
{
    int n;  
    cin >> n;  
    int i;  
    for (i = 1; i <= n; i++) {
        cin >> fa[i];
    }  
    for (i = 1; i <= n; i++) {
        cin >> midorder[i];
    }  
    Ininode(n);  
    Node* head;  
    head = new Node;  
    head = CreatTree(n);  
    //PrintTree(head);  
    CalPreorder(head);  
    tot = 0;  
    CalAftorder(head);  
    Print(n);  
    return 0;
}  
2016/12/19
DS实验题 Order 已知父节点和中序遍历求前、后序的更多相关文章
- DS实验题 order
		算法与数据结构 实验题 6.4 order ★实验任务 给出一棵二叉树的中序遍历和每个节点的父节点,求这棵二叉树的先序和后序遍历. ★数据输入 输入第一行为一个正整数n表示二叉树的节点数目,节点编号从 ... 
- DS实验题 融合软泥怪-2 Heap实现
		题目和STL实现:DS实验题 融合软泥怪-1 用堆实现优先队列 引言和堆的介绍摘自:Priority Queue(Heaps)--优先队列(堆) 引言: 优先队列是一个至少能够提供插入(Insert) ... 
- DS实验题 Old_Driver UnionFindSet结构 指针实现邻接表存储
		题目见前文:DS实验题 Old_Driver UnionFindSet结构 这里使用邻接表存储敌人之间的关系,邻接表用指针实现: // // main.cpp // Old_Driver3 // // ... 
- HDU1710---树(知前序遍历与中序遍历 求后序遍历)
		知前序遍历与中序遍历 求后序遍历 #include<iostream> #include<cstring> #include<queue> #include< ... 
- 数据结构实验之求二叉树后序遍历和层次遍历(SDUT 2137)
		Problem Description 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历和层序遍历. Input 输入数据有多组,第一行是一个整数t (t<1000),代表有t组测试数据. ... 
- DS实验题 Dijkstra算法
		参考:Dijkstra算法 数据结构来到了图论这一章节,网络中的路由算法基本都和图论相关.于是在拿到DS的实验题的时候,决定看下久负盛名的Dijkstra算法. Dijkstra的经典应用是开放最短路 ... 
- DS实验题 sights
		算法与数据结构实验题 6.3 sights ★实验任务 美丽的小风姑娘打算去旅游散心,她走进了一座山,发现这座山有 n 个景点, 由于山路难修,所以施工队只修了最少条的路,来保证 n 个景点联通,娇弱 ... 
- DS实验题 PlayGame Kruskal(UnionFindSet)
		题目: 思路: 有两种做法,一种是Prim算法,另外一种则是我所使用的Kruskal算法,Kruskal的算法实现可以参考:最小生成树-Prim算法和Kruskal算法,讲的已经是十分清楚了. 具体算 ... 
- PAT A1020——已知后序中序遍历求层序遍历
		1020 Tree Traversals Suppose that all the keys in a binary tree are distinct positive integers. Give ... 
随机推荐
- maven自建仓库 Return code : 405
			maven自建仓库jar包上传: jar包上传可以采用在自建仓库上系统上传以及通过配置maven setting.xml以及pom.xml上传. maven通过配置上传需要用户名密码以及maven仓库 ... 
- 5.19[bzoj树网的核]
			围观了final,SJTU还是飞了,泽民同志劲啊! 膜拜归膜拜...回来开题 bzoj1999树网的核 最近就喜欢给自己找切不动的题...QAQ ok.....昨天在家里做了一个下午+晚上 又困&am ... 
- Android service介绍和启动方式
			1.Android service的作用: service通常是用来处理一些耗时操作,或后台执行不提供用户交互界面的操作,例如:下载.播放音乐. 2.Android service的生命周期: ser ... 
- footer元素
			<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ... 
- while的使用
			我在用while的时候, while(当这个对象的首个字是汉字){ 执行语句 } 我发现出现死循环的现象 其实我要再添加一个条件,就是不管是不是上述条件都成立,最终还是要结束的. 
- dplyr包--数据操作与清洗
			1.简介 在我们数据分析的实际应用中,我们可能会花费大量的时间在数据清洗上,而如果使用 R 里面自带的一些函数(base 包的 transform 等),可能会觉得力不从心,或者不是很人性化.好在我们 ... 
- Windows和Linux(Ubuntu)下安装Scala及ScalaIDE
			1.下载 1.1Scala下载 Windows版:http://www.scala-lang.org/download/ Linux版:http://www.scala-lang.org/downlo ... 
- BZOJ3898 : 打的士
			设$f_i$表示选择的答案区间左端点为$i$时,区间长度最小是多少. 那么每来一批人的时候,设$nxt$为$i$右边最近的一个可行决策,则$f_i=\max(f_i,nxt-i)$. 注意到$f$的形 ... 
- 使用Percona Toolkit解决Mysql主从不同步问题【备忘】
			由于各种原因,mysql主从架构经常会出现数据不一致的情况出现,大致归结为如下几类 1:备库写数据 2:执行non-deterministic query 3:回滚掺杂事务表和非事务表的事务 4:bi ... 
- ACM The Famous Clock
			The Famous Clock 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 Mr. B, Mr. G and Mr. M are now in Warsaw, ... 
