Priority queue: Difference between revisions
Content added Content deleted
(Frink) |
|||
Line 4,415: | Line 4,415: | ||
Module Reduce { |
Module Reduce { |
||
if .many<.first*2 then exit |
if .many<.first*2 then exit |
||
if .level<.many/2 then .many/=2 : Dim .Item(.many) |
|||
} |
} |
||
Public: |
Public: |
||
Module Clear { |
Module Clear { |
||
Dim .Item() \\ erase all |
Dim .Item() \\ erase all |
||
.many<=0 \\ default |
.many<=0 \\ default |
||
.Level<=0 |
.Level<=0 |
||
} |
|||
Module PriorityQueue { |
|||
If .many>0 then Error "Clear List First" |
|||
Read .many, .cmp |
|||
.first<=.many |
|||
Dim .Item(.many) |
|||
} |
} |
||
Module Add { |
Module Add { |
||
if .level=.many then |
|||
if .many=0 then Error "Define Size First" |
|||
Dim .Item(.many*2) |
Dim .Item(.many*2) |
||
.many*=2 |
.many*=2 |
||
end if |
|||
Read Item |
Read Item |
||
if .level=0 then |
|||
.Item(0)=Item |
.Item(0)=Item |
||
else.If .cmp(.Item(0), Item)=-1 then \\ Item is max |
|||
.Item(.level)=Item |
.Item(.level)=Item |
||
swap .Item(0), .Item(.level) |
swap .Item(0), .Item(.level) |
||
else |
|||
.Item(.level)=Item |
|||
end if |
|||
.level++ |
.level++ |
||
} |
} |
||
Function Peek { |
Function Peek { |
||
if .level=0 then error "empty" |
|||
=.Item(0) |
=.Item(0) |
||
} |
} |
||
Function Poll { |
Function Poll { |
||
if .level=0 then error "empty" |
|||
=.Item(0) |
=.Item(0) |
||
if .level=2 then |
|||
swap .Item(0), .Item(1) |
swap .Item(0), .Item(1) |
||
.Item(1)=0 |
.Item(1)=0 |
||
.Level<=1 |
.Level<=1 |
||
else.If .level>2 then |
|||
.Level-- |
.Level-- |
||
Swap .Item(.level), .Item(0) |
Swap .Item(.level), .Item(0) |
||
.Item(.level)=0 |
.Item(.level)=0 |
||
for I=.level-1 to 1 |
|||
if .cmp(.Item(I), .Item(I-1))=1 then Swap .Item(I), .Item(I-1) |
|||
next |
|||
else |
|||
.level<=0 : .Item(0)=0 |
|||
end if |
|||
.Reduce |
.Reduce |
||
} |
} |
||
Module Remove { |
Module Remove { |
||
if .level=0 then error "empty" |
|||
Read Item |
Read Item |
||
k=true |
k=true |
||
if .cmp(.Item(0), Item)=0 then |
|||
Item=.Poll() |
Item=.Poll() |
||
K~ \\ k=false |
K~ \\ k=false |
||
else.If .Level>1 then |
|||
I2=.Level-1 |
I2=.Level-1 |
||
for I=1 to I2 |
|||
if k then |
|||
if .cmp(.Item(I), Item)=0 then |
|||
if I<I2 then Swap .Item(I), .Item(I2) |
|||
.Item(I2)=0 |
.Item(I2)=0 |
||
k=false |
k=false |
||
end if |
|||
else |
|||
exit |
|||
end if |
|||
next |
|||
.Level-- |
.Level-- |
||
end if |
|||
if k then Error "Not Found" |
|||
.Reduce |
.Reduce |
||
} |
} |
||
Function Size { |
Function Size { |
||
if .many=0 then Error "Define Size First" |
|||
=.Level |
=.Level |
||
} |
|||
Class: |
|||
Module PriorityQueue { |
|||
if .many>0 then Error "Clear List First" |
|||
Read .many, .cmp |
|||
.first<=.many |
|||
Dim .Item(.many) |
|||
} |
} |
||
} |
} |
||
Class Item { X, S$ |
Class Item { X, S$ |
||
Class: // constructor as temporary definition |
|||
Module Item { Read .X, .S$} |
|||
Module Item {Read .X, .S$} |
|||
} |
} |
||
Queue=PriorityQueue(100, Lambda -> {Read A,B : =Compare(A.X,B.X)}) |
|||
Function PrintTop { |
|||
Queue.Add Item(3, "Clear drains") : Gosub PrintTop() |
|||
Queue.Add Item(4 ,"Feed cat") : PrintTop() |
|||
Queue.Add Item(5 ,"Make tea") : PrintTop() |
|||
Queue.Add Item(1 ,"Solve RC tasks") : PrintTop() |
|||
Queue.Add Item(2 ,"Tax return") : PrintTop() |
|||
Print "remove items" |
|||
While true |
|||
MM=Queue.Poll() :Print MM.X, MM.S$,,"Size="; Queue.Size() |
|||
if Queue.Size()=0 then exit |
|||
PrintTop() |
|||
End While |
|||
Sub PrintTop() |
|||
M=Queue.Peek() : Print "Item ";M.X, M.S$ |
M=Queue.Peek() : Print "Item ";M.X, M.S$ |
||
End Sub |
|||
Comp=Lambda -> { Read A,B : =COMPARE(A.X,B.X)} |
|||
Queue=PriorityQueue(100,Comp) |
|||
Queue.Add Item(3, "Clear drains") |
|||
Call Local PrintTop() |
|||
Queue.Add Item(4 ,"Feed cat") |
|||
Call Local PrintTop() |
|||
Queue.Add Item(5 ,"Make tea") |
|||
Call Local PrintTop() |
|||
Queue.Add Item(1 ,"Solve RC tasks") |
|||
Call Local PrintTop() |
|||
Queue.Add Item(2 ,"Tax return") |
|||
Call Local PrintTop() |
|||
Print "remove items" |
|||
While true { |
|||
MM=Queue.Poll() |
|||
Print MM.X, MM.S$ |
|||
Print "Size="; Queue.Size() |
|||
If Queue.Size()=0 Then exit |
|||
Call Local PrintTop() |
|||
} |
|||
} |
} |
||
UnOrderedArray |
UnOrderedArray |
||
Line 4,526: | Line 4,525: | ||
===Using a stack with arrays as elements=== |
===Using a stack with arrays as elements=== |
||
Every insertion push item using binary search in proper position. Pop is very fast. |
Every insertion push item using binary search in proper position. Pop is very fast. Cons() used for demo purposes, make a new array from a series of arrays (a=cons(a,a) add to a an a . Variable a is a pointer to array (a tuple) |
||
<syntaxhighlight lang="m2000 interpreter"> |
<syntaxhighlight lang="m2000 interpreter"> |
||
Module PriorityQueue { |
Module PriorityQueue { |
||
a= ( |
a= ((3, "Clear drains"), (4 ,"Feed cat"), ( 5 , "Make tea")) |
||
a=cons(a, ((1 ,"Solve RC tasks"), ( 2 , "Tax return"))) |
|||
b=stack |
b=stack |
||
comp=lambda (a, b) -> |
comp=lambda (a, b) -> array(a, 0)<array(b, 0) |
||
=array(a, 0)<array(b, 0) |
|||
} |
|||
module InsertPQ (a, n, &comp) { |
module InsertPQ (a, n, &comp) { |
||
if len(a)=0 then stack a {data n} : exit |
if len(a)=0 then stack a {data n} : exit |
||
Line 4,541: | Line 4,540: | ||
t=2: b=len(a) |
t=2: b=len(a) |
||
m=b |
m=b |
||
while t<=b |
while t<=b |
||
t1=m |
t1=m |
||
m=(b+t) div 2 |
m=(b+t) div 2 |
||
Line 4,548: | Line 4,547: | ||
b=m-1 |
b=m-1 |
||
m=b |
m=b |
||
end while |
|||
if m>1 then shiftback m |
if m>1 then shiftback m |
||
} |
} |
||
Line 4,554: | Line 4,553: | ||
n=each(a) |
n=each(a) |
||
while n |
while n |
||
InsertPq b, array(n), &comp |
InsertPq b, array(n), &comp |
||
end while |
|||
n1=each(b) |
n1=each(b) |
||
while n1 |
while n1 |
||
m=stackitem(n1) |
m=stackitem(n1) |
||
print array(m, 0), array$(m, 1) |
|||
end while |
|||
\\ Peek topitem (without popping) |
\\ Peek topitem (without popping) |
||
print Array$(stackitem(b), 1) |
|||
\\ Pop item |
\\ Pop item |
||
Stack b { |
Stack b { |
||
Read old |
Read old |
||
} |
} |
||
print Array$(old, 1) |
|||
def Peek$(a)=Array$(stackitem(a), 1) |
|||
Function Pop$(a) { |
Function Pop$(a) { |
||
stack a { |
stack a { |
||
Line 4,578: | Line 4,577: | ||
} |
} |
||
} |
} |
||
print Peek$(b) |
|||
print Pop$(b) |
|||
def IsEmpty(a)=len(a)=0 |
|||
while not IsEmpty(b) |
|||
print pop$(b) |
|||
end while |
|||
Print pop$(b) |
|||
} |
|||
} |
} |
||
PriorityQueue |
PriorityQueue |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
Line 4,598: | Line 4,594: | ||
class obj { |
class obj { |
||
x, s$ |
x, s$ |
||
class: |
|||
module obj (.x, .s$) {} |
module obj (.x, .s$) {} |
||
} |
} |
||
Line 4,650: | Line 4,646: | ||
Print Pop$(b) |
Print Pop$(b) |
||
} |
} |
||
} |
|||
PriorityQueueForGroups |
|||
</syntaxhighlight> |
|||
===Using a stack with pointers to Groups as elements=== |
|||
Now we use pointer to group, and use of Subs and simple Functions (called using @ prefix). Also we have a global countmany (is a long type, see 0&) to check how many objects exist. We have use "as *obj" to declare a parameter to stay as pointer and to check the type (here is obj). The remove method of object called when object has to be removed. The constructor module obj called once and not exist in the final object obj (it is a part under Class: label, and this part define things for construction time only). Property toString$ is a group which return value (a string value), and we can use it with or without parameter. Because it is a group, we have to link parent properties/functions (but not modules) to get access. |
|||
<syntaxhighlight lang="m2000 interpreter"> |
|||
// using pointers to objects |
|||
global countmany=0& |
|||
class obj { |
|||
x, s$ |
|||
property toString$ { |
|||
value (sp=8) { |
|||
link parent x, s$ to x, s$ |
|||
value$=format$("{0::-5}"+string$(" ", sp)+"{1:20}", x, s$) |
|||
} |
|||
} |
|||
remove { |
|||
countmany-- |
|||
} |
|||
class: |
|||
module obj (.x, .s$) {countmany++} |
|||
} |
|||
// obj() return object as value (using a special pointer) |
|||
function global g(priority, task$) { |
|||
// here we return an object using nonrmal pointer |
|||
// try to change -> to = to see the error |
|||
->obj(priority, task$) |
|||
} |
|||
Module PriorityQueueForGroups { |
|||
Flush ' empty current stack |
|||
Data g(3, "Clear drains"),g(4 ,"Feed cat"), g( 5 , "Make tea") |
|||
Data g( 1 ,"Solve RC tasks"), g( 2 , "Tax return") |
|||
ObjectCount() |
|||
b=stack |
|||
while not empty |
|||
InsertPQ(b) // top of stack is b then objects follow |
|||
end while |
|||
ObjectCount() |
|||
Print "Using Peek to Examine Priority Queue" |
|||
n1=each(b) |
|||
Header() |
|||
while n1 |
|||
Print @Peek$(n1) |
|||
end while |
|||
ObjectCount() |
|||
Header() |
|||
while not @isEmpty(b) |
|||
Print @Pop(b)=>tostring$ |
|||
end while |
|||
ObjectCount() |
|||
// here are the subs/simple functions |
|||
// these are static parts of module |
|||
sub Header() |
|||
Print " Priority Task" |
|||
Print "========== ================" |
|||
end sub |
|||
sub ObjectCount() |
|||
Print "There are ";countmany;" objects of type obj" |
|||
end sub |
|||
sub InsertPQ(a, n as *obj) |
|||
Print "Insert:";n=>tostring$(1) |
|||
if len(a)=0 then stack a {data n} : exit sub |
|||
if @comp(n, stackitem(a)) then stack a {push n} : exit sub |
|||
stack a { |
|||
push n |
|||
local t=2, b=len(a) |
|||
local m=b |
|||
while t<=b |
|||
t1=m |
|||
m=(b+t) div 2 |
|||
if m=0 then m=t1 : exit |
|||
If @comp(stackitem(m),n) then t=m+1: continue |
|||
b=m-1 |
|||
m=b |
|||
end while |
|||
if m>1 then shiftback m |
|||
} |
|||
end sub |
|||
function comp(a as *obj, b as *obj) |
|||
=a=>x<b=>x |
|||
end function |
|||
function Peek$(a as stack) |
|||
=stackitem(a)=>toString$ |
|||
end function |
|||
function IsEmpty(a) |
|||
=len(a)=0 |
|||
end function |
|||
Function Pop(a) |
|||
// Group make a copy |
|||
stack a {=Group} |
|||
end function |
|||
} |
} |
||
PriorityQueueForGroups |
PriorityQueueForGroups |