二叉树的简单介绍

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

二叉树的简单介绍 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. Java知识回顾 (4)Java包装类

    一. Java Number 一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte.int.long.double 等. 然而,在实际开发过程中,我们经常会遇到需要使用对象,而不是内置 ...

  2. Core Animation学习总结

    文件夹: The Layer Beneath The Layer Tree(图层树) The Backing Image(寄宿层) Layer Geometry(图层几何学) Visual Effec ...

  3. Tkinter(2.x 与3.X的区别)

    1.包的引入 2.X下是 from Tkinter import * 而3.x是 from tkinter import * 否则,会报找不到tkinter的错误 Traceback (most re ...

  4. Eclipse 4.5.0 离线安装 Veloeclipse 插件

    下载 Veloeclipse 在 Eclipse eclipse-jee-mars-R-win32-x86_64 版本 4.5.0,Build id 为 20150621-1200,离线安装 Velo ...

  5. Oracle更改redo log的大小

    因为数据仓库ETL过程中,某个mapping的执行时间超过了一个小时, select event,count(*) fromv$session_wait group by event order by ...

  6. linux实现共享内存同步的四种方法

    https://blog.csdn.net/sunxiaopengsun/article/details/79869115 本文主要对实现共享内存同步的四种方法进行了介绍. 共享内存是一种最为高效的进 ...

  7. SkinTK编译使用

    简介 MFC这个东西已经落伍了,不建议使用.我就是吃饱了撑着,还在折腾这个. 平时写点带界面的小程序一般都用Qt来做,简单好用,也很容易做的比较漂亮.我觉得唯一一个算不得多大缺点的缺点就是Qt体积太大 ...

  8. FTP上传、下载(简单小例子)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...

  9. Chrome Debugger 温故而知新:上下文环境

    最早是在IOS开发中看到过这种调试方式.在无意间发现Chrome Debugger也可以.直接上图: 解释:默认的控制台想访问变量.都是只能访问全局的.但当我们用debugger; 断点进入到内部时, ...

  10. SNF开发平台WinForm-Grid表格控件大全

    我们在开发系统时,会有很多种控件进行展示,甚至有一些为了方便的一些特殊需求. 那么下面就介绍一些我们在表格控件里常用的方便的控件:   1.Grid表格查询条 Grid表格下拉 3.Grid表格弹框选 ...