View difference between Paste ID: f6fc7d4b8 and
SHOW: | | - or go back to the newest paste.
1-
1+
/*
2
 * To change this template, choose Tools | Templates
3
 * and open the template in the editor.
4
 */
5
6
/**
7
 *
8
 * @author nick
9
 */
10
public class PriorityQueue<T> {
11
    private FibNode<T> _min;
12
    private final FibList<T> _rootList;
13
    private final java.util.Comparator<T> _comparer;
14
    private int _count;
15
    
16
    public PriorityQueue(java.util.Comparator<T> comparer) {
17
        _rootList = new FibList();
18
        _comparer = comparer;
19
        _count = 0;
20
    }
21
    
22
    public void insert(T item) {
23
        FibNode<T> node = new FibNode(item);
24
        insertToRootList(node);
25
        _count++;
26
    }
27
    public T peek() {
28
        T data = null;
29
        if (_min != null) {
30
            data = _min.getData();
31
        }
32
        return data;
33
    }
34
    
35
    public boolean isEmpty() {
36
        return _count == 0;
37
    }
38
    
39
    public PriorityQueue<T> union(PriorityQueue<T> queue) {
40
        PriorityQueue<T> q = new PriorityQueue(_comparer);
41
        q._min = _min;
42
        queue._rootList.addList(q._rootList);
43
        if (this._min == null || 
44
            (queue._min != null && 
45
            _comparer.compare(queue._min.getData(), this._min.getData()) < 0)) 
46
        {
47
            q._min = queue._min;
48
        }
49
        q._count = this._count + queue._count;
50
        
51
        return q;
52
    }
53
    
54
    public T removeMin() {
55
        FibNode<T> z = _min;
56
        T data = null;
57
        
58
        if (z != null) {
59
            
60
            /* promote all of z's children to the root list */
61
            FibList<T> list = z.getChildren();
62
            int count = _rootList.getCount();
63
            FibNode<T> child = list.getHead();
64
            
65
            if (child != null) {
66
                while (!child.isSentinal) {
67
                    FibNode<T> tmp = child.getRight();
68
                    _rootList.add(child);
69
                    child.setParent(null);
70
                    child = tmp;
71
                }
72
            }
73
            _rootList.remove(z);
74
            
75
            FibNode<T> right = z.getRight();
76
            
77
            /* if count is 1, then z was the only element, so set
78
             * min to null, otherwise set z's next to _min and consolidate
79
             */
80
            if (count == 1) {
81
                _min = null;
82
            } else {
83
                _min = right;
84
                consolidate();
85
            }
86
            _count--;
87
            data = z.getData();
88
        }
89
        
90
        return data;
91
    }
92
    
93
    private void consolidate() {
94
        int count = D(_count);
95
        FibNode<T>[] A = new FibNode[count];
96
        FibNode<T> node =  _rootList.getHead();
97
        
98
        do {
99
            FibNode<T> x = node;
100
            int d = x.getDegree();
101
            node = node.getRight();
102
            
103
            /* group nodes by same degree */
104
            while (A[d] != null) {
105
                FibNode<T> y = A[d];
106
                if (_comparer.compare(x.getData(), y.getData()) > 0) {
107
                    FibNode<T> tmp = x;
108
                    x = y;
109
                    y = tmp;
110
                }
111
                heapLink(y, x);
112
                A[d] = null;
113
                d++;
114
            }
115
            A[d] = x;
116
        } while (!node.isSentinal);
117
        
118
        /* reset the root list */
119
        _min = null;
120
        for (int i=0; i < count; i++) {
121
            if (A[i] != null) {
122
                insertToRootList(A[i]);
123
            }
124
        }
125
    }
126
    
127
    private int D(int n) {
128
        if (n == 0)
129
            throw new IllegalArgumentException();
130
        
131
        return 1 + (int)(1.44 * (Math.log(n)/Math.log(2.0)));
132
    }
133
    
134
    private void heapLink(FibNode<T> y, FibNode<T> x) {
135
        _rootList.remove(y);
136
        x.addChild(y);
137
        y.mark = false;
138
    }
139
    
140
    private void insertToRootList(FibNode<T> node) {
141
        _rootList.add(node);
142
        node.setParent(null);
143
        if (_min == null ||
144
            _comparer.compare(node.getData(), _min.getData()) < 0) 
145
        {
146
            _min = node;
147
        }
148
    }
149
    
150
    private void decreaseKey(FibNode<T> x, T data)
151
        throws java.lang.IllegalArgumentException 
152
    {
153
        if (_comparer.compare(x.getData(), data) > 0)
154
            throw new java.lang.IllegalArgumentException("key cannot be less than x's key");
155
        
156
        x.setData(data);
157
        FibNode<T> node = x.getParent();
158
        
159
        if (node != null && _comparer.compare(x.getData(), node.getData()) < 0 ) {
160
            cut(x, node);
161
            cascadingCut(node);
162
        }
163
        if (_comparer.compare(x.getData(), _min.getData()) < 0) {
164
            _min = x;
165
        }
166
    }
167
    
168
    private void cut(FibNode<T> x, FibNode<T> y) {
169
        y.getChildren().remove(x);
170
        _rootList.add(x);
171
        x.setParent(null);
172
        x.mark = false;
173
    }
174
    
175
    private void cascadingCut(FibNode<T> y) {
176
        FibNode<T> z = y.getParent();
177
        if (z != null) {
178
            if (!y.mark) {
179
                y.mark = true;
180
            } else {
181
                cut(y, z);
182
                cascadingCut(z);
183
            }
184
        }
185
    }
186
    
187
    private class FibNode<T> {
188
        private FibNode<T> _parent;
189
        private FibNode<T> _left;
190
        private FibNode<T> _right;
191
        private FibList<T> _children;
192
        public boolean     mark;
193
        public boolean     isSentinal;
194
        private T           _data;
195
        
196
        public FibNode() {
197
            _parent = null;
198
            _data = null;
199
            _children = new FibList();
200
            _left = _right = this;
201
            isSentinal = mark = false;
202
        }
203
        public FibNode(FibList<T> children) {
204
            _parent = null;
205
            _data = null;
206
            _children = children;
207
            _left = _right = this;
208
            mark = false;
209
            isSentinal = true;
210
        }
211
        public FibNode(T data) {
212
            this();
213
            _data = data;
214
        }
215
        
216
        public boolean hasSiblings() {
217
            return _left == this && _right == this;
218
        }
219
        public int getDegree() {
220
            return _children.getCount();
221
        }
222
        
223
        public FibNode<T> getRight() {
224
            return _right;
225
        }
226
        
227
        public FibNode<T> getLeft() {
228
            return _left;
229
        }
230
        
231
        public FibNode<T> getParent() {
232
            return _parent;
233
        }
234
        
235
        public FibList<T> getChildren() {
236
            return _children;
237
        }
238
        
239
        public T getData() {
240
            return _data;
241
        }
242
        
243
        public void addChild(FibNode<T> node) {
244
            _children.add(node);
245
            node.setParent(this);
246
        }
247
        public void setRight(FibNode<T> node) {
248
            _right = node;
249
        }
250
        
251
        public void setLeft(FibNode<T> node) {
252
            _left = node;
253
        }
254
        
255
        public void setParent(FibNode<T> node) {
256
            _parent = node;
257
        }
258
        
259
        public void setData(T data) {
260
            _data = data;
261
        }
262
    }
263
    
264
    private class FibList<T> 
265
            implements java.lang.Iterable<FibNode<T>> 
266
    {
267
        private final FibNode<T> _sentinal;
268
        private int _count;
269
        
270
        public FibList() {
271
            _count = 0;
272
            _sentinal = new FibNode(null);
273
        }
274
        
275
        public void add(FibNode<T> node) {
276
            node.setRight(_sentinal.getRight());
277
            _sentinal.getRight().setLeft(node);
278
            _sentinal.setRight(node);
279
            node.setLeft(_sentinal);
280
            _count++;
281
        }
282
        
283
        public void remove(FibNode<T> node) {
284
            node.getLeft().setRight(node.getRight());
285
            node.getRight().setLeft(node.getLeft());
286
            _count--;
287
        }
288
        
289
        public void addList(FibList<T> list) {
290
            FibNode<T> otherSent = list._sentinal;
291
            _sentinal.getLeft().setRight(otherSent.getRight());
292
            otherSent.getLeft().setRight(_sentinal);
293
            
294
            _count += list._count;
295
        }
296
        
297
        public int getCount() {
298
            return _count;
299
        }
300
        
301
        public FibNode<T> getHead() {
302
            return (_count > 0) ? _sentinal.getRight() : null;
303
        }
304
        
305
        public java.util.Iterator<FibNode<T>> iterator() {
306
            return new FibListIterator(_sentinal);
307
        }
308
        
309
        private class FibListIterator<T>
310
                implements java.util.Iterator<FibNode<T>> 
311
        {
312
            private FibNode<T> _head;
313
            
314
            public FibListIterator(FibNode head) {
315
                if (head == null)
316
                    throw new java.lang.IllegalArgumentException("FibListIterator.ctor");
317
                
318
                _head = head;
319
            }
320
            
321
            public boolean hasNext() {
322
                return (!_head.getRight().isSentinal);
323
            }
324
            
325
            public FibNode<T> next() {
326
                FibNode<T> node = _head.getRight();
327
                
328
                if (node.isSentinal)
329
                    throw new java.util.NoSuchElementException("FibListIterator.next");
330
                
331
                _head = node;
332
                
333
                return node;
334
            }
335
            
336
            public void remove() {
337
                throw new java.lang.UnsupportedOperationException("FibListIterator.remove");
338
            }
339
            
340
        }
341
    }
342
343
}