作为一个小白的第二天(+第三天),今天被大神带领刷的题是这道:
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
看到题目的一瞬间,我一脸懵逼(╥﹏╥)。这都是什么啊!
没办法在大神的指点下,我去看了数据结构与算法分析这本书,学学啥是树、啥又是二叉树,前序遍历、中序遍历都是什么鬼东西。PS:作为工科生,以前听过树这种数据结构,但是因为偷懒从来没真接触,果然欠下的迟早要还......
步入正题:
首先是树:树是节点的集合。
树的根、树叶、父子、兄弟,连接节点的边
节点到节点的路径。根到节点的深度。节点到树叶的高(到自己子孙最长路径)。
树的实现:
链表法:数据+指针来表示节点。用儿子和兄弟放在节点链表中:建立各个儿子的链接。
typedef struct TreeNode *PtrToNode;
struct TreeNode
{
ElementType Element;
PtrToNote Firstchild;
PtrToNote NextSibling;
}
// typedef struct TreeNode *PtrToNode; :使用 typedef 为这个新的结构TreeNode(用struct TreeNode建立的)起了指向自己的指针:结构的别名PtrToNode(建立链表等数据结构的实现上看到很多这类例子) PtrToNote Firstchild:定义该结构变量 Firstchild
A
B C D E F
G H I J K L M
N O
树的遍历:
前序遍历(先序遍历):文件名打印
static void ListDir(DirectoryOrFile D,int Depth)
{
if(D is a legitimate entry)
{
PrintName(D,Depth);
if(D is a directory)
for each child ,C,of D
ListDir(C,Depth+1);
}
}
void ListDir(DirectoryOrFile D)
{
ListDir(D,0);
}
先打印头目录再打印子目录,处理在诸儿子节点之前。
后续遍历:磁盘占有量
static void SizeDirectory(DirectoryOrFile D)
{
int TotalSize;
TotalSize=0;
if(D is a legitimate entry)
{
TotalSize=FileSize(D);
if(D is a directory)
for each child,C,of D
TotalSize+=SizeDirectory(C);
}
return TotalSize;
}
从头先到尾不处理,然后从尾逐渐累加计算到根,计算在诸儿子节点之后。
二叉树
每个节点最多有两个儿子的树。
表达式树:树叶是操作数,其他节点是操作符。
中序遍历:带有括号的遍历
中序遍历:(a+b*c)+((d*e+f)*g)
前序遍历:++a*bc*+*defg
后序遍历:abc*+de*f+g*+
已经可以看图写出前中后序遍历,进步了一丢丢,还需学习更多。