session-ios/Signal/src/util/collections/PriorityQueue.m

69 lines
2 KiB
Mathematica
Raw Normal View History

2014-05-06 19:41:08 +02:00
#import "PriorityQueue.h"
@implementation PriorityQueue
+ (PriorityQueue *)priorityQueueAscendingWithComparator:(NSComparator)comparator {
ows_require(comparator != nil);
PriorityQueue *q = [PriorityQueue new];
q->_comparator = comparator;
q->items = [NSMutableArray array];
2014-05-06 19:41:08 +02:00
return q;
}
- (void)enqueue:(id)item {
2014-08-14 03:13:24 +02:00
NSUInteger curIndex = items.count;
2014-05-06 19:41:08 +02:00
[items addObject:item];
while (curIndex > 0) {
NSUInteger parentIndex = (curIndex - 1) >> 1;
id parentItem = items[parentIndex];
if (_comparator(item, parentItem) >= 0)
break;
2014-05-06 19:41:08 +02:00
[items setObject:parentItem atIndexedSubscript:curIndex];
[items setObject:item atIndexedSubscript:parentIndex];
curIndex = parentIndex;
}
}
- (id)peek {
2014-08-14 03:13:24 +02:00
requireState(items.count > 0);
return items[0];
2014-05-06 19:41:08 +02:00
}
- (id)dequeue {
2014-08-14 03:13:24 +02:00
requireState(items.count > 0);
id result = items[0];
2014-05-06 19:41:08 +02:00
// iteratively pull up smaller child until we hit the bottom of the heap
2014-08-14 03:13:24 +02:00
NSUInteger endangeredIndex = items.count - 1;
id endangeredItem = items[endangeredIndex];
NSUInteger i = 0;
2014-05-06 19:41:08 +02:00
while (true) {
NSUInteger childIndex1 = i * 2 + 1;
NSUInteger childIndex2 = i * 2 + 2;
if (childIndex1 >= endangeredIndex)
break;
NSUInteger smallerChildIndex =
_comparator(items[childIndex1], items[childIndex2]) <= 0 ? childIndex1 : childIndex2;
id smallerChild = items[smallerChildIndex];
2014-05-06 19:41:08 +02:00
bool useEndangered = _comparator(endangeredItem, smallerChild) <= 0;
if (useEndangered)
break;
2014-05-06 19:41:08 +02:00
[items setObject:smallerChild atIndexedSubscript:i];
i = smallerChildIndex;
}
2014-05-06 19:41:08 +02:00
// swap the item at the index to be removed into the new empty space at the bottom of heap
[items setObject:endangeredItem atIndexedSubscript:i];
[items removeObjectAtIndex:endangeredIndex];
2014-05-06 19:41:08 +02:00
return result;
}
- (NSUInteger)count {
2014-08-14 03:13:24 +02:00
return items.count;
2014-05-06 19:41:08 +02:00
}
@end