I have to implement either queue or priority queue in Tcl without use of any library.
I have tried to write below code. Kindly help me to implement queue in better way in Tcl/Tk.
create node
// crearting node element of queue
proc createNode {name cost} {
namespace eval $name [subst {
variable cost $cost
variable this $name
}]
functions
proc ${name}::getCost {} {
variable cost
return $cost
}
return $name
}
delete queue
proc deQueue name {
#upvar 1 $name queue
set queue $name
set res [lindex $queue 0]
set queue [lrange $queue 1 end]; # remove the first element
set res; # return the value
}
queue insertion
proc enQueue {newNode name} {
#upvar 1 $name queue
set queue $name
set queue [concat $newNode $queue]
}
create queue
proc makeQueue {n g } {
set queue [list [createNode $n $g ]]
return $queue
}
A simple queue implementation:
proc enqueue {name item} {
upvar 1 $name queue
lappend queue $item
}
proc dequeue name {
upvar 1 $name queue
set queue [lassign $queue item]
return $item
}
% enqueue a foo
% set item [dequeue a]
A simple priority queue:
proc enpqueue {name prio item} {
upvar 1 $name queue
lappend queue [list $prio $item]
set queue [lsort -decreasing -integer -index 0 $queue]
}
proc depqueue name {
upvar 1 $name queue
set queue [lassign $queue prioitem]
return [lindex $prioitem 1]
}
% enpqueue a 10 foo
% enpqueue a 40 bar
% set item [depqueue a]
bar
The only thing you need for a queue or priority queue is a list and an add/remove interface.
If you want to store structured data in the queue, make the item
either a tuple of data:
set item [list "Smith, John" 42 1500]
or a dictionary:
set item [list name "Smith, John" age 42 foo 1500]
Documentation: lappend , lassign , lindex , list , lsort , proc , return , set , upvar
Queues are abstract data structures with two (key) operations: add
and get
(and an empty
test is pretty common too). They're sufficiently complex internally that it's probably best to think in terms of using a TclOO object as their implementation:
oo::class create Queue {
variable q
constructor {} {
set q {}
}
method add {item} {
lappend q $item
return
}
method empty {} {
expr {[llength $q] == 0}
}
method get {} {
if {[my empty]} {
return -code error "queue is empty"
}
set q [lassign $q item]
return $item
}
}
Priority queues are like queues, except that they have a priority as well and sort by that priority. The trick to implementing them efficiently is not to sort on each add
or get
, but rather to only sort when necessary. (Or you can use an appropriate balanced tree, but they're quite complicated.)
oo::class create PriorityQueue {
variable q sorted
constructor {} {
set q {}
set sorted 1
}
method add {item priority} {
lappend q $item $priority
set sorted 0
return
}
method empty {} {
expr {[llength $q] == 0}
}
method get {} {
if {[my empty]} {
return -code error "queue is empty"
}
if {!$sorted} {
# You might want other options here, depending on what "priority" means
set q [lsort -stride 2 -index 1 -integer $q]
set sorted 1
}
set q [lassign $q item priority]
return $item
}
}
Using these data structures is fairly simple:
# Instantiate
set myq [PriorityQueue new]
# Add some values
$myq add "The quick brown fox" 12
$myq add "The lazy dog" 34
# Drain the queue
while {![$myq empty]} {
puts [$myq get]
}
# Get rid of it now we're done
$myq destroy
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.