Introduction to Dynamic Set

 

  A Dynamic Set is an Abstract Data Type (ADT) that can support the following operations:

  (1)  search for an item to determine whether the item exists in the set;

  (2)  insert a new item into the set;

  (3)  delete a current item from the set.


1. Binary Search Tree

  All the operations mentioned above have a time performance of O(h) in a Binary Search Tree (BST), where h is the height of the BST. In order to maintain the balance of such a binary tree and thus gain a relatively good time performance, sophisticated strategies are exploited in AVL Tree, Red-Black Tree and other advanced data structures. Here I would only provide a Java class of a naive binary search tree.

  1 class BST<T extends Comparable> {
  2     private class Node<T> {
  3         // Node of Binary Search Tree
  4         public Node<T> left, right;
  5         public T data;
  6     }
  7     
  8     private Node<T> root;     // root of Binary Search Tree
  9     private int minIdx;    // index aimed to help ithMin
 10     
 11     public boolean search(T item) {
 12         // Search for an item starting from the root
 13         //        return whether such an item exists
 14         return srchHelp(root,item)!=null;
 15     }
 16     private Node<T> srchHelp(Node<T> sub,T item) {
 17         // Search a Node that contains item as its data
 18         //        return such a Node of the minimum depth
 19         //        if no such Node exists, return null
 20         if (sub==null||sub.data.equals(item)) {
 21             return sub;
 22         } else if (sub.data.compareTo(item)<0) {
 23             return srchHelp(sub.right,item);
 24         } else {
 25             return srchHelp(sub.left,item);
 26         }
 27     }
 28     public void insert(T item) {
 29         // Insert an item to BST starting from root
 30         root = insHelp(root, item);
 31     }
 32     private Node<T> insHelp(Node<T> sub,T item) {
 33         // Insert an item to a subtree recursively
 34         if (sub==null) {
 35             sub = new Node<T>();
 36             sub.data = item;
 37         } else if (item.compareTo(sub.data)<0) {
 38             sub.left = insHelp(sub.left,item);
 39         } else {
 40             sub.right = insHelp(sub.right,item);
 41         }
 42         return sub;
 43     }
 44     public void delete(T item) {
 45         // Delete a Node with data item from BST
 46         root = delHelp(root,item);
 47     }
 48     public Node<T> delHelp(Node<T> sub,T item) {
 49         // Search an item and ultimately delete it
 50         if (sub==null) {
 51             return null;
 52         } else if (item.compareTo(sub.data)==0) {
 53             sub = delNode(sub);
 54         } else if (item.compareTo(sub.data)<0) {
 55             sub.left = delHelp(sub.left,item);
 56         } else {
 57             sub.right = delHelp(sub.right,item);
 58         }
 59         return sub;
 60     }
 61     private Node<T> delNode(Node<T> sub) {
 62         // Delete the Node sub given sub!=null
 63         if (sub.right==null) {
 64             return sub.left;
 65         } else if (sub.left==null) {
 66             return sub.right;
 67         } else if (sub.right.left==null) {
 68             sub.data = sub.right.data;
 69             sub.right = sub.right.right;
 70             return sub;
 71         } else {
 72             Node<T> prev = sub.right;
 73             while (prev.left.left!=null) {
 74                 prev = prev.left;
 75             }
 76             sub.data = prev.left.data;
 77             prev.left = prev.left.right;
 78             return sub;
 79         }
 80     }
 81     public void delLessThan(T item) {
 82         // Delete items less than item starting from root
 83         root = delLessThanHelp(root,item);
 84     }
 85     private Node<T> delLessThanHelp(Node<T> sub,T item) {
 86         // Delete items less than item from a subtree
 87         if (sub==null) {
 88             return null;
 89         } else if (sub.data.compareTo(item)<0) {
 90             sub.left = delLessThanHelp(sub.left,item);
 91             return delLessThanHelp(sub.right,item);
 92         } else {
 93             sub.left = delLessThanHelp(sub.left,item);
 94             return sub;
 95         }
 96     }
 97     public void delGreaterThan(T item) {
 98         // Delete items greater than item starting from root
 99         root = delGreaterThanHelp(root,item);
100     }
101     private Node<T> delGreaterThanHelp(Node<T>  sub,T item) {
102         // Delete items greater than item from a subtree
103         if (sub==null) {
104             return null;
105         } else if (sub.data.compareTo(item)>0) {
106             sub.right = delGreaterThanHelp(sub.right,item);
107             return delGreaterThanHelp(sub.left,item);
108         } else {
109             sub.right = delGreaterThanHelp(sub.right,item);
110             return sub;
111         }
112     }
113     public void delInterval(T a, T b) {
114         // Delete items greater than a && less than b
115         root = delIntervalHelp(root,a,b);
116     }
117     public Node<T> delIntervalHelp(Node<T> sub,T a,T b) {
118         // Delete items belonging to (a,b) from a subtree
119         if (a.compareTo(b)>=0) {
120             return sub;
121         } else if (sub==null) {
122             return null;
123         } else if (sub.data.compareTo(a)<=0) {
124             sub.right = delIntervalHelp(sub.right,a,b);
125         } else if (sub.data.compareTo(b)>=0) {
126             sub.left = delIntervalHelp(sub.left,a,b);
127         } else {
128             sub.left = delIntervalHelp(sub.left,a,b);
129             sub.right = delIntervalHelp(sub.right,a,b);
130             sub = delNode(sub);
131         }
132         return sub;
133     }
134     public T ithMin(int idx) {
135         // Return the idx-th least item in BST
136         if (idx<=0) {
137             return null;
138         } else {
139             minIdx = idx;
140             return ithMinHelp(root);
141         }
142     }
143     private T ithMinHelp(Node<T> sub) {
144         // Return the minIdx-th least item recursively
145         if (sub==null) {
146             return null;
147         } else {
148             T val = ithMinHelp(sub.left);
149             if (minIdx<=0) {
150                 // counting has been terminated
151                 return val;
152             } else if (--minIdx==0) {
153                 // termination of counting
154                 return sub.data;
155             } else {
156                 // counting is going on
157                 return ithMinHelp(sub.right);
158             }
159         }
160     }
161     public void display()  {
162         inOrderTraverse(root);
163         System.out.println();
164     }
165     private void inOrderTraverse(Node<T> sub) {
166         if (sub!=null) {
167             inOrderTraverse(sub.left);
168             System.out.print("\t"+sub.data);
169             inOrderTraverse(sub.right);
170         }
171     }
172 }

 

2. Hash Table

  In a Hash Table, a hash function maps an item to its proper slot in the table and thus each set operation can gain a time performance of O(1). To tackle the problem of what is called "conflict", we can resort to either Open Hashing or Chaining. Here, I used a chaining hash table to solve a problem from SJTU ACM Online Judge,

 1 import java.util.*;
 2 
 3 class Hash  {
 4     private class Node {
 5         public int data;
 6         public int cnt = 1;
 7         public Node next;
 8     }
 9     
10     private final int SIZE = 100003;
11     private Node[] tbl;
12     
13     public Hash() {
14         tbl = new Node[SIZE];
15         for (int i=0;i<SIZE;i++) {
16             tbl[i] = new Node();
17         }
18     }
19     private int index(int item) {
20         // Hash function using division method
21         if (item%SIZE<0) {
22             return item%SIZE+SIZE;
23         } else {
24             return item%SIZE;
25         }
26     }
27     public void insert(int item) {
28         // Insert an item to the hash table
29         Node itr = tbl[index(item)];
30         while (itr.next!=null) {
31             if (itr.next.data==item) {
32                 itr.next.cnt++;
33                 return;
34             } else {
35                 itr = itr.next;
36             }
37         }
38         itr.next = new Node();
39         itr.next.data = item;
40     }
41     public int search(int item) {
42         // Search an item in the hash table
43         //        return its count value
44         Node itr = tbl[index(item)].next;
45         while (itr!=null) {
46             if (itr.data==item) {
47                 return itr.cnt;
48             } else {
49                 itr = itr.next;
50             }
51         }
52         return 0;
53     }
54 }
55 
56 public class Main {
57     public static void main(String[] args) {
58         // get and store the input data
59         Scanner in = new Scanner(System.in);
60         int num = in.nextInt();
61         int[][] table = new int [num][4];
62         for (int i=0;i<num;i++) {
63             table[i][0] = in.nextInt();
64             table[i][1] = in.nextInt();
65             table[i][2] = in.nextInt();
66             table[i][3] = in.nextInt();
67         }
68         in.close();
69         // build up the hash table
70         Hash set = new Hash();
71         for (int i=0;i<num;i++) {
72             for (int j=0;j<num;j++) {
73                 set.insert(table[i][0]+table[j][1]);
74             }
75         }
76         // solve the problem and print the result
77         int val = 0;
78         for (int i=0;i<num;i++) {
79             for (int j=0;j<num;j++) {
80                 val += set.search(-table[i][2]-table[j][3]);
81             }
82         }
83         System.out.println(val);
84     }
85 
86 }

 

P.S.  关于链表的操作比较易错的是遍历的同时删除结点,应该这样做:

 1     private void srchAndDel(int del) {
 2         Node itr = tbl[index(item)];
 3         while (itr.next!=null) {
 4             if (itr.next.data==item) {
 5                 itr.next = itr.next.next;
 6                 continue;    //    Attention!
 7             }
 8             itr = itr.next;
 9         }
10     }

 

3. Cantor Expansion

  In the example above, I constructed a hash function by Division Method and this may seem more than facile. However, in other cases, the construction of a proper hash function may be a rather tricky work, which involves a lot of mathematical knowledge. Here, I'd like to take Cantor Expansion for example, a bijection that maps a permutation of n distinct integers to a natural number index in a hash table.

 1     public static int cantor(int[] perm) {
 2         // Encode a 0 through n-1 permutation into an index
 3         int val = 0, len = perm.length;
 4         int[] cnt = new int[len];
 5         boolean[] vis = new boolean[len];
 6         for (int i=0;i<len;i++) {
 7             for (int j=0;j<perm[i];j++) {
 8                 // cnt[i] is the number of unvisited numbers
 9                 //        that are smaller than perm[i]
10                 cnt[i] += (vis[j])? 0:1;
11             }
12             vis[perm[i]] = true;
13         }
14         for (int i=0;i<len;i++) {
15             val = val*(len-i)+cnt[i];
16         }
17         return val;
18     }
19     public static void cantInv(int code,int[] perm) {
20         // Decode an index into a 0 through n-1 permutation
21         int len = perm.length;
22         int[] fact = new int[len];
23         fact[0] = 1;
24         for (int i=1;i<len;i++) {
25             // fact[i] stores i factorial
26             fact[i] = fact[i-1]*i;
27         }
28         boolean[] vis = new boolean[len];
29         for (int i=0;i<len;i++) {
30             int cnt = code/fact[len-i-1];
31             for (int j=0;j<len;j++) {
32                 // perm[i] is the (cnt+1) th smallest one among unvisited items
33                 if (!vis[j]&&--cnt<0) {
34                     perm[i] = j;
35                     break;
36                 }
37             }
38             vis[perm[i]] = true;
39             code %= fact[len-i-1];
40         }
41     }

 

posted on 2015-03-20 22:11  DevinZ  阅读(177)  评论(0编辑  收藏  举报

导航