简体   繁体   中英

How to implement queue and priority queue in Tcl?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM