二叉查找树的解析与实现

概念

实现

      结点定义

      树定义及方法

      测试

概念描述

二叉查找树或者是一棵空树,或者是具有下列性质的二叉树:

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();

  

posted @ 2011-08-15 23:47  Bindog  阅读(250)  评论(0)    收藏  举报