用二叉树表示法表示的树的操作
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Diagnostics;
using System.Collections.Generic;
namespace TreeDemo1
{
public class CSNode<T> where T:Entity
{
/// <summary>
/// 节点唯一的ID;
/// </summary>
private int id;
public int ID
{
internal set
{
id = value;
}
get
{
return id;
}
}
private T data;
public T Data
{
set
{
data = value;
}
get
{
return data;
}
}
private CSNode<T> firstChild;
public CSNode<T> FirstChild
{
set
{
firstChild = value;
}
get
{
return firstChild;
}
}
private CSNode<T> nextSibling;
public CSNode<T> NextSibling
{
set
{
nextSibling = value;
}
get
{
return nextSibling;
}
}
private CSNode<T> parent;
public CSNode<T> Parent
{
set
{
parent = value;
}
get
{
return parent;
}
}
public CSNode()
{
data = default(T);
firstChild = null;
nextSibling = null;
}
public CSNode(T _data)
{
data = _data;
firstChild = null;
nextSibling = null;
}
public CSNode(CSNode<T> _firstChild, CSNode<T> _nextSibling)
{
data = default(T);
firstChild = _firstChild;
nextSibling = _nextSibling;
}
public CSNode(T _data,CSNode<T> _firstChild, CSNode<T> _nextSibling)
{
data = _data;
firstChild = _firstChild;
nextSibling = _nextSibling;
}
/// <summary>
/// 用节点的ID是否相等作为判断两个节点是不是同一节点的标志
/// </summary>
/// <param name="_target">相比较的节点</param>
/// <returns>true:同一节点 false:不同节点</returns>
public bool EqualsNode(CSNode<T> _target)
{
return ID == _target.ID;
}
}
public class CSTree<T>:ITree<CSNode<T>> where T:Entity
{
private int validId = 100; //这里面存在一个隐患,如果实体不断消失,不断增加,但validId总是递增的,程序运行很长时间后,或许会超过int的取值范围
private CSNode<T> root;
public CSNode<T> Root
{
private set
{
root = value;
}
get
{
return root;
}
}
public CSTree()
{
root = null;
}
public CSTree(T _rootData)
{
root = new CSNode<T>(_rootData);
}
public CSNode<T> GetRoot()
{
return root;
}
/// <summary>
/// 因为很多方法用了递归,所以只好把返回的结果放在外面了,注意这个集合的值是随时会变的,使用它之前要先调用返回集合的方法。
/// 并且要注意清空
/// </summary>
public List<CSNode<T>> result;
//------------------------------------------------------------------------------------插入操作-----------------------------------------------------------------------------//
/// <summary>
/// 把一个节点插在父节点的第一个子节点位置上
/// </summary>
/// <param name="_parent">父节点</param>
/// <param name="_firstChild">将要插入的节点</param>
/// <returns>插入是否成功</returns>
public void InsertFirstChild(CSNode<T> _parent, CSNode<T> _firstChild)
{
if (_parent != null)
{
validId += 1;
_firstChild.ID = validId;
_firstChild.Data.ID = validId;
_firstChild.Parent = _parent;
_firstChild.NextSibling = _parent.FirstChild;
_parent.FirstChild = _firstChild;
}
}
/// <summary>
/// 把一个指定值的新节点插在父节点的第一个子节点位置上
/// </summary>
/// <param name="_parent">父节点</param>
/// <param name="_firstChild">将要插入的节点</param>
/// <returns>操作是否成功</returns>
public bool InsertFirstChild(CSNode<T> _parent, T _data)
{
if (_parent != null)
{
CSNode<T> temp = new CSNode<T>(_data);
validId += 1;
temp.ID = validId;
_data.ID = temp.ID;
temp.Parent = _parent;
temp.NextSibling = _parent.FirstChild;
_parent.FirstChild = temp;
return true;
}
return false;
}
/// <summary>
/// 把一个新节点插在父节点的最后一个子节点的后面
/// </summary>
/// <param name="_parent">父节点</param>
/// <param name="_lastChild">将要插入的节点</param>
/// <returns>操作是否成功</returns>
public bool InsertLastChild(CSNode<T> _parent,CSNode<T> _lastChild)
{
if(_parent!=null)
{
validId += 1;
_lastChild.ID = validId;
_lastChild.Data.ID = validId;
_lastChild.Parent = _parent;
if(_parent.FirstChild==null)
{
_parent.FirstChild = _lastChild;
}
else
{
GetLastChild(_parent).NextSibling = _lastChild;
}
return true;
}
return false;
}
/// <summary>
/// 把指定节点插入到源节点的指定位置
/// </summary>
/// <param name="_sourceNode">父节点</param>
/// <param name="_targetNode">被插入的节点</param>
/// <param name="_nodePos">需要插入的位置</param>
public void Insert(CSNode<T> _sourceNode, CSNode<T> _targetNode, int _nodePos)
{
if (_nodePos == 0)
{
InsertFirstChild(_sourceNode, _targetNode);
}
else if (_nodePos >= GetNodeDegree(_sourceNode))
{
InsertLastChild(_sourceNode, _targetNode);
}
else
{
CSNode<T> current = _sourceNode.FirstChild;
int nodePos = 1;
while (nodePos != _nodePos)
{
current = current.NextSibling;
nodePos++;
}
_targetNode.NextSibling = current.NextSibling;
current.NextSibling = _targetNode;
}
}
//-----------------------------------------------------------------------------------删除操作-------------------------------------------------------------------------//
/// <summary>
/// 删除目标节点
/// </summary>
/// <param name="_target">目标节点</param>
/// <returns>返回被删除的节点,如果没有此节点,则返回Null</returns>
public CSNode<T> Delete(CSNode<T> _target)
{
if (_target.EqualsNode(Root))
Root = null;
ClearChild(_target);
if (_target.Parent == null)
{
MessageBox.Show("节点不存在!");
return null;
}
if (_target.Parent.FirstChild.EqualsNode(_target))
{
_target.Parent.FirstChild = _target.NextSibling;
return _target;
}
else
{
CSNode<T> current = _target.Parent.FirstChild;
while (current.NextSibling!=null)
{
if (current.NextSibling.EqualsNode(_target))
{
current.NextSibling = _target.NextSibling;
return _target;
}
current = current.NextSibling;
}
return null;
}
}
/// <summary>
/// 删除目标节点指定位置的子节点
/// </summary>
/// <param name="_target">目标节点</param>
/// <param name="_pos">索引</param>
/// <returns>被删除的节点</returns>
public CSNode<T> DeleteChild(CSNode<T> _target, int _pos)
{
if (_pos < 0)
throw new Exception();
CSNode<T> result = null;
int searchPos = 0;
CSNode<T> next = null;
if (_pos == 0)
{
result = _target.FirstChild;
ClearChild(result);
_target.FirstChild = _target.FirstChild.NextSibling;
}
else
{
next = _target.FirstChild;
searchPos++;
while (searchPos != _pos)
{
next = next.NextSibling;
searchPos++;
}
result = next.NextSibling;
ClearChild(result);
next.NextSibling = result.NextSibling;
}
return result;
}
/// <summary>
/// 把父节点的所有子节点指向父节点的域和父节点的首子节点全部设为null
/// </summary>
/// <param name="_parent">父节点</param>
public void ClearChild(CSNode<T> _parent)
{
CSNode<T> next;
if (_parent.FirstChild != null)
{
next = _parent.FirstChild.NextSibling;
while (next != null)
{
next.Parent = null;
next = next.NextSibling;
}
_parent.FirstChild = null;
}
}
//-----------------------------------------------------------------------------------返回节点集合操作-------------------------------------------------------------------------//
/// <summary>
/// 取得父节点的最后一个子节点
/// </summary>
/// <param name="_parent">父节点</param>
/// <returns>父节点的最后一个子节点</returns>
public CSNode<T> GetLastChild(CSNode<T> _parent)
{
if(_parent.FirstChild==null)
{
return null;
}
CSNode<T> temp = _parent.FirstChild;
while(temp.NextSibling!=null)
{
temp = temp.NextSibling;
}
return temp;
}
/// <summary>
/// 返回指定节点的所有子节点,注意!仅仅是子节点,不包括节点的的节点
/// </summary>
/// <param name="_parent">父节点</param>
/// <returns>父节点的所有子节点的集合</returns>
public List<CSNode<T>> GetParentChildren(CSNode<T> _parent)
{
if (_parent.FirstChild != null)
{
List<CSNode<T>> result = new List<CSNode<T>>();
result.Add(_parent.FirstChild);
CSNode<T> current = _parent.FirstChild.NextSibling;
while (current != null)
{
result.Add(current);
current = current.NextSibling;
}
return result;
}
else
{
return null;
}
}
/// <summary>
/// 返回指定节点包括自己在内的所有兄弟节点,注意!仅仅是子节点,不包括节点的的节点
/// </summary>
/// <param name="_sibling">指定节点</param>
/// <returns>结果节点的集合</returns>
public List<CSNode<T>> GetSiblingChildren(CSNode<T> _sibling)
{
CSNode<T> parent = _sibling.Parent;
return GetParentChildren(parent);
}
/// <summary>
/// 返回所有的节点,注意!这个方法仅适用于取根节点
/// </summary>
/// <param name="_parent">这个参数只能是根节点</param>
public void GetAllChildren(CSNode<T> _parent)
{
if (_parent != null)
{
GetAllChildren(_parent.FirstChild);
result.Add(_parent);
GetAllChildren(_parent.NextSibling);
}
}
/// <summary>
/// 返回目标节点的所有子节点
/// </summary>
/// <param name="_parent">目标节点(父节点)</param>
public void GetTargetAllChildren(CSNode<T> _parent)
{
if (_parent.FirstChild != null)
{
result.Add(_parent.FirstChild);
GetTargetAllChildren(_parent.FirstChild);
CSNode<T> current = _parent.FirstChild.NextSibling;
while (current != null)
{
result.Add(current);
GetTargetAllChildren(current);
current = current.NextSibling;
}
}
}
//---------------------------------------------------------------------------------查找操作----------------------------------------------------------------//
public CSNode<T> GetNodeFromID(int _id)
{
result = new List<CSNode<T>>();
CSNode<T> resultNode = null;
GetAllChildren(root);
foreach (CSNode<T> item in result)
{
if (item.ID == _id)
{
resultNode = item;
break;
}
}
result.Clear();
result = null;
return resultNode;
}
//---------------------------------------------------------------------------------其他操作----------------------------------------------------------------//
/// <summary>
/// 判断是否是空树
/// </summary>
/// <returns>true:空树 false:非空树</returns>
public bool IsEmpty()
{
return root == null;
}
/// <summary>
/// 得到目标节点的度
/// </summary>
/// <param name="_target">目标节点</param>
/// <returns>目标节点的度</returns>
public int GetNodeDegree(CSNode<T> _target)
{
int result = 0;
CSNode<T> current = _target.FirstChild ;
while (current!= null)
{
result++;
current = current.NextSibling;
}
return result;
}
/// <summary>
/// 判断是否是叶子节点
/// </summary>
/// <param name="_target">需要判断的节点</param>
/// <returns>true:叶子节点 false:非叶子节点</returns>
public bool IsLeaf(CSNode<T> _target)
{
return GetNodeDegree(_target) == 0;
}
}
}