时间:2021-05-20
C语言数据结构 中序二叉树
前言:
线索二叉树主要是为了解决查找结点的线性前驱与后继不方便的难题。它只增加了两个标志性域,就可以充分利用没有左或右孩子的结点的左右孩子的存储空间来存放该结点的线性前驱结点与线性后继结点。两个标志性域所占用的空间是极少的,所有充分利用了二叉链表中空闲存的储空间。
要实现线索二叉树,就必须定义二叉链表结点数据结构如下(定义请看代码):
left
leftTag
data
rightTag
right
说明:
1.leftTag=false时,表示left指向该结点的左孩子;
2.leftTag=true时,表示left指向该结点的线性前驱结点;
3.rightTag=false时,表示right指向该结点的右孩子;
4.rightTag=true时,表示right指向该结点的线性后继结点;
以二叉链表结点数据结构所构成的二叉链表作为二叉树的存储结构,叫做线索二叉链表;指向结点的线性前驱或者线性后继结点的指针叫做线索;加上线索的二叉树称为线索二叉树;对二叉树以某种次序遍历将其变为线索二叉树的过程叫做线索化。
中序次序线索化二叉树算法:
中序次序线索化是指用二叉链表结点数据结构建立二叉树的二叉链表,然后按照中序遍历的方法访问结点时建立线索;(具体看代码)
检索中序二叉树某结点的线性前驱结点的算法:
1.如果该结点的leftTag=true,那么left就是它的线性前驱;
2.如果该结点的leftTag=false,那么该结点左子树最右边的尾结点就是它的线性前驱点;
(具体请看代码)
检索中序二叉树某结点的线性后继结点和算法:
1.如果该结点的right=true,那么right就是它的线性后继结点;
2.如果该结点的right=false,那么该结点右子树最左边的尾结点就是它的线性后继结点
(具体请看代码)
图:后继线索
图:前驱线索
节点定义:
struct Node { int data; bool leftTag; bool rightTag; Node* left; Node* right; Node(int _data):data(_data),left(0),right(0),leftTag(false),rightTag(false){} };类定义:
class BinaryTree { private: Node* root; private: Node* head; Node* pre; void makeThread(Node* node); public: void buildThread(); void traverseBySuccessor(); void traverseByPredecessor(); // helper methods private: static inline bool visit(Node* T) { if (T) { printf("data:%c, left:%c, right:%c\n", (char)T->data, (T->left!=0) ? (char)T->left->data : '#', (T->right!=0) ? (char)T->right->data : '#'); return true; } else return false; } };方法定义:
void BinaryTree::makeThread(Node* node) { if (node!=NULL) { makeThread(node->left); if (pre!= NULL) { if (pre->right==NULL) // 如果前驱节点的右子树为空, 那么把前驱节点的右子树用作线索 { pre->rightTag = true; pre->right = node; } else pre->rightTag = false; } if (node->left==NULL) // 如果当前结点的左子树为空, 那么把当前结点的左子树用作线索 { node->leftTag = true; node->left = pre; } else node->leftTag = false; pre = node; makeThread(node->right); } } void BinaryTree::traverseBySuccessor() { Node* p = head->left; //first find the root node // 亲测表明 如果不使用head哑节点 就要设三道卡, 防止p访问到NULL, // 分别在主while处, 第二个visit处和下面的p=p->right处 while (p!=head) { while (!p->leftTag) p = p->left; visit(p); while (p->rightTag && p->right!=head) { p = p->right; visit(p); } p = p->right; } cout<<endl; } void BinaryTree::traverseByPredecessor() { Node* p = head->left; //first find the root node while (p!=head) { while (!p->rightTag) p = p->right; visit(p); if (p!=NULL) { while (p->leftTag && p->left!=head) { p = p->left; visit(p); } p = p->left; } } cout<<endl; } void BinaryTree::buildThread() { pre = NULL; head = new Node('@'); head->left = root; head->right = head; makeThread(root); // 经过了makeThread过程之后, pre必然指向中序遍历最晚的结点. // 把pre的右子树指向head, 就构成了一个双向循环链表 // pre->rightTag = 1; pre->right = head; pre = NULL; Node* p = root; /* * 在建立前驱线索的时候,最左边的结点没有和head结点连接。要在这里补上 */ while (p->left!=NULL) p = p->left; p->left = head; }感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了JavaScript数据结构与算法之二叉树遍历算法。分享给大家供大家参考,具体如下:javascript数据结构与算法--二叉树遍历(先序)先序遍
C++数据结构二叉树(前序/中序/后序递归、非递归遍历)二叉树的性质:二叉树是一棵特殊的树,二叉树每个节点最多有两个孩子结点,分别称为左孩子和右孩子。例:实例代
本文实例讲述了C语言实现二叉树遍历的迭代算法,是数据结构算法中非常经典的一类算法。分享给大家供大家参考。具体实现方法如下:二叉树中序遍历的迭代算法:#inclu
二叉树是一种非常重要的数据结构。本文总结了二叉树的常见操作:二叉树的构建,查找,删除,二叉树的遍历(包括前序遍历、中序遍历、后序遍历、层次遍历),二叉搜索树的构
C语言数据结构之线索二叉树及其遍历遍历二叉树就是以一定的规则将二叉树中的节点排列成一个线性序列,从而得到二叉树节点的各种遍历序列,其实质是:对一个非线性的结构进