二叉查找树的解析与实现
概念描述
二叉查找树或者是一棵空树,或者是具有下列性质的二叉树:
1、每个结点都有一个作为查找依据的关键码(key),所有结点的关键码互不相同。
2、左子树(如果存在)上所有结点的关键码都小于根结点的关键码。
3、右子树(如果存在)上所有结点的关键码都大于根结点的关键码。
4、左子树和右子树也是二叉查找树。
实现
节点定义
/// <summary>
/// 二叉树节点
/// </summary>
public class BtNode<T>
{
public BtNode()
{
LeftNode = null;
RightNode = null;
}
/// <summary>
/// 索引
/// </summary>
public string Key
{
get;
set;
}
/// <summary>
/// 数据对像
/// </summary>
public T Node
{
get;
set;
}
/// <summary>
/// 父节点
/// </summary>
public BtNode<T> Parent
{
get;set;
}
/// <summary>
/// 左节点
/// </summary>
public BtNode<T> LeftNode
{
get;
set;
}
/// <summary>
/// 右节点
/// </summary>
public BtNode<T> RightNode
{
get;
set;
}
}
树定义及方法
/// <summary>
/// 查找二叉树
/// </summary>
public class BTree<T>
{
private BtNode<T> _head;
/// <summary>
/// 头结点
/// </summary>
public BtNode<T> Head
{
get { return _head; }
}
public BTree(List<BtNode<T>> data)
{
_head = data[0];
for (int i = 1; i < data.Count; i++)
Add(_head, data[i]);
}
public BTree()
{
}
public bool Add(BtNode<T> node)
{
if (_head == null)
{
_head = node;
return true;
}
else
return Add(_head, node);
}
public bool Remove(BtNode<T> node)
{
return Remove(_head, node);
}
public T Find(string key)
{
if (_head != null)
return Find(_head, key).Node;
else
return default(T);
}
public BtNode<T> Find(BtNode<T> node)
{
if (_head != null)
return Find(_head, node.Key);
else
return null;
}
#region 私有方法
/// <summary>
/// 查找
/// </summary>
private BtNode<T> Find(BtNode<T> root, string key)
{
int comp = root.Key.CompareTo(key);
if (comp == 0)
return root;
else if (comp < 0)
{
if (root.LeftNode != null)
return Find(root.LeftNode, key);
else
return null;
}
else
{
if (root.RightNode != null)
return Find(root.RightNode, key);
else
return null;
}
}
/// <summary>
/// 新增节点
/// </summary>
private bool Add(BtNode<T> root, BtNode<T> node)
{
int comp = root.Key.CompareTo(node.Key);
if (comp < 0)//小于
{
if (root.LeftNode == null)
{
root.LeftNode = node;
node.Parent = root;
}
else
Add(root.LeftNode, node);
}
else if (comp == 0)//等于
return false;
else//大于
{
if (root.RightNode == null)
{
root.RightNode = node;
node.Parent = root;
}
else
Add(root.RightNode, node);
}
return true;
}
/// <summary>
/// 删除节点
/// </summary>
private bool Remove(BtNode<T> root, BtNode<T> node)
{
int comp = root.Key.CompareTo(node.Key);
if (comp < 0)
{
if (root.LeftNode == null)
return false;
else
Remove(root.LeftNode, node);
}
else if (comp == 0)
{
if (root.LeftNode == null && root.RightNode ==null)
{
if (root.Parent.LeftNode.Key.CompareTo(node.Key) == 0)
root.Parent.LeftNode = null;
else
root.Parent.RightNode = null;
}
else if (root.LeftNode != null)
{
root.LeftNode.Parent = root.Parent;
if (root.Parent.LeftNode.Key.CompareTo(node.Key) == 0)
root.Parent.LeftNode = root.LeftNode;
else
root.Parent.RightNode = root.LeftNode;
}
else
{
root.RightNode.Parent = root.Parent;
if (root.Parent.LeftNode.Key.CompareTo(node.Key) == 0)
root.Parent.LeftNode = root.RightNode;
else
root.Parent.RightNode = root.RightNode;
}
root = null;
}
else
{
if (root.RightNode == null)
return false;
else
Remove(root.RightNode, node);
}
return true;
}
#endregion
}
测试
int maxsize = 2000000;
Dictionary<int, string> dict = new Dictionary<int, string>();
BTree<int> tree = new BTree<int>();
DateTime hashStart = DateTime.Now;
for (int i = 0; i < maxsize; i++)
{
string guid = Guid.NewGuid().ToString();
dict.Add(i, guid);
}
DateTime hashEnd = DateTime.Now;
System.Console.WriteLine("hash构建时间:" + hashEnd.Subtract(hashStart).ToString());
DateTime treeStart = DateTime.Now;
foreach (KeyValuePair<int, string> kvp in dict)
tree.Add(new BtNode<int> { Key = kvp.Value, Node = kvp.Key });
DateTime treeEnd = DateTime.Now;
System.Console.WriteLine("tree构建时间:" + treeEnd.Subtract(treeStart).ToString());
int min, max;
int num = 300;
int[] values = new int[num];
for (int i = 1; i <= num; i++)
{
if (i == 1)
min = 0;
else
min = maxsize / num * (i - 1);
max = maxsize / num * i - 1;
Random ran = new Random();
values[i - 1] = ran.Next(min, max);
}
DateTime data1 = DateTime.Now;
string[] key = new string[num];
for (int i = 0; i < num; i++)
{
key[i] = dict[values[i]];
}
DateTime data2 = DateTime.Now;
System.Console.WriteLine("hash查找时间:" + data2.Subtract(data1).ToString());
DateTime data3 = DateTime.Now;
for (int i = 0; i < num; i++)
{
if (values[i] != tree.Find(key[i]))
System.Console.WriteLine("未找到值:" + values[i]);
}
DateTime data4 = DateTime.Now;
System.Console.WriteLine("tree查找时间:" + data4.Subtract(data3).ToString());
System.Console.ReadKey();
浙公网安备 33010602011771号