![](https://csdnimg.cn/release/download_crawler_static/3219514/bg1.jpg)
二叉表达式树
http://blog.csdn.net/timercrack/archive/2007/11/08/1874767.aspx
终于到谈到树了,可以说数据结构最精彩的算法都出自这里(但不是最复杂的,后面还有图..)。接下
来的 2 篇文章会介绍有关树的一些操作和应用。
树的两个基本用途,可以用物质和精神来比喻。
一个用途是做为数据储存,储存具有树结构的数据——目录、族谱等等。为了在实际上是线性的储
存载体上(内存、磁盘)储存非线性的树结构,必须有标志指示出树的结构。因此,只要能区分根和子
树,树可以采取各种方法来储存——多叉链表、左孩子-右兄弟二叉链表、广义表、多维数组。由于操
作的需求,储存方法并不是随意选取的。比如,在并查集的实现上,选取的是双亲链表。
一个用途是做为逻辑判断,此时会常常听到一个名词——判定树。最常用的结构是二叉树(见下文),
一个孩子代表 true,一个孩子代表 false。关于多叉判定树,有个例子是求 8 皇后的全部解——这个连高
斯都算错了(一共是 92 组解,高斯最开始说 76 组解),我们比不上高斯,但是我们会让 computer 代
劳。
就像哲学界到现在还纠缠于物质和精神本源问题,实际上在树这里也是如此。有些情况下,并不能
区分是做为储存来用还是做为判断来用,比如搜索树,既储存了数据,还蕴涵着判断,这在后续的文章
会提到。
和后面的图相比,树更基本,也更常用。你可以不知道最短路径怎么求,却每时每刻都在和树打交
道——看看你电脑里的文件夹吧^_^
首先要介绍的是树形结构中最基础、最常用的所谓二叉树。二叉树可以说是人们假想的一个模型,
因此,允许有空的二叉树是无争议的。二叉树是有序的,左边有一个孩子和右边有一个的是不同的两棵
二叉树树。做这个规定,是因为人们赋予了左孩子和右孩子不同的意义。二叉树有多种存储方式,下面
只讲解链式结构。看各种讲数据结构的书,你会发现一个有趣的现象:在二叉树这里,基本操作有计算
树高、寻找节点以及各种遍历,但就是没有插入、删除操作。那树是怎么建立起来的?其实这很好理解,
对于非线性的树形结构,插入删除操作不在一定的法则规定下,是毫无意义的。因此,只有在具体的应
用中,才会有插入删除操作。
与之前的文章一样,这里不讨论各种基本操作,而是讲一些实际应用。我发现这样更有利于加深对
数据结构的理解。这里讲书上的例子:二叉表达式树。但书上一个具体算法都没有给出,倒是随书光盘
里给出了一个中缀表达式建树的演示,我就根据它编写了一个完整的表达式树类,下面以它来介绍二叉
树的一些典型操作。包括:输入任意形式的表达式建立一棵树,表达式树的求值以及通过不同方式的遍
历来生成不同形式的表达式。
首先是结点结构。与前面学过的线形链表一样,二叉树的结点也分为数据域与指针域,只不过这里
有两个指针域分别指向左右孩子节点。有时为了操作方便还会附加一个双亲指针,这里就不需要了,下
面是节点定义:
classTNode{
public:
union{charoptr;intopnd;};
TNode*left;
TNode*right;
TNode(charop,TNode*lef,TNode*rgt)
:optr(op),left(lef),right(rgt){}
TNode(intnum)
- 1
- 2
- 3
- 4
- 5
- 6
前往页