DS实验题 order
算法与数据结构 实验题
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的更多相关文章
- DS实验题 Order 已知父节点和中序遍历求前、后序
题目: 思路: 这题是比较典型的树的遍历问题,思路就是将中序遍历作为位置的判断依据,假设有个节点A和它的父亲Afa,那么如果A和Afa的顺序在中序遍历中是先A后Afa,则A是Afa的左儿子,否则是右儿 ...
- DS实验题 融合软泥怪-2 Heap实现
题目和STL实现:DS实验题 融合软泥怪-1 用堆实现优先队列 引言和堆的介绍摘自:Priority Queue(Heaps)--优先队列(堆) 引言: 优先队列是一个至少能够提供插入(Insert) ...
- DS实验题 Old_Driver UnionFindSet结构 指针实现邻接表存储
题目见前文:DS实验题 Old_Driver UnionFindSet结构 这里使用邻接表存储敌人之间的关系,邻接表用指针实现: // // main.cpp // Old_Driver3 // // ...
- DS实验题 Dijkstra算法
参考:Dijkstra算法 数据结构来到了图论这一章节,网络中的路由算法基本都和图论相关.于是在拿到DS的实验题的时候,决定看下久负盛名的Dijkstra算法. Dijkstra的经典应用是开放最短路 ...
- DS实验题 sights
算法与数据结构实验题 6.3 sights ★实验任务 美丽的小风姑娘打算去旅游散心,她走进了一座山,发现这座山有 n 个景点, 由于山路难修,所以施工队只修了最少条的路,来保证 n 个景点联通,娇弱 ...
- DS实验题 Inversion
题目: 解题过程: 第一次做这题的时候,很自然的想到了冒泡和选择,我交的代码是用选择写的.基本全WA(摊手). 贴上第一次的代码: // // main.cpp // sequenceschange ...
- DS实验题 Missile
题目: 提示:并没有精度问题. 原题 NOIP2010 导弹拦截 思路 设源点为A(x1, y1)和B(x2, y2). 第一步,用结构体存节点,包括以下元素: 1.横坐标x 2.纵坐标y 3.节点和 ...
- DS实验题 击鼓传花
题目: 代码1(数组实现): // // main.cpp // DS-击鼓传花 // // Created by wasdns on 16/11/9. // Copyright © 2016年 wa ...
- DS实验题 地鼠安家
★实验任务 fd是一个公认的美丽校园.一天,fd来了一群地鼠,编号为1到n,他们希望在这里定居.现在先由第一只地鼠往下打一个单位的距离,并且在那里安家.对于每一个已经安家的地鼠,如果他左下或右下没有邻 ...
随机推荐
- 在iOS开发中,给项目添加新的.framework
首先需要了解一下iOS中静态库和动态库.framework的概念 静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我 ...
- hdu 1159:Common Subsequence(动态规划)
Common Subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- 在Linux中创建静态库.a和动态库.so
转自:http://www.cnblogs.com/laojie4321/archive/2012/03/28/2421056.html 在Linux中创建静态库.a和动态库.so 我们通常把一些公用 ...
- 【Grunt】关于Grunt可视化的尝试
使用Grunt遇到的问题? 必须要安装NodeJS 必须安装grunt-cli 需要编写复杂的Gruntfile.js规则 每个项目中必须存在nodejs的grunt模块 不方便管理每一个包含grun ...
- 拼接JSONStringer出现的不正确的情况。
错误现象: 错误分析及其解答: JSONStringer可以直接嵌套JSONArray,JSONArray可以作为JSONStringer的值.我错误的原因是本质是:JSONArray存放的是JSON ...
- 常用的 Python 爬虫技巧总结
用python也差不多一年多了,python应用最多的场景还是web快速开发.爬虫.自动化运维:写过简单网站.写过自动发帖脚本.写过收发邮件脚本.写过简单验证码识别脚本. 爬虫在开发过程中也有很多复用 ...
- chrome扩展程序开发之在目标页面运行自己的JS
大家都知道JS是运行在客户端的,所以,如果我们自己写一个浏览器的话,是一定可以往下载下来的网页源代码中加入js的.可惜我们没有这个能力.不过幸运的是,chrome的扩展程序可以帮我们做到这件事. 本文 ...
- Hark的数据结构与算法练习之梳排序
算法说明梳排序是交换排序的一种,它其实也是改自冒泡排序,不同之处是冒泡排序的比较步长恒定为1,而梳排序的比较步长是变化的. 步长需要循环以数组长度除以1.3,到最后大于等于1即可. 光说可能比较抽象, ...
- PDA手持终端集成一体打印 二次开发
PDA手持终端集成一体打印 二次开发支持 VS2008或VS2005开发工具 c#或C++开发语言 Mobile6.5,支持GSM通话,GPRS,EDGE网络;内置wifi,蓝牙,gps商场单品管理小 ...
- 递推DP URAL 1009 K-based Numbers
题目传送门 题意:n位数,k进制,求个数分析:dp[i][j] 表示i位数,当前数字为j的个数:若j==0,不加dp[i-1][0]; 代码1: #include <cstdio> #in ...