1, 文章内容概述(利用先、中、后序双向线索链表遍历二叉树)
这篇博客主要写在将二叉树线索化之后(分别先序、中序、后序线索化,见我之前的博客,传送门:前、中、后序线索化二叉树),根据得到的双向二叉链表来打印二叉树的具体操作。
2, 算法思路分析
1.先序:先序思路和实现比较简单。访问根节点后依次循环访问左子树直到节点的左tag(标记)为线索为止,然后无论此节点的右tag是指针还是线索都前往其右孩子,在重复上述操作即可。(先序我们无需设栈来存储某些之前的节点来保证我们之后不会“丢失”我们的下一个节点,因为线索的存在给了我们这种便利)
2.中序:中序也较简单。首先循环直到左指针为线索为止,访问此节点。如果存在右孩子,则以右孩子为根重复上一过程。如果不能存在右孩子则其右指针必为线索,此时我们前往其线索并访问即可。(注意这种情况也不需要设栈来辅助我们的遍历工作,原因同上)
3.后序:后序思路相对麻烦一点。首先还是循环左指针直到左指针为thread(线索)为止,如果有右子树则前往右子树重复上述过程,否则前往其线索。需要注意的是我们需要设栈来辅助我们的工作,记录下所有路径上的节点以便我们之后对根节点进行回溯访问(可能没有说清楚,可以看下面代码)
3,代码
看代码:
#include <iostream>
#include <stack>
using namespace std;
//-----------------------二叉树的二叉线索存储结构------------------------//
typedef enum {
pointer, //指针
thread //线索
} ptrtype;
typedef struct BTree {
int val;
struct BTree *lchild, *rchild;
ptrtype Ltag, Rtag; //左右标志
} BTree, *pBTree;
// 以下算法均基于利用线索二叉树中双向线索链表进行遍历
//-------------------遍历-中序线索二叉树-----------------//
//head为双向线索链表头节点 root为树根
int MidOrderDEList(pBTree head, void (*visit)(int))
{
if (head->lchild == head && head->rchild == head) return -