算法与数据结构 实验题

6.4 order

★实验任务

给出一棵二叉树的中序遍历和每个节点的父节点,求这棵二叉树的先序和后序遍历。

★数据输入

输入第一行为一个正整数n表示二叉树的节点数目,节点编号从1到n,其中1为根节点。

第2行有n个数字,第i个数字表示i的父亲节点。(1的父亲节点为0,表示无)第3行为中序遍历。30%的数据:n<=20;60%的数据:n<=1000;100%的数据:n<=10000;

★ 数据输出

输出2行,第一行为先序遍历,第二行为后序遍历。

输入示例

10

0 7 2 2 9 1 8 1 6 8

9 5 6 1 10 8 7 3 2 4

输出示例

1 6 9 5 8 10 7 2 3 4

5 9 6 10 3 4 2 7 8 1

我的实现

第一次比较正式的写树,我所想出的这个算法效率也不是很高,感觉只能A三个点,等大神的代码出来了再看看他们的算法。

我的想法是,根据父子节点关系和中序遍历的优先级来进行建树,最后利用递归解决前序和后序遍历。

但是这样的话有T的风险,因此贴出的代码,打算和之后大神的代码进行比对。

//
// main.cpp
// Tree_Inoder
//
// Created by wasdns on 16/10/11.
// Copyright © 2016年 wasdns. All rights reserved.
// #include <cstdio>
#include <algorithm>
#include <iostream>
#include <string>
#include <cstdlib>
#include <queue>
using namespace std; int inorder[10005];
int depen[10005]; struct Tree {
int data;
Tree* l;
Tree* r;
}; /*
* 前序遍历实现
*/ void Preorder(Tree* p) {
if (p != NULL) {
if (p -> data != -1)
cout << p -> data << " "; if (p -> l != NULL)
Preorder(p -> l); if (p -> r != NULL)
Preorder(p -> r);
}
} /*
* 后序遍历实现
*/ void Postorder(Tree* p) {
if (p != NULL) {
if (p -> l != NULL)
Postorder(p -> l); if (p -> r != NULL)
Postorder(p -> r); if (p -> data != -1)
cout << p -> data << " ";
}
} /*
* 初始化节点
*/ Tree* Initial() { Tree* p;
p = new Tree; if (p == NULL) {
cout << "Error" << endl;
exit(1);
} p -> data = -1; p -> l = NULL;
p -> r = NULL; return p;
} /*
* 用于建树过程中区别左右子节点
*/ bool isleft(int n, int l, int r) {
bool flagl = false;
bool flagr = false;
for(int i = 1; i <= n; i++) {
if (inorder[i] == l || inorder[i] == r) {
if (inorder[i] == l) {
flagl = true;
}
else flagr = true; break;
}
} if (flagl && !flagr) return true;
else return false;
} /*
* 程序核心:建树
*/ Tree* CreatTree(int n, int m) {
int i; Tree* header;
Tree* tp;
header = Initial();
header -> data = m;
tp = header; queue<Tree*> q;
q.push(header); int turn = 0; while (1) { if (!q.empty()) {
tp = q.front();
}
else break; turn = tp -> data; //cout << "turn: " << turn << endl; q.pop(); /*
* find father node's son nodes.
*/ int a = -1, b = -1;
for (i = 1; i <= n; i++) {
if (depen[i] == turn) {
if (a == -1) a = i;
else b = i;
}
} /*
* father node don't have any son node.
*/ if (a == -1 && b == -1) {
//do nothing
continue;
} /*
* one son node.
*/ else if (a != -1 && b == -1) { tp -> l = Initial();
tp -> r = Initial(); if (isleft(n, a, turn)) {
tp -> l -> data = a;
q.push(tp -> l);
}
else {
tp -> r -> data = a;
q.push(tp -> r);
}
} /*
* two son nodes.
*/ else if (a != -1 && b != -1) { tp -> l = Initial();
tp -> r = Initial(); if (isleft(n, a, b)) {
tp -> l -> data = a;
tp -> r -> data = b;
}
else {
tp -> l -> data = b;
tp -> r -> data = a;
} q.push(tp -> l);
q.push(tp -> r);
}
} return header;
} /*
* 打印树
*/ void PrintTree(Tree* p) {
queue<Tree*> q;
q.push(p); Tree* turn;
turn = Initial(); while (!q.empty()) { turn = q.front();
q.pop(); cout << turn -> data << " "; if (turn -> l != NULL) {
if (turn -> l -> data != -1)
q.push(turn -> l);
} if (turn -> r != NULL) {
if (turn -> r -> data != -1)
q.push(turn -> r);
} } cout << endl;
} int main() {
int n, i;
cin >> n; int turn = 0;
for (i = 1; i <= n; i++) {
cin >> depen[i]; if (depen[i] == 0) turn = i;
} for (i = 1; i <= n; i++) {
cin >> inorder[i];
} Tree* header;
header = CreatTree(n, turn); //PrintTree(header); 打印树,检查建树过程有没有出错。 Preorder(header); //先序遍历 cout << endl; Postorder(header); //后序遍历 cout << endl; return 0;
}

To be continued.

2016/10/13

DS实验题 order的更多相关文章

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

    题目: 思路: 这题是比较典型的树的遍历问题,思路就是将中序遍历作为位置的判断依据,假设有个节点A和它的父亲Afa,那么如果A和Afa的顺序在中序遍历中是先A后Afa,则A是Afa的左儿子,否则是右儿 ...

  2. DS实验题 融合软泥怪-2 Heap实现

    题目和STL实现:DS实验题 融合软泥怪-1 用堆实现优先队列 引言和堆的介绍摘自:Priority Queue(Heaps)--优先队列(堆) 引言: 优先队列是一个至少能够提供插入(Insert) ...

  3. DS实验题 Old_Driver UnionFindSet结构 指针实现邻接表存储

    题目见前文:DS实验题 Old_Driver UnionFindSet结构 这里使用邻接表存储敌人之间的关系,邻接表用指针实现: // // main.cpp // Old_Driver3 // // ...

  4. DS实验题 Dijkstra算法

    参考:Dijkstra算法 数据结构来到了图论这一章节,网络中的路由算法基本都和图论相关.于是在拿到DS的实验题的时候,决定看下久负盛名的Dijkstra算法. Dijkstra的经典应用是开放最短路 ...

  5. DS实验题 sights

    算法与数据结构实验题 6.3 sights ★实验任务 美丽的小风姑娘打算去旅游散心,她走进了一座山,发现这座山有 n 个景点, 由于山路难修,所以施工队只修了最少条的路,来保证 n 个景点联通,娇弱 ...

  6. DS实验题 Inversion

    题目: 解题过程: 第一次做这题的时候,很自然的想到了冒泡和选择,我交的代码是用选择写的.基本全WA(摊手). 贴上第一次的代码: // // main.cpp // sequenceschange ...

  7. DS实验题 Missile

    题目: 提示:并没有精度问题. 原题 NOIP2010 导弹拦截 思路 设源点为A(x1, y1)和B(x2, y2). 第一步,用结构体存节点,包括以下元素: 1.横坐标x 2.纵坐标y 3.节点和 ...

  8. DS实验题 击鼓传花

    题目: 代码1(数组实现): // // main.cpp // DS-击鼓传花 // // Created by wasdns on 16/11/9. // Copyright © 2016年 wa ...

  9. DS实验题 地鼠安家

    ★实验任务 fd是一个公认的美丽校园.一天,fd来了一群地鼠,编号为1到n,他们希望在这里定居.现在先由第一只地鼠往下打一个单位的距离,并且在那里安家.对于每一个已经安家的地鼠,如果他左下或右下没有邻 ...

随机推荐

  1. 记录远程桌面登录者的IP和MAC

    WINDOWS 2003 远程桌面不能记录登陆IP真是件头痛的事,本方法可以记录登陆者IP,具体的操作步骤如下: 1.建立一个存放日志的目录,如C盘下建立一个RDP的目录“C:/RDP”. 2.然后在 ...

  2. The Unique MST(poj 1679)

    题意:求次小生成树,若权值和与最小生成树相等,输出"Not Unique!" :否则,输出mst /* 次小生成树 首先明白一点,次小生成树是由最小生成树改变一条边得来的,然后我们 ...

  3. 学习BigDecimal用法

    一.简介 Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.双精度浮点型变量double可以处理16位有效数.在实际应用中,需要对更大或者更 ...

  4. 面向服务的体系结构(SOA)——(1)目标与核心概念

    什么是SOA? 常常听到人们拿OOP和SOA一起来说事,诸如SOA是否可以代替面向对象(OOP)或者两者比哪个更加有优势?直接回答有难度举个例子可能显得答案更容易理解.小孩子问你该认真写作业呢?还是高 ...

  5. TypeScript 1.5 Beta带来修饰元数据支持

    (此文章同时发表在本人微信公众号"dotNET每日精华文章") 今天由于有点小感冒,就不长篇大论了,简单介绍一下和VS 2015 RC一同发布的TypeScript 1.5 Bet ...

  6. OD hit跟踪 run跟踪使用问题

    刚学习OD不久,现在使用HIT跟踪 run跟踪功能,在我的程序里碰到点问题,还请赐教 选了一部分代码添加到HIT跟踪,在选的代码处设置断点,程序运行到断点,按单步跟踪,当执行到第二个PUSH时,程序就 ...

  7. 判断checkbox是否被选中事件

    第一种////////////////////////////////////////////////////////<input type="checkbox" value ...

  8. Fragments碎片

    A Fragment represents a behavior or a portion of user interface in an Activity. 在一个Activity活动中,一个Fra ...

  9. AsyncTask的基础讲解

    @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); s ...

  10. 参加 TiD 2015 是怎样一番体验?

    人生有很多第一次,(专程打飞的去帝都)参加软件大会,我也是第一次.   TiD   说到软件大会,QCon.PyCon 什么的早已如雷贯耳,没吃过猪肉还没见过猪跑?但对于 TiD,确实还是头一次听说. ...