二叉树的简单介绍

关于二叉树的介绍请看这里 :

二叉树的简单介绍 http://www.cnblogs.com/JiYF/p/7048785.html


二叉链表存储结构:

二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。

通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址。其结点结构为:

其中,data域存放某结点的数据信息;lchild与rchild分别存放指向左孩子和右孩子的指针,当左孩子或右孩子不存在时,相应指针域值为空(用符号∧或NULL表示)。利用这样的结点结构表示的二叉树的链式存储结构被称为二叉链表,如图5-8所示。

C#实现代码

二叉树的节点类:

 Binary Tree

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DataStructure
{
/// <summary>
/// 二叉链表结点类
/// </summary>
/// <typeparam name="T"></typeparam>
public class TreeNode<T>
{
private T data; //数据域
private TreeNode<T> lChild; //左孩子 树中一个结点的子树的根结点称为这个结点的孩子
private TreeNode<T> rChild; //右孩子 public TreeNode(T val, TreeNode<T> lp, TreeNode<T> rp)
{
data = val;
lChild = lp;
rChild = rp;
} public TreeNode(TreeNode<T> lp, TreeNode<T> rp)
{
data = default(T);
lChild = lp;
rChild = rp;
} public TreeNode(T val)
{
data = val;
lChild = null;
rChild = null;
} public TreeNode()
{
data = default(T);
lChild = null;
rChild = null;
} public T Data
{
get { return data; }
set { data = value; }
} public TreeNode<T> LChild
{
get { return lChild; }
set { lChild = value; }
} public TreeNode<T> RChild
{
get { return rChild; }
set { rChild = value; }
} }
定义索引文件结点的数据类型
  /// <summary>
/// 定义索引文件结点的数据类型
/// </summary>
public struct indexnode
{
int key; //键
int offset; //位置
public indexnode(int key, int offset)
{
this.key = key;
this.offset = offset;
} //键属性
public int Key
{
get { return key; }
set { key = value; }
}
//位置属性
public int Offset
{
get { return offset; }
set { offset = value; }
} } public class LinkBinaryTree<T>
{
private TreeNode<T> head; //头引用 public TreeNode<T> Head
{
get { return head; }
set { head = value; }
} public LinkBinaryTree()
{
head = null;
} public LinkBinaryTree(T val)
{
TreeNode<T> p = new TreeNode<T>(val);
head = p;
} public LinkBinaryTree(T val, TreeNode<T> lp, TreeNode<T> rp)
{
TreeNode<T> p = new TreeNode<T>(val, lp, rp);
head = p;
} //判断是否是空二叉树
public bool IsEmpty()
{
if (head == null)
return true;
else
return false;
} //获取根结点
public TreeNode<T> Root()
{
return head;
} //获取结点的左孩子结点
public TreeNode<T> GetLChild(TreeNode<T> p)
{
return p.LChild;
} public TreeNode<T> GetRChild(TreeNode<T> p)
{
return p.RChild;
} //将结点p的左子树插入值为val的新结点,原来的左子树称为新结点的左子树
public void InsertL(T val, TreeNode<T> p)
{
TreeNode<T> tmp = new TreeNode<T>(val);
tmp.LChild = p.LChild;
p.LChild = tmp;
} //将结点p的右子树插入值为val的新结点,原来的右子树称为新节点的右子树
public void InsertR(T val, TreeNode<T> p)
{
TreeNode<T> tmp = new TreeNode<T>(val);
tmp.RChild = p.RChild;
p.RChild = tmp;
} //若p非空 删除p的左子树
public TreeNode<T> DeleteL(TreeNode<T> p)
{
if ((p == null) || (p.LChild == null))
return null;
TreeNode<T> tmp = p.LChild;
p.LChild = null;
return tmp;
} //若p非空 删除p的右子树
public TreeNode<T> DeleteR(TreeNode<T> p)
{
if ((p == null) || (p.RChild == null))
return null;
TreeNode<T> tmp = p.RChild;
p.RChild = null;
return tmp;
} //编写算法 在二叉树中查找值为value的结点 public TreeNode<T> Search(TreeNode<T> root, T value)
{
TreeNode<T> p = root;
if (p == null)
return null;
if (!p.Data.Equals(value))
return p;
if (p.LChild != null)
{
return Search(p.LChild, value);
}
if (p.RChild != null)
{
return Search(p.RChild, value);
}
return null;
} //判断是否是叶子结点
public bool IsLeaf(TreeNode<T> p)
{
if ((p != null) && (p.RChild == null) && (p.LChild == null))
return true;
else
return false;
} //中序遍历
//遍历根结点的左子树->根结点->遍历根结点的右子树
public void inorder(TreeNode<T> ptr)
{
if (IsEmpty())
{
Console.WriteLine("Tree is Empty !");
return;
}
if (ptr != null)
{
inorder(ptr.LChild);
Console.WriteLine(ptr.Data + " ");
inorder(ptr.RChild);
}
} //先序遍历
//根结点->遍历根结点的左子树->遍历根结点的右子树
public void preorder(TreeNode<T> ptr)
{
if (IsEmpty())
{
Console.WriteLine("Tree is Empty !");
return;
}
if (ptr != null)
{
Console.WriteLine(ptr.Data + " ");
preorder(ptr.LChild);
preorder(ptr.RChild);
}
} //后序遍历
//遍历根结点的左子树->遍历根结点的右子树->根结点
public void postorder(TreeNode<T> ptr)
{
if (IsEmpty())
{
Console.WriteLine("Tree is Empty !");
return;
}
if (ptr != null)
{
postorder(ptr.LChild);
postorder(ptr.RChild);
Console.WriteLine(ptr.Data + "");
}
} //层次遍历
//引入队列
public void LevelOrder(TreeNode<T> root)
{
if (root == null)
{
return;
}
CSeqQueue<TreeNode<T>> sq = new CSeqQueue<TreeNode<T>>();
sq.EnQueue(root);
while (!sq.IsEmpty())
{
//结点出队
TreeNode<T> tmp = sq.DeQueue();
//处理当前结点
Console.WriteLine("{0}", tmp);
//将当前结点的左孩子结点入队
if (tmp.LChild != null)
{
sq.EnQueue(tmp.LChild);
}
if (tmp.RChild != null)
{
sq.EnQueue(tmp.RChild);
}
}
}
}
二叉搜索树:结点的左子节点的值永远小于该结点的值,而右子结点的值永远大于该结点的值 称为二叉搜索树
 /// <summary>
/// 二叉搜索树:结点的左子节点的值永远小于该结点的值,而右子结点的值永远大于该结点的值 称为二叉搜索树
/// </summary>
public class LinkBinarySearchTree : LinkBinaryTree<indexnode>
{
//定义增加结点的方法
public void insert(indexnode element)
{
TreeNode<indexnode> tmp, parent = null, currentNode = null;
//调用FIND方法
find(element, ref parent, ref currentNode);
if (currentNode != null)
{
Console.WriteLine("Duplicates words not allowed");
return;
}
else
{
//创建结点
tmp = new TreeNode<indexnode>(element);
if (parent == null)
Head = tmp;
else
{
if (element.Key < parent.Data.Key)
parent.LChild = tmp;
else
parent.RChild = tmp;
}
}
} //定义父结点
public void find(indexnode element, ref TreeNode<indexnode> parent, ref TreeNode<indexnode> currentNode)
{
currentNode = Head;
parent = null;
while ((currentNode != null) && (currentNode.Data.Key.ToString() != element.Key.ToString()) && (currentNode.Data.Offset .ToString() != element.Offset .ToString()))//
{
parent = currentNode;
if (element.Key < currentNode.Data.Key)
currentNode = currentNode.LChild;
else
currentNode = currentNode.RChild;
}
} //定位结点
public void find(int key)
{
TreeNode<indexnode> currentNode = Head;
while ((currentNode != null) && (currentNode.Data.Key.ToString () != key.ToString ()))
{
Console.WriteLine(currentNode.Data.Offset.ToString());
if (key < currentNode.Data.Key)
currentNode = currentNode.LChild;
else
currentNode = currentNode.RChild;
}
} //中序遍历
//遍历根结点的左子树->根结点->遍历根结点的右子树
public void inorderS(TreeNode<indexnode> ptr)
{
if (IsEmpty())
{
Console.WriteLine("Tree is Empty !");
return;
}
if (ptr != null)
{
inorderS(ptr.LChild);
Console.WriteLine(ptr.Data.Key + " ");
inorderS(ptr.RChild);
}
} //先序遍历
//根结点->遍历根结点的左子树->遍历根结点的右子树
public void preorderS(TreeNode<indexnode> ptr)
{
if (IsEmpty())
{
Console.WriteLine("Tree is Empty !");
return;
}
if (ptr != null)
{
Console.WriteLine(ptr.Data.Key + " ");
preorderS(ptr.LChild);
preorderS(ptr.RChild);
}
} //后序遍历
//遍历根结点的左子树->遍历根结点的右子树->根结点
public void postorderS(TreeNode<indexnode> ptr)
{
if (IsEmpty())
{
Console.WriteLine("Tree is Empty !");
return;
}
if (ptr != null)
{
postorderS(ptr.LChild);
postorderS(ptr.RChild);
Console.WriteLine(ptr.Data.Key + "");
}
}
} /// <summary>
/// 循环顺序队列
/// </summary>
/// <typeparam name="T"></typeparam>
class CSeqQueue<T>
{
private int maxsize; //循环顺序队列的容量
private T[] data; //数组,用于存储循环顺序队列中的数据元素
private int front; //指示最近一个已经离开队列的元素所占有的位置 循环顺序队列的对头
private int rear; //指示最近一个进入队列的元素的位置 循环顺序队列的队尾 public T this[int index]
{
get { return data[index]; }
set { data[index] = value; }
} //容量属性
public int Maxsize
{
get { return maxsize; }
set { maxsize = value; }
} //对头指示器属性
public int Front
{
get { return front; }
set { front = value; }
} //队尾指示器属性
public int Rear
{
get { return rear; }
set { rear = value; }
} public CSeqQueue()
{ } public CSeqQueue(int size)
{
data = new T[size];
maxsize = size;
front = rear = -;
} //判断循环顺序队列是否为满
public bool IsFull()
{
if ((front == - && rear == maxsize - ) || (rear + ) % maxsize == front)
return true;
else
return false;
} //清空循环顺序列表
public void Clear()
{
front = rear = -;
} //判断循环顺序队列是否为空
public bool IsEmpty()
{
if (front == rear)
return true;
else
return false;
} //入队操作
public void EnQueue(T elem)
{
if (IsFull())
{
Console.WriteLine("Queue is Full !");
return;
}
rear = (rear + ) % maxsize;
data[rear] = elem;
} //出队操作
public T DeQueue()
{
if (IsEmpty())
{
Console.WriteLine("Queue is Empty !");
return default(T);
}
front = (front + ) % maxsize;
return data[front];
} //获取对头数据元素
public T GetFront()
{
if (IsEmpty())
{
Console.WriteLine("Queue is Empty !");
return default(T);
}
return data[(front + ) % maxsize];//front从-1开始
} //求循环顺序队列的长度
public int GetLength()
{
return (rear - front + maxsize) % maxsize;
}
}

C#实现二叉树--二叉链表结构的更多相关文章

  1. C语言递归实现二叉树(二叉链表)的三种遍历和销毁操作(实验)

    今天写的是二叉树操作的实验,这个实验有三个部分: ①建立二叉树,采用二叉链表结构 ②先序.中序.后续遍历二叉树,输出节点值 ③销毁二叉树 二叉树的节点结构定义 typedef struct BiTNo ...

  2. 二叉树的二叉链表存储结构及C++实现

    前言:存储二叉树的关键是如何表示结点之间的逻辑关系,也就是双亲和孩子之间的关系.在具体应用中,可能要求从任一结点能直接访问到它的孩子. 一.二叉链表 二叉树一般多采用二叉链表(binary linke ...

  3. c使用二叉链表创建二叉树遇到的一些疑问和思考

    二叉链表存储二叉树 学习的时候参考的是<大话数据结构>,书中是这样定义的 typedef char TElemType; typedef struct BiTNode { TElemTyp ...

  4. 树(二叉树 & 二叉搜索树 & 哈夫曼树 & 字典树)

    树:n(n>=0)个节点的有限集.有且只有一个root,子树的个数没有限制但互不相交.结点拥有的子树个数就是该结点的度(Degree).度为0的是叶结点,除根结点和叶结点,其他的是内部结点.结点 ...

  5. 树&二叉树&二叉搜索树

    树&二叉树 树是由节点和边构成,储存元素的集合.节点分根节点.父节点和子节点的概念. 二叉树binary tree,则加了"二叉"(binary),意思是在树中作区分.每个 ...

  6. 建立二叉树的二叉链表存储结构(严6.70)--------西工大noj

    #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct TreeNode ...

  7. 二叉树(二叉链表实现)JAVA代码

      publicclassTest{       publicstaticvoid main(String[] args){           char[] ch =newchar[]{'A','B ...

  8. 建立二叉树的二叉链表(严6.65)--------西工大noj

    需要注意的点:在创建二叉树的函数中,如果len1==len2==0,一定要把(*T)置为NULL然后退出循环 #include <stdio.h> #include <stdlib. ...

  9. Trees on the level (二叉链表树)

    紫书:P150 uva122 Background Trees are fundamental in many branches of computer science. Current state- ...

随机推荐

  1. [前端] 记录工作中遇到的各种问题(Bug,总结,记录)

    最近一年,在开发实践过程中遇到了不少问题,大多都能得到解决 部分知其原理,部分只能做到解决问题,而半年前遇到的问题,或多或少都忘得差不多了 是该记录一下一些问题,防止再遇到就得再查资料了 1. 浏览器 ...

  2. arcgis pro行列转换

    行转列 列转行

  3. Java代码常见的十种错误

    每一个程序员在编写代码的过程中都免不了出现错误或是小的失误,这些小的错误和失误往往使得程序员还得返工.那么,如何才能尽量避免这些错误的发生呢?笔者总结只有在日常的编写代码中总结出经验,在这篇文章中,笔 ...

  4. python unknown error: DevToolsActivePort file doesn't exist 问题解决

    解决方案: from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_option ...

  5. wifipineapple外接SD卡

    通过SSH或者web访问URL, http://172.16.42.1:1471 输入帐号:root  密码:pineapplesareyummy(默认账号密码) ssh连接:ssh root@172 ...

  6. Ubuntu上安装git和创建工作区和提交文件!!!

    1.安装git: sudo apt-get install git 2.创建工作区: 创建一个文件夹,sudo mkdir 文件文件夹.告诉git这是个工作区文件夹,sudo git init 文件夹 ...

  7. 使用vue.js路由踩到的一个坑Unknown custom element

    在配合require.js使用vue路由的时候,遇到了路由组件报错: “vue.js:597 [Vue warn]: Unknown custom element: <router-link&g ...

  8. hdu2255 奔小康赚大钱,最大权匹配,KM算法

    点击打开链接 最大权匹配 KM算法 算法步骤: 设顶点Xi的顶标为a[i],顶点Yi的顶标为b[i] ⅰ.初始时.a[i]为与Xi相关联的边的最大权值.b[j]=0.保证a[i]+b[j]>=w ...

  9. 【SqlServer】SqlServer的异常处理

    在SQLserver数据库中,如果有很多存储过程的时候,我们会使用动态SQL进行存储过程调用存储过程,这时候,很可能在某个环节就出错了,但是出错了我们很难去跟踪到出错的存储过程,此时我们就可以使用异常 ...

  10. 不同局域网中同一IP地址的计算机怎么通信的

    1.IP地址在192.--.255之内的是私有地址,即192.168.1.56的电脑a是不能直接与192.168.1.56的电脑b进行通信的.他们需要用到NAT技术,即网络地址转换.2.NAT的作用是 ...