二叉树线索化示意图_二叉树的线索化

二叉树是一种非线性结构,遍历二叉树几乎都是通过递归或者用栈辅助实现非递归的遍历。二叉树作为存储结构时,一个节点只能获取节点的左孩子和右孩子,不能直接得到节点的任一遍历序列的前驱或者后继。为了保存这种在遍历中需要的信息,我们利用二叉树中指向左右子树的空指针来存放节点的前驱或后继信息。

也就是说,线索二叉树就是充分利用二叉树节点中的空指针,让它们分别指向本节点的前驱或者后继。既充分利用了资源,又方便我们遍历这颗二叉树。

1、线索二叉树的概念

n个节点的二叉树中含有n+1个空指针域。利用二叉树中的空指针域 来存放在某种遍历次序下的前驱和后继 ,这种指针叫“线索”。这种加上了线索的二叉树称为线索二叉树(Threaded BinaryTree)。根据遍历次序的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树和后序线索二叉树三种。

2、线索二叉树结构定义

/*线索化二叉树的结构*/

enumFlag

{

LINK,

CLUE

};structTreeNode

{

TreeNode(intx) : value(x), left(NULL), right(NULL), left_flag(LINK), right_flag(LINK) {};intvalue;

TreeNode*left;

TreeNode*right;

Flag left_flag;

Flag right_flag;

};

value

left

left_flag

right

right_flag

3、前序线索二叉树实现

/*前序遍历的构建*/

void prevCreate(TreeNode *root, TreeNode *&prev) //&prev用引用,相当于全局变量的作用,在整个递归过程传递

{if(root)

{if(root->left ==NULL)

{

root->left_flag =CLUE;

root->left =prev;

}if(prev && prev->right ==NULL)

{

prev->right_flag =CLUE;

prev->right =root;

}

prev=root;if(!root->left_flag)

{

prevCreate(root->left, prev);

}

prevCreate(root->right, prev);

}

}

/*前序线索下的遍历*/

void prevOrder(TreeNode *root)

{while(root)

{while(root->left_flag !=CLUE)

{

cout<< root->value << " ";

root= root->left;

}

cout<< root->value << " ";

root= root->right;

}

cout<

}

4、中序线索二叉树实现

/*中序遍历的构建*/

void inCreate(TreeNode *root, TreeNode *&prev)

{if(root)

{

inCreate(root->left, prev);if(root->left ==NULL)

{

root->left_flag =CLUE;

root->left =prev;

}if(prev && prev->right ==NULL)

{

prev->right_flag =CLUE;

prev->right =root;

}

prev=root;

inCreate(root->right, prev);

}

}

/*中序线索下的遍历*/

void inOrder(TreeNode *root)

{while(root)

{while(root->left_flag !=CLUE)

root= root->left;

cout<< root->value << " ";while(root->right_flag !=LINK)

{

root= root->right;

cout<< root->value << " ";

}

root= root->right;

}

cout<

}

5、线索化思想拓展

题目:如何将一个二叉树转化成一个有序的双向链表?

在没有学线索化之前,这道题可能非常麻烦。但现在,利用中序线索化的思想就可以很快将这道题做出来!

/*利用中序线索化思想将二叉树转换成有序的双向链表*/

void TreeToList(TreeNode *root)

{static TreeNode *prev = NULL; //设立prev保存上一次访问的节点

if(root == NULL) //根节点为空,直接返回

return;

TreeToList(root->left); //递归左子树

root->left = prev; //让左指针指向上一次访问的节点,即前驱

if(prev)

prev->right = root; //让prev指向当前节点,构成双向

prev = root; //更新prev

TreeToList(root->right); //递归右子树

}

本博文参考https://www.cnblogs.com/shihaochangeworld/p/5473163.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值