什么是数结构
树结构是一种非线性层次关系的数据结构,其中重要的是树的概念,树是n个结点的集合,在该结构中包含一个根节点,根节点之下有一些交叉的子集合,这些集合是根节点的子树,
几个特性:
- 在树结构中,有且只有一个跟结点没有直接前驱,这个结点就是树的根节点。
- 除了根节点外,其他结点都有一个直接前驱。
- 每个结点可以有任意多个后驱结点。
树的基本概念
- 父节点和子节点,每个结点子树的跟称为该结点的子结点,相应的,该结点称为其子结点的父节点。
- 兄弟结点,具有同一父节点的结点称为兄弟结点。
- 结点的度,一个结点所包含子树的数量。
- 树的度,指该树所有结点中最大的度。
- 叶结点,树中度为零的结点称为叶结点或者终端结点。
- 分支结点,树中度不为零的结点称为分支结点或者非终端结点。
- 结点的层树,结点的层树是从树根开始算的,跟结点为第一层,依次往下。
- 树的深度,树中结点的最大层树称为树的深度。
- 有序树,若树中各结点的子树是按一定次序从左到右排列,称为有序树,
- 无序树若树中的子结点未按一定次序排序,称为无序树。
- 森林 n(n>0)棵互不相交的树的集合。
二叉树
每个结点至多拥有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。
代码示例
public class CBTType
{
public string data; //元素数据
public CBTType left; //左子树结点引用
public CBTType right; //右子树结点引用
}
public class Tree
{
static int MAXLEN = 20; //最大长度
public CBTType InitTree() //初始化二叉树
{
CBTType node;
if ((node = new CBTType()) != null)
{
Console.WriteLine("请输入一个根节点数据");
node.data = Console.ReadLine();
node.left = null;
node.right = null;
if (node != null)
{
return node;
}
else
{
return null;
}
}
return null;
}
//添加结点
public void AddTreeNode(CBTType treeNode)
{
CBTType pnode, parent;
string data; //数据
int menused; //成员 左结点 / 右结点
if ((pnode = new CBTType()) != null)
{
Console.WriteLine("请输入一个根节点数据");
pnode.data = Console.ReadLine(); //创建新结点
pnode.left = null;
pnode.right = null;
data = Console.ReadLine(); //输入父节点数据
parent = TreeFindNode(treeNode, data);
Console.WriteLine("请输入该结点的父结点");
if (parent == null)
{
Console.WriteLine("未能找到父节点");
pnode = null;
return;
}
//添加到左还是右结点?
menused = int.Parse(Console.ReadLine());
do
{
if (menused == 1 || menused == 2)
{
if (parent == null)
{
Console.WriteLine("不存在父节点");
}
else
{
switch (menused)
{
case 1:
{
//左结点
if (parent.left != null)
{
//左子树不为空
Console.WriteLine("左子树不为空,不能添加");
}
else
{
parent.left = pnode;
}
}
break;
case 2:
{
//右结点
if (parent.right != null)
{
//右子树不为空
Console.WriteLine("右子树不为空,不能添加");
}
else
{
parent.right = pnode;
}
}
break;
default:
Console.WriteLine("无效参数");
break;
}
}
}
}
while (menused != 1 && menused != 2);
}
}
//查找结点
public CBTType TreeFindNode(CBTType treeNode, string data)
{
CBTType ptr;
if (treeNode == null)
{
return null;
}
if (treeNode.data.Equals(data))
{
return treeNode;
}
else
{
//分别向左右子树递归查找
if ((ptr = TreeFindNode(treeNode.left, data)) != null)
{
return ptr;
}
else if ((ptr = TreeFindNode(treeNode.right, data)) != null)
{
return ptr;
}
return null;
}
}
//获取左子树
public CBTType GetLetfNode(CBTType treeNode)
{
if (treeNode == null)
{
return null;
}
if (treeNode.left != null)
{
return treeNode.left;
}
return null;
}
//获取右子树
public CBTType GetRightNode(CBTType treeNode)
{
if (treeNode == null)
{
return null;
}
if (treeNode.right != null)
{
return treeNode.right;
}
return null;
}
//判断是否为空树
public int TreeEmpty(CBTType tree)
{
if (tree != null)
{
return 0;
}
else
{
return 1;
}
}
//计算二叉树的深度
public int TreeDepth(CBTType treeNode)
{
int depleft, depright; //左右子树深度
if (treeNode == null)
{
return 0; //空
}
depleft = TreeDepth(treeNode.left);
depright = TreeDepth(treeNode.right);
if (depleft > depright)
{
return depleft++;
}
else
{
return depright++;
}
}
//清空二叉树
public void ClesrTree(CBTType treeNode)
{
if (treeNode != null)
{
ClesrTree(treeNode.left);
ClesrTree(treeNode.right);
treeNode = null;
}
}
//显示结点数据
public void TreeNodeData(CBTType treeNode)
{
if (treeNode == null)
{
return;
}
Console.WriteLine(treeNode.data);
}
//遍历树 按层
public void LevelTree(CBTType treeNode)
{
if (treeNode == null)
{
return;
}
CBTType p;
CBTType[] q = new CBTType[MAXLEN]; //定义一个顺序栈
int hrad = 0;
int tail = 0;
tail = (tail + 1) % MAXLEN; //计算循环队列对尾序号
q[tail] = treeNode; //将二叉树根引用进队
if (hrad != tail)
{
//队列不为空进入循环
hrad = (hrad + 1) % MAXLEN;
p = q[hrad];
TreeNodeData(p);
if (p.left != null)
{
tail = (tail + 1) % MAXLEN;
q[tail] = p.left;
}
if (p.right != null)
{
tail = (tail + 1) % MAXLEN;
q[tail] = p.right;
}
}
}
public void DLRTree(CBTType treeNode)
{
if (treeNode == null)
{
return;
}
TreeNodeData(treeNode);
DLRTree(treeNode.left);
DLRTree(treeNode.right);
}
public void LDRTree(CBTType treeNode)
{
if (treeNode == null)
{
return;
}
LDRTree(treeNode.left);
TreeNodeData(treeNode);
LDRTree(treeNode.right);
}
public void LRDTree(CBTType treeNode)
{
if (treeNode == null)
{
return;
}
LRDTree(treeNode.left);
LRDTree(treeNode.right);
TreeNodeData(treeNode);
}
}