线索二叉树存在的意义

百度,google了二十分钟也没看到关于线索二叉树的应用。

线索二叉树减少了的空指针域的同时又对每个节点增加了两个标志位。

如果要遍历树可以用栈或者队列或者递归,那线索二叉树的意义是什么?莫不是学者们强迫症犯了就为了减少空指针域的个数。

书上写着引入线索二叉树是为了加快查找节点前驱和后继的速度,而个人觉得线索二叉树在建立的时候使得树的建立变得复杂了一点点,从逻辑上去想也变得复杂,觉得有点吃力不讨好。

除了考试时可能会考到线索二叉树,其他的用处暂时没发现,有缘再见线索二叉树吧。


终于,发现了一个实际的应用:

当路由器使用CIDR,选择下一跳的时候,或者转发分组的时候,通常会用最长前缀匹配(最佳匹配)来得到路由表的一行数据,为了更加有效的查找最长前缀匹配,使用了一种层次的数据结构中,通常使用的数据结构为二叉线索。

阔以阔以,先留个悬念,后续详解CIDR以及线索二叉树。

### 关于线索二叉树的遍历算法 #### 线索二叉树的概念 线索二叉树是一种特殊的二叉树表示方式,其中原本为空的指针被用来指向某种特定顺序下的前驱或后继节点。这种设计能够减少额外的空间开销并简化某些操作流程[^1]。 #### 中序线索化过程概述 为了实现中序遍历而构建的线索二叉树称为 **中序线索二叉树**。在此过程中,每个节点会设置两个标志位 `ltag` 和 `rtag` 来区分当前子节点是指向实际孩子还是作为线索指向某个祖先或其他关联节点: - 如果 `ltag=0` 表明该节点存在左子树;如果 `ltag=1` 则表明此位置保存的是前驱节点的线索。 - 同理,当 `rtag=0` 时表示右子树有效;反之则代表它存储着后继节点的信息。 #### 基本遍历逻辑描述 针对已经完成线索化的二叉树执行遍历时无需再借助显式的堆栈数据结构即可达成目标。具体做法如下: 1. 找到整个序列的第一个元素——即沿着任意给定根路径不断深入至最左侧叶子处所到达的那个点; 2. 对于此初始状态下的活动结点A来说, - 若其右侧链接指示为真实后代(`rtag==0`) ,那么就转向那个方向继续探索新的分支顶端; - 反之若是间接连接到了另一个兄弟型成员身上 (`rtag==1`) , 就单纯读取这个数值后再更新自身定位成后者的样子重复上述判断直至结束条件满足为止. 以下是采用C++风格伪代码形式展示如何基于已建立好的线索单元开展迭代式扫描: ```cpp // 定义一个函数用于获取下一个待处理节点 ThreadedBinaryTreeNode* getNextNode(ThreadedBinaryTreeNode* pNode){ if(pNode->rightTag == Link){ // 当前节点有真正的右子树 pNode = pNode->right; while (pNode && pNode->leftTag == Link) { pNode = pNode->left; } }else{ // 使用线索跳转到下一节点 pNode = pNode->right; } return pNode; } void InOrderTraversalWithoutStack(ThreadedBinaryTreeNode *root){ ThreadedBinaryTreeNode *current = root; // 寻找第一个节点(最左边的节点) while(current != nullptr && current->leftTag == Link){ current = current->left; } // 开始遍历 while(current !=nullptr ){ visit(current); current=getNextNode(current); } } ``` 以上展示了怎样利用预先存在线索信息来代替传统意义上的压入弹出动作从而达到同样效果的方法论[^3]. ### Java版本示例程序片段 下面给出一段简单的java版例子演示同样的概念应用情况 : ```java public static class ThreadedNode{ int value; boolean isLeftThread,isRightThread; ThreadedNode left,right; public ThreadedNode(){} public ThreadedNode(int v){ this.value=v; } } private static void inorderTraverse(ThreadedNode root){ ThreadedNode cur=root; // Find the first node to be visited. while(cur!=null&&cur.isLeftThread==false){ cur=cur.left; } while(cur!=null){ System.out.print(cur.value+" "); if(!cur.isRightThread){ cur=cur.right; while(cur!=null&&!cur.isLeftThread){ cur=cur.left; } }else{ cur=cur.right; } } } ```
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值