1.基于二叉查找树实现集合
class BST1Set<E> : ISet<E> where E : IComparable<E>
{
private BST1<E> bst;
public BST1Set()
{
bst = new BST1<E>();
}
public int Count { get { return bst.Count; } }
public bool IsEmpty { get { return bst.IsEmpty; } }
public void Add(E e)
{
bst.Add(e);
}
public bool Contains(E e)
{
return bst.Contains(e);
}
public void Remove(E e)
{
bst.Remove(e);
}
public int MaxHeigh()
{
return bst.MaxHeigh();
}
}
与基于有序数组实现的集合对比测试:
class Program
{
private static long TestSet(ISet<string> set, List<string> words)
{
Stopwatch t = new Stopwatch();
t.Start();
foreach (string word in words)
set.Add(word);
t.Stop();
return t.ElapsedMilliseconds;
}
static void Main(string[] args)
{
Console.WriteLine("双城记");
List<string> words = TestHelper.ReadFile("测试文件1/双城记.txt");
Console.WriteLine("词汇量总数:" + words.Count);
Console.WriteLine();
Console.WriteLine("(基于二叉查找树实现)集合");
BST1Set<string> bST1Set = new BST1Set<string>();
long t1 = TestSet(bST1Set, words);
Console.WriteLine("不同单词的总数:" + bST1Set.Count);
Console.WriteLine("运行时间:" + t1 + "ms");
Console.WriteLine("数的最大高度:" + bST1Set.MaxHeigh());
Console.WriteLine();
Console.WriteLine("(基于有序数组实现)集合");
SortedArray1Set<string> sortedArray1Set = new SortedArray1Set<string>();
long t2 = TestSet(sortedArray1Set, words);
Console.WriteLine("不同单词的总数:" + sortedArray1Set.Count);
Console.WriteLine("运行时间:" + t2 + "ms");
Console.Read();
}
}
测试1万个数字顺序添加:
class Program
{
static void Main(string[] args)
{
Stopwatch t = new Stopwatch();
t.Start();
BST1Set<int> set = new BST1Set<int>();
for (int i = 0; i < 10000; i++)
set.Add(i);
t.Stop();
Console.WriteLine("运行时间:" + t.ElapsedMilliseconds + "ms");
Console.WriteLine("树的最大高度:"+set.MaxHeigh());
Console.Read();
}
}
树的最大高度等于顺序传入数的数量。
测试10万个数字顺序添加:
class Program
{
static void Main(string[] args)
{
Stopwatch t = new Stopwatch();
t.Start();
BST1Set<int> set = new BST1Set<int>();
for (int i = 0; i < 100000; i++)
set.Add(i);
t.Stop();
Console.WriteLine("运行时间:" + t.ElapsedMilliseconds + "ms");
Console.WriteLine("树的最大高度:"+set.MaxHeigh());
Console.Read();
}
}
由于栈的存储空间不足以存放10万高度的树,导致栈溢出,抛出异常。
测试100万个随机数进行存储:
class Program
{
static void Main(string[] args)
{
Random r = new Random();
//r.Next() [0,2147483647)
Stopwatch t = new Stopwatch();
t.Start();
BST1Set<int> set = new BST1Set<int>();
for (int i = 0; i < 1000000; i++)
set.Add(r.Next());
t.Stop();
Console.WriteLine("运行时间:" + t.ElapsedMilliseconds + "ms");
Console.WriteLine("树的最大高度:"+set.MaxHeigh());
Console.Read();
}
}
2.基于二叉查找树实现映射
二叉查找树:
class BST2<Key, Value> where Key : IComparable<Key>
{
private class Node
{
public Key key;
public Value value;
public Node left;
public Node right;
public Node(Key key, Value value)
{
this.key = key;
this.value = value;
left = null;
right = null;
}
}
private Node root;
private int N;
public BST2()
{
root = null;
N = 0;
}
public int Count { get { return N; } }
public bool IsEmpty { get { return N == 0; } }
public void Add(Key key, Value value)
{
root = Add(root, key, value);
}
//递归
private Node Add(Node node, Key key, Value value)
{
if (node == null)
{
N++;
return new Node(key, value);
}
if (key.CompareTo(node.key) < 0)
node.left = Add(node.left, key, value);
else if (key.CompareTo(node.key) > 0)
node.right = Add(node.right, key, value);
else //要添加的value已存在,更新value的值
node.value = value;
return node;
}
private Node Min(Node node)
{
if (node.left == null)
return node;
return Min(node.left);
}
//删除掉以node为根的二叉查找树中的最小节点
//返回删除节点后新的二叉查找树的根
private Node RemoveMin(Node node)
{
if (node.left == null)
{
N--;
return node.right;
}
node.left = RemoveMin(node.left);
return node;
}
public void Remove(Key key)
{
root = Remove(root, key);
}
//删除以node为根的二叉查找树中值为e的节点
//返回删除节点后新的二叉查找树的根
private Node Remove(Node node, Key key)
{
if (node == null)
return null;
if (key.CompareTo(node.key) < 0)
{
node.left = Remove(node.left, key);
return node;
}
else if (key.CompareTo(node.key) > 0)
{
node.right = Remove(node.right, key);
return node;
}
else //key.CompareTo(node.key)>0
{
if (node.right == null)
{
N--;
return node.left;
}
if (node.left == null)
{
N--;
return node.right;
}
//要删除的节点左右都有孩子
//找到比待删除节点大的最小节点,即待删除节点右子树的最小节点
//用这个节点顶替待删除节点的位置
Node s = Min(node.right);
s.right = RemoveMin(node.right);
s.left = node.left;
return s;
}
}
//返回以node为根节点的二叉查找树中,key所在的节点
private Node GetNode(Node node, Key key)
{
if (node == null)
return null;
if (key.Equals(node.key))
return node;
else if (key.CompareTo(node.key) < 0)
return GetNode(node.left, key);
else //key.CompareTo(node.key) > 0
return GetNode(node.right, key);
}
//查看是否包含指定的键
public bool Contains(Key key)
{
return GetNode(root, key) != null;
}
//通过一个键获取对应的值
public Value Get(Key key)
{
Node node = GetNode(root, key);
if (node == null)
throw new ArgumentException("键" + key + "不存在,无法获取对应值!");
else
return node.value;
}
public void Set(Key key,Value newValue)
{
Node node = GetNode(root, key);
if (node == null)
throw new ArgumentException("键" + key + "不存在,无法更改对应值!");
else
node.value = newValue;
}
}
基于二叉查找树实现映射:
class BST2Dictionary<Key, Value> : IDictionary<Key, Value> where Key : IComparable<Key>
{
private BST2<Key, Value> bst;
public BST2Dictionary()
{
bst = new BST2<Key, Value>();
}
public int Count { get { return bst.Count; } }
public bool IsEmpty { get { return bst.IsEmpty; } }
public void Add(Key key, Value value)
{
bst.Add(key, value);
}
public bool ContainsKey(Key key)
{
return bst.Contains(key);
}
public Value Get(Key key)
{
return bst.Get(key);
}
public void Remove(Key key)
{
bst.Remove(key);
}
public void Set(Key key, Value newValue)
{
bst.Set(key, newValue);
}
}
与基于有序数组实现的字典对比测试:
class Program
{
private static long TestDictionary(IDictionary<string, int> dic, List<string> words)
{
Stopwatch t = new Stopwatch();
t.Start();
foreach (string word in words)
{
//如果单词不存在字典中,说明是第一次遇见这个单词,频次设为1
if (!dic.ContainsKey(word))
dic.Add(word, 1);
//如果单词已经存在于字典中,将单词对应的频次+1
else
dic.Set(word, dic.Get(word) + 1);
}
t.Stop();
return t.ElapsedMilliseconds;
}
static void Main(string[] args)
{
Console.WriteLine("双城记");
List<string> words = TestHelper.ReadFile("测试文件1/双城记.txt");
Console.WriteLine("词汇量总数:" + words.Count);
Console.WriteLine();
Console.WriteLine("(基于二叉查找树实现)字典");
BST2Dictionary<string, int> dic1 = new BST2Dictionary<string, int>();
long t1 = TestDictionary(dic1, words);
Console.WriteLine("不同单词的总数:" + dic1.Count);
Console.WriteLine("city出现的频次:" + dic1.Get("city"));
Console.WriteLine("运行时间:" + t1 + "ms");
Console.WriteLine();
Console.WriteLine("(基于有序数组实现)字典");
SortedArray2Dictionary<string, int> dic2 = new SortedArray2Dictionary<string, int>();
long t2 = TestDictionary(dic2, words);
Console.WriteLine("不同单词的总数:" + dic2.Count);
Console.WriteLine("city出现的频次:" + dic2.Get("city"));
Console.WriteLine("运行时间:" + t2 + "ms");
Console.Read();
}
}