-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBinarySearchST.java
More file actions
157 lines (134 loc) · 3.97 KB
/
Copy pathBinarySearchST.java
File metadata and controls
157 lines (134 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
* Sample usage: java BinarySearchST < tinyST.txt
*/
public class BinarySearchST<Key extends Comparable<Key>, Value>{
private Key[] keys;
private Value[] vals;
private int N;
// Initializes an empty symbol table with the initial capacity 2.
public BinarySearchST(){
keys = (Key[]) new Comparable[2];
vals = (Value[]) new Object[2];
}
// resize the underlying arrays
private void resize(int capacity){
assert capacity >= N;
Key[] tempk = (Key[]) new Comparable[capacity];
Value[] tempv = (Value[]) new Object[capacity];
for (int i=0; i<N; i++){
tempk[i] = keys[i];
tempv[i] = vals[i];
}
vals = tempv;
keys = tempk;
}
public int size(){
return N;
}
public boolean isEmpty(){
return size()==0;
}
public boolean contains(Key key){
return get(key) != null;
}
// Returns the number of keys in this symbol table strictly less than key
public int rank(Key key){
int lo=0, hi = N-1;
while (lo <= hi){
int mid = lo+(hi-lo)/2;
int cmp = key.compareTo(keys[mid]);
if (cmp < 0) hi = mid-1;
else if (cmp > 0) lo = mid+1;
else return mid;
}
return lo;
}
public Value get(Key key){
if (isEmpty()) return null;
int i = rank(key);
if (i < N && keys[i].compareTo(key)==0) return vals[i];
else return null;
}
public void put(Key key, Value val){
// Search for key. Update value if found; grow table if new.
int i = rank(key);
if (i<N && keys[i].compareTo(key)==0){
vals[i] = val;
return;
}
// insert new key-value pair
if (N==keys.length) resize(2*keys.length);
for (int j=N; j>i; j--){
keys[j] = keys[j-1];
vals[j] = vals[j-1];
}
keys[i] = key;
vals[i] = val;
N++;
}
public void delete(Key key){
int i = rank(key);
for (int j = i; j < N-1; j++){
keys[j] = keys[j+1];
vals[j] = vals[j+1];
}
N--;
keys[N] = null; // to avoid loitering
vals[N] = null;
//resize if 1/4 full
if (N>0 && N==keys.length/4) resize(keys.length/2);
}
public Key min(){
return keys[0];
}
public Key max(){
return keys[N-1];
}
public Key select(int k){
return keys[k];
}
// Returns the smallest key in this symbol table greater than or equal to key.
public Key ceiling(Key key){
int i = rank(key);
if (i==N) return null;
else return keys[i];
}
// Returns the greatest key in this symbol table less than or equal to key.
public Key floor(Key key){
int i = rank(key);
if (i<N && key.compareTo(keys[i])==0) return keys[i];
if (i==0) return null;
else return keys[i-1];
}
public void deleteMin(){
delete(min());
}
public void deleteMax(){
delete(max());
}
public int size(Key lo, Key hi){
if (hi.compareTo(lo)<0) return 0;
else if (contains(hi)) return rank(hi)-rank(lo)+1;
else return rank(hi)-rank(lo);
}
public Iterable<Key> keys(Key lo, Key hi){
LinkedQueue<Key> queue = new LinkedQueue<>();
if (lo.compareTo(hi)>0) return queue;
for (int i = rank(lo); i < rank(hi); i++)
queue.enqueue(keys[i]);
if (contains(hi)) queue.enqueue(keys[rank(hi)]);
return queue;
}
public Iterable<Key> keys(){
return keys(min(), max());
}
public static void main(String[] args){
BinarySearchST<String, Integer> st = new BinarySearchST<>();
for (int i=0; !StdIn.isEmpty(); i++){
String key = StdIn.readString();
st.put(key, i);
}
for (String s: st.keys())
StdOut.println(s + " " + st.get(s));
}
}