C#数据结构-线索化二叉树

C#数据结构-线索化二叉树,第1张

概述为什么线索化二叉树? 对于二叉树的遍历,我们知道每个节点的前驱与后继,但是这是建立在遍历的基础上,否则我们只知道后续的左右子树。现在我们充分利用二叉树左右子树的空节点,分别指向当前节点的前驱、后继,便

为什么线索化二叉树?

对于二叉树的遍历,我们知道每个节点的前驱与后继,但是这是建立在遍历的基础上,否则我们只知道后续的左右子树。现在我们充分利用二叉树左右子树的空节点,分别指向当前节点的前驱、后继,便于快速查找树的前驱后继。

不多说,直接上代码:

/// <summary>/// 线索二叉树 节点</summary><typeparam name="T"></typeparam>public class ClueTreeNode<T>{    <summary>     内容    </summary>    public T data { get; set; }     左树    public ClueTreeNode<T> leftNode {  右树    public ClueTreeNode<T> rightNode {  0 标识左树 1 标识 当前节点的前驱    int leftTag {  0标识右树 1 标识 当前节点的后继    int rightTag { ; }    public ClueTreeNode()    {        data = default(T);        leftNode = null;        rightNode = ;    }     ClueTreeNode(T item)    {        data = item;        leftNode = ;    }}
 线索化 二叉树 ///  为什么线索化二叉树? 第一:对于二叉树,如果有n个节点,每个节点有指向左右孩子的两个指针域,所以一共有2n个指针域。 而n个节点的二叉树一共有n-1条分支线数,也就是说,其实是有 2n-(n-1) = n+1个空指针。 这些空间不存储任何事物,白白浪费内存的资源。 第二:对于二叉树的遍历,我们知道每个节点的前驱与后继,但是这是建立在遍历的基础上。 否则我们只知道后续的左右子树。 第三:对于二叉树来说,从结构上来说是单向链表,引入前驱后继后,线索化二叉树可以认为是双向链表。class ClueBinaryTree<T> 树根节    private ClueTreeNode<T> head {  线索化时作为前驱转存    private ClueTreeNode<T> preNode {  ClueBinaryTree(){        head = new ClueTreeNode<T>();    }     ClueBinaryTree(T val){        head = (val);    }    public ClueTreeNode<T> GetRoot(){        return head;    }     插入左节点    </summary>    <param name="val"></param>    <param name="node"></param>    <returns></returns>    public ClueTreeNode<T> AddleftNode(T val,ClueTreeNode<T> node){        if (node == )            throw new ArgumentNullException("参数错误");        ClueTreeNode<T> treeNode = (val);        ClueTreeNode<T> childNode = node.leftNode;        treeNode.leftNode = childNode;        node.leftNode = treeNode;         treeNode;    }     插入右节点    public ClueTreeNode<T> AddRightNode(T val,1)"> node.rightNode;        treeNode.rightNode = childNode;        node.rightNode = treeNode;    }     删除当前节点的 左节点    public ClueTreeNode<T> DeleteleftNode(ClueTreeNode<T>null || node.leftNode == );        ClueTreeNode<T> leftChild = node.leftNode;        node.leftNode = ;         leftChild;    }     删除当前节点的 右节点    public ClueTreeNode<T> DeleteRightNode(ClueTreeNode<T>null || node.rightNode == );        ClueTreeNode<T> rightChild = node.rightNode;        node.rightNode =  rightChild;    }     中序遍历线索化二叉树    voID MIDdlePrefaceTraversal(){        ClueTreeNode<T> node = head;        while (node != )        {            //判断是否是            while (node.leftTag == 0)            {                node = node.leftNode;            }            Console.Write($ {node.data});            while (node.rightTag == 1 node.rightNode;                Console.Write($);            }            node = node.rightNode;        }    }     线索化二叉树    <param name="node"></param>    voID MIDdleClueNodes(ClueTreeNode<T>;        }        线索化左子树        MIDdleClueNodes(node.leftNode);        当左树为空时,指向前驱,标识为 1        if (node.leftNode == )        {            node.leftNode = preNode;            node.leftTag = 如果 前驱的右树不为空        if (preNode != null && preNode.rightNode == )        {            preNode.rightNode = node;            preNode.rightTag = ;        }        preNode = node;        线索化右子树        MIDdleClueNodes(node.rightNode);    }}

 

 

 

 

 

 现在我们测试:

创建树ClueBinaryTree<string> clueBinaryTree = new ClueBinaryTree<string>(A);ClueTreeNode<string> tree1 = clueBinaryTree.AddleftNode(B,clueBinaryTree.GetRoot());ClueTreeNode<string> tree2 = clueBinaryTree.AddRightNode(Cstring> tree3 = clueBinaryTree.AddleftNode(DEFG中序遍历);clueBinaryTree.MIDdlePrefaceTraversal();

打印结果:

中序遍历 D B E A F C G

 

 

总结

以上是内存溢出为你收集整理的C#数据结构-线索化二叉树全部内容,希望文章能够帮你解决C#数据结构-线索化二叉树所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1213258.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存