github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/g/queue.go (about)

     1  package g
     2  
     3  import "time"
     4  
     5  type Queue struct {
     6  	length int
     7  	data   []QueueComparer
     8  }
     9  
    10  type QueueComparer interface {
    11  	Less(QueueComparer) bool
    12  }
    13  
    14  type QueueString struct {
    15  	index  int64
    16  	String string
    17  }
    18  
    19  func NewQueueString(s string) *QueueString {
    20  	return &QueueString{index: time.Now().UnixNano(), String: s}
    21  }
    22  
    23  // Less Implementation QueueComparer interface.
    24  func (a *QueueString) Less(b QueueComparer) bool {
    25  	return a.index < b.(*QueueString).index
    26  	//return strings.Compare(a.String, b.String) < 0
    27  }
    28  
    29  func NewQueue(data []QueueComparer) *Queue {
    30  	q := &Queue{}
    31  	q.data = data
    32  	q.length = len(data)
    33  	if q.length > 0 {
    34  		i := q.length >> 1
    35  		for ; i >= 0; i-- {
    36  			q.down(i)
    37  		}
    38  	}
    39  	return q
    40  }
    41  
    42  func (q *Queue) Push(item QueueComparer) {
    43  	q.data = append(q.data, item)
    44  	q.length++
    45  	q.up(q.length - 1)
    46  }
    47  
    48  func (q *Queue) Pop() QueueComparer {
    49  	if q.length == 0 {
    50  		return nil
    51  	}
    52  	top := q.data[0]
    53  	q.length--
    54  	if q.length > 0 {
    55  		q.data[0] = q.data[q.length]
    56  		q.down(0)
    57  	}
    58  	q.data = q.data[:len(q.data)-1]
    59  	return top
    60  }
    61  
    62  func (q *Queue) Peek() QueueComparer {
    63  	if q.length == 0 {
    64  		return nil
    65  	}
    66  	return q.data[0]
    67  }
    68  
    69  func (q *Queue) Len() int {
    70  	return q.length
    71  }
    72  
    73  func (q *Queue) down(pos int) {
    74  	data := q.data
    75  	halfLength := q.length >> 1
    76  	item := data[pos]
    77  	for pos < halfLength {
    78  		left := (pos << 1) + 1
    79  		right := left + 1
    80  		best := data[left]
    81  		if right < q.length && data[right].Less(best) {
    82  			left = right
    83  			best = data[right]
    84  		}
    85  		if !best.Less(item) {
    86  			break
    87  		}
    88  		data[pos] = best
    89  		pos = left
    90  	}
    91  	data[pos] = item
    92  }
    93  
    94  func (q *Queue) up(pos int) {
    95  	data := q.data
    96  	item := data[pos]
    97  	for pos > 0 {
    98  		parent := (pos - 1) >> 1
    99  		current := data[parent]
   100  		if !item.Less(current) {
   101  			break
   102  		}
   103  		data[pos] = current
   104  		pos = parent
   105  	}
   106  	data[pos] = item
   107  }