The previous articles introduced the basic sorting algorithms. Sorting is usually a prelude to searching. This article introduces basic search algorithms. When introducing the search algorithm, we first need to understand the abstract data structure of the symbol table. This article first introduces what is a symbol table and the API of this abstract data structure, then we introduce two simple symbol table implementation methods. Before introducing the search algorithm to a symbolic Table, we need to define an abstract data structure named Symbol Table, which is similar to the Dictionary we use in C, it is an abstraction of elements with key-value pairs. Each element has a key and value. We can add key-value pairs to it, you can also search for value based on the key. In real life, we often encounter various situations where we need to search for value based on the key. For example, DNS searches for IP addresses based on the domain name, and the library searches for books based on the index number: to implement this function, SymbolTableApplication defines an abstract data structure and selects an appropriate data structure for implementation: public class ST <Key, Value> ST () create a query table object void Put (Key key Key, Value val) and insert a key-value Pair record into the set. If the Value is empty, no Value Get (Key key Key) is added) searches for value based on the key. If no value is found, the return value is null void Delete (Key key). The record boolean Contains (key Key key) with the deletion key as the Key is returned) boolean IsEmpty () indicates whether a record with the key as the key exists in the set. int Size () indicates whether the table is null. int Size () indicates the number of key-value pairs in the set. I Terable <Key> Keys () returns all the Keys in the set. 2. Implement 1. Use an unordered linked list to find a table. The Key lies in the selection of data structures, one of the simplest implementations is to use unordered linked lists. Each node records the key value, value, and object pointing to the next record. SymbolTableImplementByUnOrderedLinkList. When we insert an element into the linked list, we start searching from the header. If it is found, the value is updated. Otherwise, a new node element is inserted in the header. Implementation is also simple: public class SequentSearchSymbolTable <TKey, TValue>: SymbolTables <TKey, TValue> where TKey: IComparable <TKey>, IEquatable <TKey> {private int length = 0; node first; private class Node {public TKey key {get; set;} public TValue value {get; set;} public Node next {get; set;} public Node (TKey key, TValue, Node next) {this. key = key; this. value = value; this. next = next ;}} Public override TValue Get (TKey key) {TValue result = default (TValue); Node temp = first; while (temp! = Null) {if (temp. key. equals (key) {result = temp. value; break;} temp = temp. next;} return result;} public override void Put (TKey key, TValue value) {Node temp = first; while (temp! = Null) {if (temp. key. equals (key) {temp. value = value; return;} temp = temp. next;} first = new Node (key, value, first); length ++ ;}....} analysis: from the graph or code analysis, we can see that we need to search before inserting data. If so, we need to update the value. During the search, we need to search from the linked list header, therefore, the average time complexity of insertion and search is O (n ). So is there a better method? Next we will introduce binary search. 2. Using Binary lookup to find a table is different from using an unordered linked list. The idea of binary lookup is to maintain a two-dimensional array sorted by key internally, compare with the intermediate element. If the element is small, continue the left half recursive search; otherwise, continue the right half recursive search. The implementation code is as follows: class BinarySearchSymbolTable <TKey, TValue>: SymbolTables <TKey, TValue> where TKey: IComparable <TKey>, IEquatable <TKey> {private TKey [] keys; private TValue [] values; private int length; private static readonly int INIT_CAPACITY = 2; public BinarySearchSymbolTable (int capacity) {keys = new TKey [capacity]; values = new TValue [capacity]; length = capacity;} public BinarySearchSymbolTabl E (): this (INIT_CAPACITY) {}/// <summary> /// search for value based on the key. /// First, find the location where the key is located in the keys. If it is within the length range and the value of this location is equal to the key, return the value. // otherwise, does not exist // </summary> /// <param name = "key"> </param> // <returns> </returns> public override TValue Get (TKey key) {int I = Rank (key); if (I <length & keys [I]. equals (key) return values [I]; else return default (TValue) ;}/// <summary> // Insert key-value pairs to the symbol table. /// If an equal key exists, the value is directly updated; otherwise, the key and value are inserted to an appropriate position. // 1. first, move all the elements from the position to the next position as // 2. then, let's talk about this element in the position I. /// </summary> /// <param name = "key"> </param> /// <param name =" value "> </param> public override void Put (TKey key, TValue) {int I = Rank (key); if (I <length & keys [I]. equals (key) {values [I] = value; return;} // if the length is equal, expand if (length = keys. length) Resize (2 * keys. length); for (int j = length; j> I; j --) {keys [j] = keys [j-1]; values [j] = values [j-1];} keys [I] = key; values [I] = value; length ++ ;} /// <summary> /// return the position of the key in the array /// </summary> /// <param name = "key"> </param> /// <returns> </returns> private int Rank (TKey key) {int lo = 0; int hi = length-1; while (lo <= hi) {int mid = lo + (hi-lo)/2; if (key. compareTo (keys [mid])> 0) lo = mid + 1; else if (key. compareTo (keys [m Id]) <0) hi = mid-1; else return mid;} return lo ;}...} Here the emphasis is on the Rank method. We can see that the mid position is obtained first, then the current element and the mid position element are compared, and then the lo or hi location is updated to replace with the mid, if an equal value is found, the system returns the mid value. Otherwise, the system returns the appropriate position of the element to be inserted in the set. The above is implemented through iteration, and can also be rewritten to recursion: private int Rank (TKey key, int lo, int hi) {if (lo> = hi) return lo; int mid = lo + (hi-lo)/2; if (key. compareTo (keys [mid])> 0) return Rank (key, mid + 1, hi); else if (key. compareTo (keys [mid]) <0) return Rank (key, lo, hi-1); else return mid ;}