C#实现二叉树--二叉链表结构
二叉树的简单介绍
关于二叉树的介绍请看这里 :
二叉树的简单介绍 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#实现二叉树--二叉链表结构的更多相关文章
- C语言递归实现二叉树(二叉链表)的三种遍历和销毁操作(实验)
今天写的是二叉树操作的实验,这个实验有三个部分: ①建立二叉树,采用二叉链表结构 ②先序.中序.后续遍历二叉树,输出节点值 ③销毁二叉树 二叉树的节点结构定义 typedef struct BiTNo ...
- 二叉树的二叉链表存储结构及C++实现
前言:存储二叉树的关键是如何表示结点之间的逻辑关系,也就是双亲和孩子之间的关系.在具体应用中,可能要求从任一结点能直接访问到它的孩子. 一.二叉链表 二叉树一般多采用二叉链表(binary linke ...
- c使用二叉链表创建二叉树遇到的一些疑问和思考
二叉链表存储二叉树 学习的时候参考的是<大话数据结构>,书中是这样定义的 typedef char TElemType; typedef struct BiTNode { TElemTyp ...
- 树(二叉树 & 二叉搜索树 & 哈夫曼树 & 字典树)
树:n(n>=0)个节点的有限集.有且只有一个root,子树的个数没有限制但互不相交.结点拥有的子树个数就是该结点的度(Degree).度为0的是叶结点,除根结点和叶结点,其他的是内部结点.结点 ...
- 树&二叉树&二叉搜索树
树&二叉树 树是由节点和边构成,储存元素的集合.节点分根节点.父节点和子节点的概念. 二叉树binary tree,则加了"二叉"(binary),意思是在树中作区分.每个 ...
- 建立二叉树的二叉链表存储结构(严6.70)--------西工大noj
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct TreeNode ...
- 二叉树(二叉链表实现)JAVA代码
publicclassTest{ publicstaticvoid main(String[] args){ char[] ch =newchar[]{'A','B ...
- 建立二叉树的二叉链表(严6.65)--------西工大noj
需要注意的点:在创建二叉树的函数中,如果len1==len2==0,一定要把(*T)置为NULL然后退出循环 #include <stdio.h> #include <stdlib. ...
- Trees on the level (二叉链表树)
紫书:P150 uva122 Background Trees are fundamental in many branches of computer science. Current state- ...
随机推荐
- Revit API根据链接文件开洞
开洞信息数据: ]); ; ; ; ; ...
- Fortran中的指针使用
Fortran中的指针如何使用,功能怎样,下面的的5个例子足可以让你明白一切! 对于单个值,用起来很简单,但是无法体现指针的强大功能, 示例1: program test_pointer_1 impl ...
- 奇怪吸引子---QiChen
奇怪吸引子是混沌学的重要组成理论,用于演化过程的终极状态,具有如下特征:终极性.稳定性.吸引性.吸引子是一个数学概念,描写运动的收敛类型.它是指这样的一个集合,当时间趋于无穷大时,在任何一个有界集上出 ...
- Windows下Phalcon的安装以及phpstorm识别phalcon语法及提示
1.由于Phalcon是C语言写的一个扩展,所以需要安装这个扩展php_phalcon.dll,下载地址https://github.com/phalcon/cphalcon/releases, 然后 ...
- MySQL查看数据库表容量大小
本文介绍MySQL查看数据库表容量大小的命令语句,提供完整查询语句及实例,方便大家学习使用. 1.查看所有数据库容量大小 select table_schema as '数据库', sum(table ...
- 利用 Express 托管静态文件
通过 Express 内置的 express.static 可以方便地托管静态文件,例如图片.CSS.JavaScript 文件等. 将静态资源文件所在的目录作为参数传递给 express.stati ...
- 12C新特性 -- 共享asm口令文件
12C中,ASM口令文件,可以提供本地.远程登录asm的验证.当然,要想使用asm口令文件验证,必须为每个asm创建一个口令文件. 如果是使用asm存储,asmca在配置asm磁盘组的会后,会自动为a ...
- css中border-radius用法详解
border-radius:由浮点数字和单位标识符组成的长度值.border-top-left-radius --- 左上border-top-right-radius --- 右上border-bo ...
- Android 测试入门之---Monkey test
这周重点学习的也是Android monkey test 的一些相关知识,也对其进行了初步的操作和试验.讲学习资料整理如下 : Monkey是一个命令行工具 ,可以运行在模拟器里或实际设备中.它向系统 ...
- javascript 简略
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...