当前位置 : 主页 > 网络编程 > 其它编程 >

C#数据结构二叉树链式存储结构

来源:互联网 收集:自由互联 发布时间:2023-07-02
对比上一篇文章“顺序存储二叉树”,链式存储二叉树的优点是节省空间。 二叉树的性质:1、在二叉树的第i层上至多有2i-1个节点(i1)。2、深度为k的二叉树至多有2k-1个节点(k 对比上一
对比上一篇文章“顺序存储二叉树”,链式存储二叉树的优点是节省空间。 二叉树的性质:1、在二叉树的第i层上至多有2i-1个节点(i1)。2、深度为k的二叉树至多有2k-1个节点(k

对比上一篇文章“顺序存储二叉树”,链式存储二叉树的优点是节省空间。

 

二叉树的性质:

1、在二叉树的第i层上至多有2i-1个节点(i>=1)。

2、深度为k的二叉树至多有2k-1个节点(k>=1)。

 

3、对任何一棵二叉树T,如果其终结点数为n0,度为2的节点数为n2,则n0=n2+1。

4、具有n个节点的完全二叉树的深度为log2n+1。

5、对于一棵有n个节点的完全二叉树的节点按层序编号,若完全二叉树中的某节点编号为i,则若有左孩子编号为2i,若有右孩子编号为2i+1,母亲节点为i/2。

 

在此记录下链式二叉树的实现方式 :

/// /// 树节点 /// /// public class TreeNode { /// /// 节点数据 /// public T data { get; set; } /// /// 左节点 /// public TreeNode leftChild { get; set; } /// /// 右节点 /// public TreeNode rightChild { get; set; } public TreeNode() { data = default(T); leftChild = null; rightChild = null; } public TreeNode(T item) { data = item; leftChild = null; rightChild = null; } }

/// /// 二叉树 链表存储结构/// /// public class LinkStorageBinaryTree{/// /// 树根节/// private TreeNode head { get; set; }public LinkStorageBinaryTree(){head = null;}public LinkStorageBinaryTree(T val){head = new TreeNode(val);}/// /// 获取左节点/// ///

/// public TreeNode GetLeftNode(TreeNode treeNode){if (treeNode == null)return null;return treeNode.leftChild;}/// /// 获取右节点/// ///

/// public TreeNode GetRightNode(TreeNode treeNode){if (treeNode == null)return null;return treeNode.rightChild;}/// /// 获取根节点/// /// public TreeNode GetRoot(){return head;}/// /// 插入左节点/// ///

///

/// public TreeNode AddLeftNode(T val,TreeNode node){if (node == null)throw new ArgumentNullException("参数错误");TreeNode treeNode = new TreeNode(val);TreeNode childNode = node.leftChild;treeNode.leftChild = childNode;node.leftChild = treeNode;return treeNode;}/// /// 插入右节点/// ///

///

/// public TreeNode AddRightNode(T val, TreeNode node){if (node == null)throw new ArgumentNullException("参数错误");TreeNode treeNode = new TreeNode(val);TreeNode childNode = node.rightChild;treeNode.rightChild = childNode;node.rightChild = treeNode;return treeNode;}/// /// 删除当前节点的 左节点/// ///

/// public TreeNode DeleteLeftNode(TreeNode node){if (node == null || node.leftChild == null)throw new ArgumentNullException("参数错误");TreeNode leftChild = node.leftChild;node.leftChild = null;return leftChild;}/// /// 删除当前节点的 右节点/// ///

/// public TreeNode DeleteRightNode(TreeNode node){if (node == null || node.leftChild == null)throw new ArgumentNullException("参数错误");TreeNode rightChild = node.rightChild;node.rightChild = null;return rightChild;}/// /// 先序遍历/// ///

public void PreorderTraversal(TreeNode node){//递归的终止条件if (head == null){Console.WriteLine("当前树为空");return;}if (node != null){Console.Write(node.data+ " ");PreorderTraversal(node.leftChild);PreorderTraversal(node.rightChild);}}/// /// 中序遍历/// ///

public void MiddlePrefaceTraversal(TreeNode node){//递归的终止条件if (head == null){Console.WriteLine("当前树为空");return;}if (node != null){MiddlePrefaceTraversal(node.leftChild);Console.Write(node.data + " ");MiddlePrefaceTraversal(node.rightChild);}}/// /// 后序遍历/// ///

public void AfterwordTraversal(TreeNode node){//递归的终止条件if (head == null){Console.WriteLine("当前树为空");return;}if (node != null){AfterwordTraversal(node.leftChild);AfterwordTraversal(node.rightChild);Console.Write(node.data + " ");}}public void LevelTraversal(){if (head == null)return;//使用队列先入先出Queue> queue = new Queue>();queue.Enqueue(head);while (queue.Any()){TreeNode item = queue.Dequeue();Console.Write(item.data +" ");if (item.leftChild != null)queue.Enqueue(item.leftChild);if (item.rightChild != null)queue.Enqueue(item.rightChild);}}/// /// 校验节点是否是叶子节点/// ///

/// public bool ValidLeafNode(TreeNode node){if (node == null)throw new ArgumentNullException("参数错误");if (node.leftChild != null return false;}Console.WriteLine($"节点 {node.data} 是叶子节点");return true;}}

遍历方式在顺序存储一文中已经用图表示过,在此不做重复说明。

现在测试下:

LinkStorageBinaryTree linkStorageBinary = new LinkStorageBinaryTree("A");TreeNode tree1 = linkStorageBinary.AddLeftNode("B", linkStorageBinary.GetRoot());TreeNode tree2 = linkStorageBinary.AddRightNode("C", linkStorageBinary.GetRoot());TreeNode tree3 =linkStorageBinary.AddLeftNode("D", tree1);linkStorageBinary.AddRightNode("E",tree1);linkStorageBinary.AddLeftNode("F", tree2);linkStorageBinary.AddRightNode("G", tree2);//先序遍历Console.Write("先序遍历:");linkStorageBinary.PreorderTraversal(linkStorageBinary.GetRoot());Console.WriteLine();//中序遍历Console.Write("中序遍历:");linkStorageBinary.MiddlePrefaceTraversal(linkStorageBinary.GetRoot());Console.WriteLine();//中序遍历Console.Write("后序遍历:");linkStorageBinary.AfterwordTraversal(linkStorageBinary.GetRoot());Console.WriteLine();//层次遍历Console.Write("层次遍历:");linkStorageBinary.LevelTraversal();linkStorageBinary.ValidLeafNode(tree1);linkStorageBinary.ValidLeafNode(tree3);Console.ReadKey();

输出:

先序遍历:A B D E C F G中序遍历:D B E A F C G后序遍历:D E B F G C A层次遍历:A B C D E F G 节点 B 不是叶子节点节点 D 是叶子节点

 

上一篇:【Jenkins系列】备份机制
下一篇:没有了
网友评论