depq 0.1 → 0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +6 -9
- data/depq.rb +363 -60
- data/test-depq.rb +46 -0
- metadata +4 -4
data/README
CHANGED
@@ -139,15 +139,12 @@ A* search algorithm, etc.
|
|
139
139
|
# [["A", "B", "C"], 3],
|
140
140
|
# [["A", "B", "C", "D"], 4]]
|
141
141
|
|
142
|
-
= Internal Heap Algorithm
|
143
|
-
|
144
|
-
Depq uses min-heap or
|
145
|
-
When delete_min is used, min-heap is constructed
|
146
|
-
When delete_max is used, max-heap is constructed
|
147
|
-
|
148
|
-
In future, min-max-heap may be implemented to avoid this problem.
|
149
|
-
min-max-heap will be used when delete_min and delete_max is used both.
|
150
|
-
(Because min-max-heap is slower than min-heap/max-heap.)
|
142
|
+
= Internal Heap Algorithm
|
143
|
+
|
144
|
+
Depq uses min-heap, max-heap or interval-heap internally.
|
145
|
+
When delete_min is used, min-heap is constructed.
|
146
|
+
When delete_max is used, max-heap is constructed.
|
147
|
+
When delete_min and delete_max is used, interval-heap is constructed.
|
151
148
|
|
152
149
|
= Author
|
153
150
|
|
data/depq.rb
CHANGED
@@ -165,15 +165,12 @@
|
|
165
165
|
# # [["A", "B", "C"], 3],
|
166
166
|
# # [["A", "B", "C", "D"], 4]]
|
167
167
|
#
|
168
|
-
# = Internal Heap Algorithm
|
168
|
+
# = Internal Heap Algorithm
|
169
169
|
#
|
170
|
-
# Depq uses min-heap or
|
171
|
-
# When delete_min is used, min-heap is constructed
|
172
|
-
# When delete_max is used, max-heap is constructed
|
173
|
-
#
|
174
|
-
# In future, min-max-heap may be implemented to avoid this problem.
|
175
|
-
# min-max-heap will be used when delete_min and delete_max is used both.
|
176
|
-
# (Because min-max-heap is slower than min-heap/max-heap.)
|
170
|
+
# Depq uses min-heap, max-heap or interval-heap internally.
|
171
|
+
# When delete_min is used, min-heap is constructed.
|
172
|
+
# When delete_max is used, max-heap is constructed.
|
173
|
+
# When delete_min and delete_max is used, interval-heap is constructed.
|
177
174
|
#
|
178
175
|
class Depq
|
179
176
|
include Enumerable
|
@@ -217,8 +214,6 @@ class Depq
|
|
217
214
|
define_method(:eql?, Object.instance_method(:eql?))
|
218
215
|
define_method(:hash, Object.instance_method(:hash))
|
219
216
|
|
220
|
-
include Comparable
|
221
|
-
|
222
217
|
# Create a Depq::Locator object.
|
223
218
|
def initialize(value, priority=value, subpriority=nil)
|
224
219
|
super value, subpriority, priority
|
@@ -447,25 +442,41 @@ class Depq
|
|
447
442
|
end
|
448
443
|
private :each_entry
|
449
444
|
|
450
|
-
def
|
451
|
-
if @mode
|
445
|
+
def use_min
|
446
|
+
if @mode == MinHeap || @mode == IntervalHeap
|
447
|
+
if @heapsize < self.size
|
448
|
+
@heapsize = @mode.heapify(self, @ary, @heapsize)
|
449
|
+
end
|
450
|
+
else
|
452
451
|
@mode = MinHeap
|
453
452
|
@heapsize = @mode.heapify(self, @ary)
|
454
|
-
elsif @heapsize < self.size
|
455
|
-
@heapsize = @mode.heapify(self, @ary, @heapsize)
|
456
453
|
end
|
457
454
|
end
|
458
|
-
private :
|
455
|
+
private :use_min
|
459
456
|
|
460
|
-
def
|
461
|
-
if @mode
|
457
|
+
def use_max
|
458
|
+
if @mode == MaxHeap || @mode == IntervalHeap
|
459
|
+
if @heapsize < self.size
|
460
|
+
@heapsize = @mode.heapify(self, @ary, @heapsize)
|
461
|
+
end
|
462
|
+
else
|
462
463
|
@mode = MaxHeap
|
463
464
|
@heapsize = @mode.heapify(self, @ary)
|
464
|
-
elsif @heapsize < self.size
|
465
|
-
@heapsize = @mode.heapify(self, @ary, @heapsize)
|
466
465
|
end
|
467
466
|
end
|
468
|
-
private :
|
467
|
+
private :use_max
|
468
|
+
|
469
|
+
def use_minmax
|
470
|
+
if @mode == IntervalHeap
|
471
|
+
if @heapsize < self.size
|
472
|
+
@heapsize = @mode.heapify(self, @ary, @heapsize)
|
473
|
+
end
|
474
|
+
else
|
475
|
+
@mode = IntervalHeap
|
476
|
+
@heapsize = @mode.heapify(self, @ary)
|
477
|
+
end
|
478
|
+
end
|
479
|
+
private :use_minmax
|
469
480
|
|
470
481
|
def mode_heapify
|
471
482
|
if @mode
|
@@ -756,8 +767,8 @@ class Depq
|
|
756
767
|
#
|
757
768
|
def find_min_locator
|
758
769
|
return nil if empty?
|
759
|
-
|
760
|
-
@mode.find_min_locator(@ary)
|
770
|
+
use_min
|
771
|
+
@mode.find_min_locator(self, @ary)
|
761
772
|
end
|
762
773
|
|
763
774
|
# return the minimum value with its priority.
|
@@ -810,8 +821,8 @@ class Depq
|
|
810
821
|
#
|
811
822
|
def find_max_locator
|
812
823
|
return nil if empty?
|
813
|
-
|
814
|
-
@mode.find_max_locator(@ary)
|
824
|
+
use_max
|
825
|
+
@mode.find_max_locator(self, @ary)
|
815
826
|
end
|
816
827
|
|
817
828
|
# return the maximum value with its priority.
|
@@ -862,35 +873,8 @@ class Depq
|
|
862
873
|
#
|
863
874
|
def find_minmax_locator
|
864
875
|
return [nil, nil] if empty?
|
865
|
-
|
866
|
-
|
867
|
-
loc1 = find_min_locator
|
868
|
-
loc2 = loc1
|
869
|
-
self.each_locator {|loc|
|
870
|
-
if compare_for_max(loc2.priority, loc2.subpriority, loc.priority, loc.subpriority) < 0
|
871
|
-
loc2 = loc
|
872
|
-
end
|
873
|
-
}
|
874
|
-
when :max
|
875
|
-
loc2 = find_max_locator
|
876
|
-
loc1 = loc2
|
877
|
-
self.each_locator {|loc|
|
878
|
-
if compare_for_min(loc1.priority, loc1.subpriority, loc.priority, loc.subpriority) > 0
|
879
|
-
loc1 = loc
|
880
|
-
end
|
881
|
-
}
|
882
|
-
else
|
883
|
-
loc1 = loc2 = nil
|
884
|
-
self.each_locator {|loc|
|
885
|
-
if loc1 == nil || compare_for_min(loc1.priority, loc1.subpriority, loc.priority, loc.subpriority) > 0
|
886
|
-
loc1 = loc
|
887
|
-
end
|
888
|
-
if loc2 == nil || compare_for_max(loc2.priority, loc2.subpriority, loc.priority, loc.subpriority) < 0
|
889
|
-
loc2 = loc
|
890
|
-
end
|
891
|
-
}
|
892
|
-
end
|
893
|
-
[loc1, loc2]
|
876
|
+
use_minmax
|
877
|
+
return @mode.find_minmax_locator(self, @ary)
|
894
878
|
end
|
895
879
|
|
896
880
|
# returns the minimum and maximum value as a two-element array.
|
@@ -953,8 +937,8 @@ class Depq
|
|
953
937
|
#
|
954
938
|
def delete_min_locator
|
955
939
|
return nil if empty?
|
956
|
-
|
957
|
-
loc = @mode.find_min_locator(@ary)
|
940
|
+
use_min
|
941
|
+
loc = @mode.find_min_locator(self, @ary)
|
958
942
|
@heapsize = @mode.delete_locator(self, @ary, loc)
|
959
943
|
loc
|
960
944
|
end
|
@@ -1018,8 +1002,8 @@ class Depq
|
|
1018
1002
|
#
|
1019
1003
|
def delete_max_locator
|
1020
1004
|
return nil if empty?
|
1021
|
-
|
1022
|
-
loc = @mode.find_max_locator(@ary)
|
1005
|
+
use_max
|
1006
|
+
loc = @mode.find_max_locator(self, @ary)
|
1023
1007
|
@heapsize = @mode.delete_locator(self, @ary, loc)
|
1024
1008
|
loc
|
1025
1009
|
end
|
@@ -1320,8 +1304,7 @@ class Depq
|
|
1320
1304
|
|
1321
1305
|
# :stopdoc:
|
1322
1306
|
|
1323
|
-
module
|
1324
|
-
|
1307
|
+
module HeapArray
|
1325
1308
|
def size(ary)
|
1326
1309
|
return ary.size / ARY_SLICE_SIZE
|
1327
1310
|
end
|
@@ -1364,6 +1347,10 @@ class Depq
|
|
1364
1347
|
ei.send(:index=, j)
|
1365
1348
|
ej.send(:index=, i)
|
1366
1349
|
end
|
1350
|
+
end
|
1351
|
+
|
1352
|
+
module SimpleHeap
|
1353
|
+
include HeapArray
|
1367
1354
|
|
1368
1355
|
def upheap(pd, ary, j)
|
1369
1356
|
while true
|
@@ -1393,7 +1380,7 @@ class Depq
|
|
1393
1380
|
end
|
1394
1381
|
end
|
1395
1382
|
|
1396
|
-
def find_top_locator(ary)
|
1383
|
+
def find_top_locator(pd, ary)
|
1397
1384
|
loc, _ = get_entry(ary, 0)
|
1398
1385
|
loc
|
1399
1386
|
end
|
@@ -1516,5 +1503,321 @@ class Depq
|
|
1516
1503
|
alias find_max_locator find_top_locator
|
1517
1504
|
end
|
1518
1505
|
|
1506
|
+
module IntervalHeap
|
1507
|
+
end
|
1508
|
+
class << IntervalHeap
|
1509
|
+
include HeapArray
|
1510
|
+
|
1511
|
+
def root?(i) i < 2 end
|
1512
|
+
def minside?(i) i.even? end
|
1513
|
+
def maxside?(i) i.odd? end
|
1514
|
+
def minside(i) i & ~1 end
|
1515
|
+
def maxside(i) i | 1 end
|
1516
|
+
def parent_minside(j) (j-2)/2 & ~1 end
|
1517
|
+
def parent_maxside(j) (j-2)/2 | 1 end
|
1518
|
+
def child1_minside(i) i &= ~1; (i*2+2) & ~1 end
|
1519
|
+
def child1_maxside(i) i &= ~1; (i*2+2) | 1 end
|
1520
|
+
def child2_minside(i) i &= ~1; (i*2+4) & ~1 end
|
1521
|
+
def child2_maxside(i) i &= ~1; (i*2+4) | 1 end
|
1522
|
+
|
1523
|
+
def pcmp(pd, ary, i, j)
|
1524
|
+
ei, pi, si = get_entry(ary, i)
|
1525
|
+
ej, pj, sj = get_entry(ary, j)
|
1526
|
+
pd.compare_priority(pi, pj)
|
1527
|
+
end
|
1528
|
+
|
1529
|
+
def scmp(pd, ary, i, j)
|
1530
|
+
ei, pi, si = get_entry(ary, i)
|
1531
|
+
ej, pj, sj = get_entry(ary, j)
|
1532
|
+
si <=> sj
|
1533
|
+
end
|
1534
|
+
|
1535
|
+
def psame(pd, ary, i)
|
1536
|
+
pcmp(pd, ary, minside(i), maxside(i)) == 0
|
1537
|
+
end
|
1538
|
+
|
1539
|
+
def travel(pd, ary, i, range, fix_subpriority)
|
1540
|
+
while true
|
1541
|
+
j = yield i
|
1542
|
+
return i if !j
|
1543
|
+
swap ary, i, j
|
1544
|
+
if fix_subpriority
|
1545
|
+
imin = minside(i)
|
1546
|
+
imax = maxside(i)
|
1547
|
+
if range.include?(imin) && range.include?(imax)
|
1548
|
+
if pcmp(pd, ary, imin, imax) == 0 && scmp(pd, ary, imin, imax) > 0
|
1549
|
+
swap ary, imin, imax
|
1550
|
+
end
|
1551
|
+
end
|
1552
|
+
end
|
1553
|
+
i = j
|
1554
|
+
end
|
1555
|
+
end
|
1556
|
+
|
1557
|
+
def upheap_minside(pd, ary, i, range)
|
1558
|
+
travel(pd, ary, i, range, true) {|j|
|
1559
|
+
if root?(j)
|
1560
|
+
nil
|
1561
|
+
elsif !range.include?(k = parent_minside(j))
|
1562
|
+
nil
|
1563
|
+
else
|
1564
|
+
if pcmp(pd, ary, k, j) > 0
|
1565
|
+
swap(ary, minside(k), maxside(k)) if psame(pd, ary, k)
|
1566
|
+
k
|
1567
|
+
else
|
1568
|
+
nil
|
1569
|
+
end
|
1570
|
+
end
|
1571
|
+
}
|
1572
|
+
end
|
1573
|
+
|
1574
|
+
def upheap_maxside(pd, ary, i, range)
|
1575
|
+
travel(pd, ary, i, range, true) {|j|
|
1576
|
+
if root?(j)
|
1577
|
+
nil
|
1578
|
+
elsif !range.include?(k = parent_maxside(j))
|
1579
|
+
nil
|
1580
|
+
else
|
1581
|
+
if pcmp(pd, ary, k, j) < 0
|
1582
|
+
k
|
1583
|
+
else
|
1584
|
+
nil
|
1585
|
+
end
|
1586
|
+
end
|
1587
|
+
}
|
1588
|
+
end
|
1589
|
+
|
1590
|
+
def downheap_minside(pd, ary, i, range)
|
1591
|
+
travel(pd, ary, i, range, true) {|j|
|
1592
|
+
k1 = child1_minside(j)
|
1593
|
+
k2 = child2_minside(j)
|
1594
|
+
if !range.include?(k1)
|
1595
|
+
nil
|
1596
|
+
else
|
1597
|
+
if !range.include?(k2)
|
1598
|
+
k = k1
|
1599
|
+
else
|
1600
|
+
if (pc = pcmp(pd, ary, k1, k2)) < 0
|
1601
|
+
k = k1
|
1602
|
+
elsif pc > 0
|
1603
|
+
k = k2
|
1604
|
+
elsif (sc = scmp(pd, ary, k1, k2)) <= 0
|
1605
|
+
k = k1
|
1606
|
+
else
|
1607
|
+
k = k2
|
1608
|
+
end
|
1609
|
+
end
|
1610
|
+
if (pc = pcmp(pd, ary, k, j)) < 0
|
1611
|
+
k
|
1612
|
+
else
|
1613
|
+
nil
|
1614
|
+
end
|
1615
|
+
end
|
1616
|
+
}
|
1617
|
+
end
|
1618
|
+
|
1619
|
+
def downheap_maxside(pd, ary, i, range)
|
1620
|
+
travel(pd, ary, i, range, true) {|j|
|
1621
|
+
k1 = child1_maxside(j)
|
1622
|
+
k2 = child2_maxside(j)
|
1623
|
+
k1 = minside(k1) if range.include?(k1) && psame(pd, ary, k1)
|
1624
|
+
k2 = minside(k2) if range.include?(k2) && psame(pd, ary, k2)
|
1625
|
+
if !range.include?(k1)
|
1626
|
+
nil
|
1627
|
+
else
|
1628
|
+
if !range.include?(k2)
|
1629
|
+
k = k1
|
1630
|
+
else
|
1631
|
+
if (pc = pcmp(pd, ary, k1, k2)) < 0
|
1632
|
+
k = k2
|
1633
|
+
elsif pc > 0
|
1634
|
+
k = k1
|
1635
|
+
elsif (sc = scmp(pd, ary, k1, k2)) <= 0
|
1636
|
+
k = k1
|
1637
|
+
else
|
1638
|
+
k = k2
|
1639
|
+
end
|
1640
|
+
end
|
1641
|
+
if (pc = pcmp(pd, ary, k, j)) > 0
|
1642
|
+
swap(ary, minside(k), maxside(k)) if minside?(k)
|
1643
|
+
maxside(k)
|
1644
|
+
else
|
1645
|
+
nil
|
1646
|
+
end
|
1647
|
+
end
|
1648
|
+
}
|
1649
|
+
end
|
1650
|
+
|
1651
|
+
def upheap_sub(pd, ary, i, range)
|
1652
|
+
travel(pd, ary, i, range, false) {|j|
|
1653
|
+
k = nil
|
1654
|
+
if minside?(j)
|
1655
|
+
if range.include?(kk=parent_maxside(j)) && pcmp(pd, ary, j, kk) == 0
|
1656
|
+
k = kk
|
1657
|
+
elsif range.include?(kk=parent_minside(j)) && pcmp(pd, ary, j, kk) == 0
|
1658
|
+
k = kk
|
1659
|
+
end
|
1660
|
+
else
|
1661
|
+
if range.include?(kk=minside(j)) && pcmp(pd, ary, j, kk) == 0
|
1662
|
+
k = kk
|
1663
|
+
elsif range.include?(kk=parent_maxside(j)) && pcmp(pd, ary, j, kk) == 0
|
1664
|
+
k = kk
|
1665
|
+
end
|
1666
|
+
end
|
1667
|
+
if !k
|
1668
|
+
nil
|
1669
|
+
elsif !range.include?(k)
|
1670
|
+
nil
|
1671
|
+
elsif scmp(pd, ary, k, j) > 0
|
1672
|
+
k
|
1673
|
+
else
|
1674
|
+
nil
|
1675
|
+
end
|
1676
|
+
}
|
1677
|
+
end
|
1678
|
+
|
1679
|
+
def downheap_sub(pd, ary, i, range)
|
1680
|
+
travel(pd, ary, i, range, false) {|j|
|
1681
|
+
k1 = k2 = nil
|
1682
|
+
if minside?(j)
|
1683
|
+
if range.include?(kk=maxside(j)) && pcmp(pd, ary, j, kk) == 0
|
1684
|
+
k1 = kk
|
1685
|
+
else
|
1686
|
+
k1 = kk if range.include?(kk=child1_minside(j)) && pcmp(pd, ary, j, kk) == 0
|
1687
|
+
k2 = kk if range.include?(kk=child2_minside(j)) && pcmp(pd, ary, j, kk) == 0
|
1688
|
+
end
|
1689
|
+
else
|
1690
|
+
if range.include?(kk=child1_minside(j)) && pcmp(pd, ary, j, kk) == 0
|
1691
|
+
k1 = kk
|
1692
|
+
elsif range.include?(kk=child1_maxside(j)) && pcmp(pd, ary, j, kk) == 0
|
1693
|
+
k1 = kk
|
1694
|
+
end
|
1695
|
+
if range.include?(kk=child2_minside(j)) && pcmp(pd, ary, j, kk) == 0
|
1696
|
+
k2 = kk
|
1697
|
+
elsif range.include?(kk=child2_maxside(j)) && pcmp(pd, ary, j, kk) == 0
|
1698
|
+
k2 = kk
|
1699
|
+
end
|
1700
|
+
end
|
1701
|
+
if k1 && k2
|
1702
|
+
k = scmp(pd, ary, k1, k2) > 0 ? k2 : k1
|
1703
|
+
else
|
1704
|
+
k = k1 || k2
|
1705
|
+
end
|
1706
|
+
if k && scmp(pd, ary, k, j) < 0
|
1707
|
+
k
|
1708
|
+
else
|
1709
|
+
nil
|
1710
|
+
end
|
1711
|
+
}
|
1712
|
+
end
|
1713
|
+
|
1714
|
+
def adjust(pd, ary, i, range)
|
1715
|
+
if minside?(i)
|
1716
|
+
j = upheap_minside(pd, ary, i, range)
|
1717
|
+
if i == j
|
1718
|
+
i = downheap_minside(pd, ary, i, range)
|
1719
|
+
if !range.include?(child1_minside(i)) && range.include?(j=maxside(i)) && pcmp(pd, ary, i, j) > 0
|
1720
|
+
swap(ary, i, j)
|
1721
|
+
i = j
|
1722
|
+
end
|
1723
|
+
if maxside?(i) || !range.include?(maxside(i))
|
1724
|
+
i = upheap_maxside(pd, ary, i, range)
|
1725
|
+
end
|
1726
|
+
end
|
1727
|
+
else
|
1728
|
+
j = upheap_maxside(pd, ary, i, range)
|
1729
|
+
if i == j
|
1730
|
+
i = downheap_maxside(pd, ary, i, range)
|
1731
|
+
if !range.include?(child1_maxside(i))
|
1732
|
+
if range.include?(j=child1_minside(i)) && pcmp(pd, ary, j, i) > 0
|
1733
|
+
swap(ary, i, j)
|
1734
|
+
i = j
|
1735
|
+
elsif range.include?(j=minside(i)) && pcmp(pd, ary, j, i) > 0
|
1736
|
+
swap(ary, i, j)
|
1737
|
+
i = j
|
1738
|
+
end
|
1739
|
+
end
|
1740
|
+
if minside?(i)
|
1741
|
+
i = upheap_minside(pd, ary, i, range)
|
1742
|
+
end
|
1743
|
+
end
|
1744
|
+
end
|
1745
|
+
i = upheap_sub(pd, ary, i, range)
|
1746
|
+
downheap_sub(pd, ary, i, range)
|
1747
|
+
end
|
1748
|
+
|
1749
|
+
def update_priority(pd, ary, loc, prio, subprio)
|
1750
|
+
i = loc.send(:index)
|
1751
|
+
ei, pi, si = get_entry(ary, i)
|
1752
|
+
subpriority ||= si
|
1753
|
+
set_entry(ary, i, ei, prio, subprio)
|
1754
|
+
range = 0...size(ary)
|
1755
|
+
adjust(pd, ary, i, range)
|
1756
|
+
end
|
1757
|
+
|
1758
|
+
def insert_internal(pd, ary, loc, prio, subprio)
|
1759
|
+
i = size(ary)
|
1760
|
+
set_entry(ary, i, loc, prio, subprio)
|
1761
|
+
range = 0...size(ary)
|
1762
|
+
adjust(pd, ary, i, range)
|
1763
|
+
end
|
1764
|
+
|
1765
|
+
def heapify(pd, ary, heapsize=0)
|
1766
|
+
currentsize = size(ary)
|
1767
|
+
h = Math.log(currentsize+1)/Math.log(2)
|
1768
|
+
if currentsize - 1 < (h - 1) * (currentsize - heapsize + 1)
|
1769
|
+
(currentsize-1).downto(0) {|i|
|
1770
|
+
adjust(pd, ary, i, i...currentsize)
|
1771
|
+
}
|
1772
|
+
else
|
1773
|
+
heapsize.upto(currentsize-1) {|i|
|
1774
|
+
adjust(pd, ary, i, 0...(i+1))
|
1775
|
+
}
|
1776
|
+
end
|
1777
|
+
currentsize
|
1778
|
+
end
|
1779
|
+
|
1780
|
+
def find_minmax_locator(pd, ary)
|
1781
|
+
case size(ary)
|
1782
|
+
when 0
|
1783
|
+
[nil, nil]
|
1784
|
+
when 1
|
1785
|
+
e0, p0, s0 = get_entry(ary, 0)
|
1786
|
+
[e0, e0]
|
1787
|
+
else
|
1788
|
+
if pcmp(pd, ary, 0, 1) == 0
|
1789
|
+
e0, p0, s0 = get_entry(ary, 0)
|
1790
|
+
[e0, e0]
|
1791
|
+
else
|
1792
|
+
e0, p0, s0 = get_entry(ary, 0)
|
1793
|
+
e1, p1, s1 = get_entry(ary, 1)
|
1794
|
+
[e0, e1]
|
1795
|
+
end
|
1796
|
+
end
|
1797
|
+
end
|
1798
|
+
|
1799
|
+
def find_min_locator(pd, ary)
|
1800
|
+
find_minmax_locator(pd, ary).first
|
1801
|
+
end
|
1802
|
+
|
1803
|
+
def find_max_locator(pd, ary)
|
1804
|
+
find_minmax_locator(pd, ary).last
|
1805
|
+
end
|
1806
|
+
|
1807
|
+
def delete_locator(pd, ary, loc)
|
1808
|
+
i = loc.send(:index)
|
1809
|
+
_, priority, subpriority = get_entry(ary, i)
|
1810
|
+
last = size(ary) - 1
|
1811
|
+
loc.send(:internal_deleted, priority, subpriority)
|
1812
|
+
el, pl, sl = delete_entry(ary, last)
|
1813
|
+
if i != last
|
1814
|
+
set_entry(ary, i, el, pl, sl)
|
1815
|
+
el.send(:index=, i)
|
1816
|
+
adjust(pd, ary, i, 0...last)
|
1817
|
+
end
|
1818
|
+
size(ary)
|
1819
|
+
end
|
1820
|
+
end
|
1821
|
+
|
1519
1822
|
# :startdoc:
|
1520
1823
|
end
|
data/test-depq.rb
CHANGED
@@ -46,6 +46,30 @@ class Depq
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
+
def IntervalHeap.validation(pd, ary)
|
50
|
+
range=0...size(ary)
|
51
|
+
range.each {|j|
|
52
|
+
imin = parent_minside(j)
|
53
|
+
imax = parent_maxside(j)
|
54
|
+
jmin = minside(j)
|
55
|
+
if minside?(j) && range.include?(imin) && pcmp(pd, ary, imin, j) > 0
|
56
|
+
raise "ary[#{imin}].priority > ary[#{j}].priority "
|
57
|
+
end
|
58
|
+
if maxside?(j) && range.include?(imax) && pcmp(pd, ary, imax, j) < 0
|
59
|
+
raise "ary[#{imax}].priority < ary[#{j}].priority "
|
60
|
+
end
|
61
|
+
if range.include?(imin) && pcmp(pd, ary, imin, j) == 0 && scmp(pd, ary, imin, j) > 0
|
62
|
+
raise "ary[#{imin}].subpriority < ary[#{j}].subpriority "
|
63
|
+
end
|
64
|
+
if range.include?(imax) && pcmp(pd, ary, imax, j) == 0 && scmp(pd, ary, imax, j) > 0
|
65
|
+
raise "ary[#{imax}].subpriority < ary[#{j}].subpriority "
|
66
|
+
end
|
67
|
+
if maxside?(j) && range.include?(jmin) && pcmp(pd, ary, jmin, j) == 0 && scmp(pd, ary, jmin, j) > 0
|
68
|
+
raise "ary[#{jmin}].subpriority < ary[#{j}].subpriority "
|
69
|
+
end
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
49
73
|
def validation
|
50
74
|
@mode.validation(self, @ary) if @mode
|
51
75
|
if @ary.length % ARY_SLICE_SIZE != 0
|
@@ -580,6 +604,28 @@ class TestDepq < Test::Unit::TestCase
|
|
580
604
|
assert_equal([1, 3], res)
|
581
605
|
end
|
582
606
|
|
607
|
+
def test_find_minmax_after_min
|
608
|
+
pd = Depq.new
|
609
|
+
assert_equal([nil, nil], pd.find_minmax)
|
610
|
+
pd.insert 3
|
611
|
+
pd.insert 1
|
612
|
+
pd.insert 2
|
613
|
+
assert_equal(1, pd.min)
|
614
|
+
res = pd.find_minmax
|
615
|
+
assert_equal([1, 3], res)
|
616
|
+
end
|
617
|
+
|
618
|
+
def test_find_minmax_after_max
|
619
|
+
pd = Depq.new
|
620
|
+
assert_equal([nil, nil], pd.find_minmax)
|
621
|
+
pd.insert 3
|
622
|
+
pd.insert 1
|
623
|
+
pd.insert 2
|
624
|
+
assert_equal(3, pd.max)
|
625
|
+
res = pd.find_minmax
|
626
|
+
assert_equal([1, 3], res)
|
627
|
+
end
|
628
|
+
|
583
629
|
def test_delete_locator
|
584
630
|
pd = Depq.new
|
585
631
|
loc = pd.insert 1
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: depq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "0.
|
4
|
+
version: "0.2"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tanaka Akira
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-09-
|
12
|
+
date: 2009-09-23 00:00:00 +09:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -30,7 +30,7 @@ files:
|
|
30
30
|
- README
|
31
31
|
- depq.rb
|
32
32
|
has_rdoc: true
|
33
|
-
homepage: http://
|
33
|
+
homepage: http://depq.rubyforge.org/
|
34
34
|
licenses: []
|
35
35
|
|
36
36
|
post_install_message:
|
@@ -52,7 +52,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
52
52
|
version:
|
53
53
|
requirements: []
|
54
54
|
|
55
|
-
rubyforge_project:
|
55
|
+
rubyforge_project: depq
|
56
56
|
rubygems_version: 1.3.4
|
57
57
|
signing_key:
|
58
58
|
specification_version: 3
|