集合
集合(set)作为存储数据容器时:
- 它不允许存储相同元素,只能保留一份。
 
- 能快速帮助我们进行去重操作,过滤掉重复元素。
 
典型应用
词汇量统计
统计一篇英文文章的总单词数,使用集合进行去重,判断英文文章难度。
创建集合接口
新建Iset接口
namespace AlgorithmTest11_集合ISet {     interface Iset<T>     {                                    bool IsEmpty { get; }
                                     int Count { get; }
                                              void Add(T t);
                                              void Remove(T t);
                                                       bool Contains(T e);     } }
   | 
 
实现集合接口
使用无序链表LinkedList1Set实现集合接口
using AlgorithmTest08_链表;
  namespace AlgorithmTest11_集合ISet {                         public class LinkedList1Set<T> : Iset<T>     {                                    private LinkedList1<T> list;         public LinkedList1Set()         {             list = new LinkedList1<T>();         }
          public bool IsEmpty { get { return list.IsEmpty; } }
          public int Count { get { return list.Count; } }
          public void Add(T t)         {                          if (!list.Contains(t))             {                 list.AddFirst(t);             }         }
          public bool Contains(T t)         {             return list.Contains(t);         }
          public void Remove(T t)         {             list.Remove(t);         }     } }
   | 
 
创建工具类
创建TestHelper,用来将文件里文本存储到列表
using System; using System.Collections.Generic; using System.IO;
  namespace AlgorithmTest11_集合ISet {     class TestHelper     {                  public static List<string> ReadFile(string filename)         {                          FileStream fs = new FileStream(filename, FileMode.Open);                          StreamReader sr = new StreamReader(fs);                          List<string> words = new List<string>();                                       while (!sr.EndOfStream)             {                                  string contents = sr.ReadLine().Trim();                                  int start = FirstCharacterIndex(contents, 0);                                  for (int i = start + 1; i < contents.Length;)                 {                     if (i == contents.Length || !Char.IsLetter(contents[i]))                     {                         string word = contents.Substring(start, i - start).ToLower();                         words.Add(word);                         start = FirstCharacterIndex(contents, i);                         i = start + 1;                     }                     else                         i++;                 }             }                          fs.Close();             sr.Close();             return words;         }                  private static int FirstCharacterIndex(string s, int start)         {             for (int i = start; i < s.Length; i++)             {                 if (Char.IsLetter(s[i]))                 {                     return i;                 }             }             return s.Length;         }     } }
 
   | 
 
添加文档,修改文档属性


测试结果
using System; using System.Collections.Generic; using System.Diagnostics;
  namespace AlgorithmTest11_集合ISet {     class Program     {         static void Main(string[] args)         {             #region 集合             Stopwatch t = new Stopwatch();             Console.WriteLine("双城记");             List<string> words = TestHelper.ReadFile("txt/A Tale Of Two Cities.txt");             Console.WriteLine("总单词数:" + words.Count);                          LinkedList1Set<string> linkedset = new LinkedList1Set<string>();             t.Start();             foreach (var item in words)             {                 linkedset.Add(item);             }             t.Stop();
              Console.WriteLine("去重后:" + linkedset.Count);             Console.WriteLine("执行时长," + t.ElapsedMilliseconds + "ms");
              #endregion             Console.ReadKey();         }     } }
 
   | 
 

用时接近六秒,可以看出顺序查找非常耗时
映射/字典
定义接口
创建IDictionary<Key, Value>,定义接口
namespace AlgorithmTest12_映射or字典IDictionary {     interface IDictionary<Key, Value>     {                                                      void Add(Key key, Value value);                                             void Remove(Key key);                                                      bool ContainsKey(Key key);                                                      Value Get(Key key);                                                      void Set(Key key, Value newValue);                                    int Count { get; }                                    bool IsEmpty { get; }     } }
   | 
 
实现接口功能
新建字典专用链表
新建带两个泛型参数的链表
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;
  namespace AlgorithmTest12_映射or字典IDictionary {     class LinkedList3<Key, Value>     {         private class Node         {             public Key key;             public Value value;             public Node next;
              public Node(Key key, Value value, Node next)             {                 this.key = key;                 this.value = value;                 this.next = next;             }             public override string ToString()             {                 return key.ToString() + ":" + value.ToString();             }         }         private Node head;         private int N;         public LinkedList3()         {             head = null;             N = 0;         }         public int Count { get { return N; } }         public bool IsEmpty { get { return N == 0; } }
                   private Node GetNode(Key key)         {             Node cur = head;             while (cur != null)             {                                  if (cur.key.Equals(key))                 {                     return cur;                 }                 cur = cur.next;             }             return null;         }                                                      public void Add(Key key, Value value)         {             Node node = GetNode(key);             if (node == null)             {                 head = new Node(key, value, head);                 N++;             }             else             {                 node.value = value;             }         }                                                      public bool Contains(Key key)         {                          return GetNode(key) != null;         }                                                      public Value Get(Key key)         {             Node node = GetNode(key);             if (node == null)             {                 throw new ArgumentException("键" + key + "不存在");             }             else             {                 return node.value;             }         }                                                      public void Set(Key key, Value newValue)         {             Node node = GetNode(key);             if (node == null)             {                 throw new ArgumentException("键" + key + "不存在");             }             else             {                 node.value = newValue;             }         }                                             public void Remove(Key key)         {             if (head == null)             {                 return;             }             if (head.key.Equals(key))             {                 head = head.next;                 N--;             }             else             {                 Node cur = head;                 Node pre = null;                 while (cur != null)                 {                     if (cur.t.Equals(key))                     {                         break;                     }                     pre = cur;                     cur = cur.next;                                      }                 if (cur != null)                 {                     pre.next = pre.next.next;                     N--;                 }             }         }     } }
 
   | 
 
实现字典类
新建字典类,通过链表实现字典功能
namespace AlgorithmTest12_映射or字典IDictionary {     class LinkedList3Dictionary<Key, Value> : IDictionary<Key, Value>     {         private LinkedList3<Key, Value> list;
          public LinkedList3Dictionary()         {             list = new LinkedList3<Key, Value>();         }
          public int Count { get { return list.Count; } }
          public bool IsEmpty { get { return list.IsEmpty; } }
          public void Add(Key key, Value value)         {             list.Add(key, value);         }
          public bool ContainsKey(Key key)         {             return list.Contains(key);         }
          public Value Get(Key key)         {             return list.Get(key);         }
          public void Remove(Key key)         {             list.Remove(key);         }
          public void Set(Key key, Value newValue)         {             list.Set(key, newValue);         }     } }
 
   | 
 
运行调试
using System; using System.Collections.Generic; using System.Diagnostics;
  namespace AlgorithmTest12_映射or字典IDictionary {     class Program     {         static void Main(string[] args)         {             Console.WriteLine("字典双城记");             List<string> words = TestHelper.ReadFile("txt/A Tale Of Two Cities.txt");             Console.WriteLine("总单词数:" + words.Count);             Stopwatch t = new Stopwatch();                          LinkedList3Dictionary<string, int> dic = new LinkedList3Dictionary<string, int>();             t.Start();             foreach (var key in words)             {                                  if (!dic.ContainsKey(key))                 {                     dic.Add(key, 1);                 }                                  else                 {                                          dic.Set(key, dic.Get(key) + 1);                 }             }             t.Stop();             Console.WriteLine("不同的单词总数: " + dic.Count);             Console.WriteLine("city出现次数: " + dic.Get("city"));             Console.WriteLine("运行时长: " + t.ElapsedMilliseconds + "ms");             Console.ReadKey();         }     } }
 
   | 
 

总结
可以看出查找用时非常久,这是因为Set和Get每次都调用GetNode循环遍历节点,复杂度n。