简单的优先链表

This commit is contained in:
2019-02-25 02:37:34 +08:00
parent 26ba5a9e0a
commit 0fb5a2ca4a
6 changed files with 183 additions and 596 deletions

70
priority_list/iterator.go Normal file
View File

@@ -0,0 +1,70 @@
package plist
type Iterator struct {
pl *PriorityList
cur *Node
}
func (iter *Iterator) Value() interface{} {
return iter.cur.Value
}
func (iter *Iterator) RingNext() bool {
if iter.pl.size == 0 {
return false
}
iter.cur = iter.cur.next
if iter.cur == iter.pl.tail {
iter.cur = iter.pl.head.next
}
return true
}
func (iter *Iterator) Next() bool {
if iter.cur == iter.pl.tail {
return false
}
if iter.cur.next == iter.pl.tail {
iter.cur = iter.cur.next
return false
}
iter.cur = iter.cur.next
return true
}
func (iter *Iterator) RingPrev() bool {
if iter.pl.size == 0 {
return false
}
iter.cur = iter.cur.prev
if iter.cur == iter.pl.head {
iter.cur = iter.pl.tail.prev
}
return true
}
func (iter *Iterator) Prev() bool {
if iter.cur == iter.pl.head {
return false
}
if iter.cur.prev == iter.pl.head {
iter.cur = iter.cur.prev
return false
}
iter.cur = iter.cur.prev
return true
}
func (iter *Iterator) MoveHead() {
iter.cur = iter.pl.head
}
func (iter *Iterator) MoveTail() {
iter.cur = iter.pl.tail
}

View File

@@ -1,18 +0,0 @@
package plist
// NodeInt plist 现成的Int节点, 可以作为例子
type NodeInt struct {
Node
}
// Compare plist 现成的Int节点Compare覆盖
func (fl *NodeInt) Compare(v INode) bool {
return fl.GetValue().(int) > v.GetValue().(int)
}
// NewNodeInt plist 现成的Int节点, New一个NodeInt
func NewNodeInt(v int) (fl *NodeInt) {
fl = new(NodeInt)
fl.SetValue(v)
return fl
}

View File

@@ -2,6 +2,7 @@ package plist
import (
"github.com/davecgh/go-spew/spew"
"github.com/emirpasic/gods/utils"
)
// INode 比较的必须继承的接口
@@ -21,59 +22,18 @@ type INode interface {
// Node 优先链表的节点
type Node struct {
INode
prev, next INode
next, prev *Node
// isrelease bool
value interface{}
}
// NewNode 创建一个PriorityList 节点
func NewNode(v interface{}) *Node {
n := new(Node)
n.SetValue(v)
return n
}
// GetValue 获取值
func (node *Node) GetValue() interface{} {
return node.value
}
// SetValue 设置值
func (node *Node) SetValue(v interface{}) {
node.value = v
}
// GetPrev 获取left值
func (node *Node) GetPrev() INode {
return node.prev
}
// SetPrev 设置left值
func (node *Node) SetPrev(n INode) {
node.prev = n
}
// GetNext 设置right值
func (node *Node) GetNext() INode {
return node.next
}
// SetNext 获取left值
func (node *Node) SetNext(n INode) {
node.next = n
}
func (node *Node) String() string {
return spew.Sprint(node.value)
Value interface{}
}
// PriorityList 优先列表
type PriorityList struct {
head INode
tail INode
head *Node
tail *Node
size int
compartor utils.Comparator
size int
}
// Size 长度
@@ -84,135 +44,73 @@ func (pl *PriorityList) Size() int {
// Clear 清空链表, 如果外部有引用其中一个节点 要把节点Prev Next值为nil, 三色标记
func (pl *PriorityList) Clear() {
pl.head = nil
pl.tail = nil
pl.size = 0
}
// GetCompare 获取比较的节点 compare >= 11这个节点小的值 [15,12,9,8,6,1] = 9
func (pl *PriorityList) GetCompare(cNode INode) INode {
cur := pl.head
for cur != nil {
if !cur.Compare(cNode) {
return cur
}
cur = cur.GetNext()
}
return nil
}
// GetCompareReverse 逆序获取比较的节点 compare >= 11这个节点大的值 [15,12,9,8,6,1] = 12
func (pl *PriorityList) GetCompareReverse(cNode INode) INode {
cur := pl.tail
for cur != nil {
if cur.Compare(cNode) {
return cur
}
cur = cur.GetPrev()
}
return nil
}
// ForEach 顺序遍历
func (pl *PriorityList) ForEach(eachfunc func(INode) bool) {
cur := pl.head
for cur != nil {
if !eachfunc(cur) {
break
}
cur = cur.GetNext()
}
}
// ForEachReverse 逆遍历
func (pl *PriorityList) ForEachReverse(eachfunc func(INode) bool) {
cur := pl.tail
for cur != nil {
if !eachfunc(cur) {
break
}
cur = cur.GetPrev()
}
}
// // ForEach 顺序遍历
// func (pl *PriorityList) ForEach(eachfunc func(*Node) *Node) {
// cur := pl.head
// }
// Get 获取索引长度
func (pl *PriorityList) Get(idx int) INode {
if idx >= pl.size {
return nil
func (pl *PriorityList) Get(idx int) interface{} {
node := pl.GetNode(idx)
if node != nil {
return node.Value
}
cur := pl.head
for i := 0; i < idx; i++ {
cur = cur.GetNext()
}
return cur
return nil
}
// GetReverse 腻序获取索引长度
func (pl *PriorityList) GetReverse(idx int) INode {
if idx >= pl.size {
return nil
}
cur := pl.tail
for i := 0; i < idx; i++ {
cur = cur.GetPrev()
}
return cur
}
// Remove 删除节点
func (pl *PriorityList) Remove(node INode) {
if pl.size <= 1 {
pl.head = nil
pl.tail = nil
if pl.size == 0 {
panic("the node is not in this list, node:" + spew.Sprint(node))
// GetNode 获取索引长度
func (pl *PriorityList) GetNode(idx int) *Node {
if idx >= 0 {
cur := pl.head.next
for i := 0; cur != pl.tail; i++ {
if i == idx {
return cur
}
cur = cur.next
}
pl.size = 0
} else {
cur := pl.tail.prev
for i := -1; cur != pl.head; i-- {
if i == idx {
return cur
}
cur = cur.prev
}
}
return nil
}
// Remove 删除节点
func (pl *PriorityList) Remove(idx int) {
pl.RemoveNode(pl.GetNode(idx))
}
// RemoveNode 删除节点
func (pl *PriorityList) RemoveNode(node *Node) {
if node == nil {
return
}
prev := node.prev
next := node.next
prev.next = next
next.prev = prev
pl.size--
prev := node.GetPrev()
next := node.GetNext()
if prev == nil {
pl.head = next
next.SetPrev(nil)
node.SetNext(nil)
} else if next == nil {
pl.tail = prev
prev.SetNext(nil)
node.SetPrev(nil)
} else {
prev.SetNext(next)
next.SetPrev(prev)
node.SetPrev(nil)
node.SetNext(nil)
}
}
// RemoveIndex 删除节点 并获取该节点
func (pl *PriorityList) RemoveIndex(idx int) INode {
result := pl.Get(idx)
pl.Remove(result)
return result
}
// RemoveReverseIndex 逆顺序删除节点 并获取该节点
func (pl *PriorityList) RemoveReverseIndex(idx int) INode {
result := pl.GetReverse(idx)
pl.Remove(result)
return result
}
func (pl *PriorityList) String() string {
content := "["
cur := pl.head
for cur != nil {
content += spew.Sprint(cur.GetValue()) + ","
cur = cur.GetNext()
cur := pl.head.next
for cur != pl.tail {
content += spew.Sprint(cur.Value) + ","
cur = cur.next
}
if content[len(content)-1:] == "," {
@@ -223,48 +121,44 @@ func (pl *PriorityList) String() string {
return content
}
func (pl *PriorityList) Iterator() *Iterator {
return &Iterator{pl: pl, cur: pl.head}
}
// Insert 插入节点
func (pl *PriorityList) Insert(node INode) {
func (pl *PriorityList) Insert(value interface{}) {
pl.size++
if pl.head == nil {
pl.head = node
pl.tail = node
return
}
cur := pl.head
for {
if !cur.Compare(node) {
// 插入该值
prev := cur.GetPrev()
if prev == nil {
pl.head.SetPrev(node)
node.SetNext(pl.head)
pl.head = node
} else {
prev.SetNext(node)
node.SetNext(cur)
cur.SetPrev(node)
node.SetPrev(prev)
}
inode := &Node{Value: value}
cur := pl.head.next
for i := 0; cur != pl.tail; i++ {
if pl.compartor(value, cur.Value) > 0 {
prev := cur.prev
prev.next = inode
cur.prev = inode
inode.prev = prev
inode.next = cur
return
}
next := cur.GetNext()
if next == nil {
cur.SetNext(node)
node.SetPrev(cur)
pl.tail = node
return
}
cur = next
cur = cur.next
}
prev := cur.prev
prev.next = inode
cur.prev = inode
inode.prev = prev
inode.next = cur
}
// New 创建 PriorityList
func New() *PriorityList {
return new(PriorityList)
func New(compartor utils.Comparator) *PriorityList {
pl := new(PriorityList)
pl.compartor = compartor
pl.head = new(Node)
pl.tail = new(Node)
pl.head.next = pl.tail
pl.tail.prev = pl.head
return pl
}

View File

@@ -2,86 +2,41 @@ package plist
import (
"testing"
"github.com/Pallinder/go-randomdata"
"github.com/emirpasic/gods/utils"
)
func TestPriority(t *testing.T) {
pl := New()
pl := New(utils.IntComparator)
for i := 0; i < 20; i++ {
pl.Insert(randomdata.Number(0, 100000))
}
t.Error(pl.String(), pl.Get(5), pl.Get(-1), pl.Get(-pl.size), pl.Get(-pl.size-1))
pl.Insert(NewNodeInt(1))
pl.Insert(NewNodeInt(2))
pl.Insert(NewNodeInt(3))
if pl.String() != "[3,2,1]" {
t.Error("Insert or String error", pl.String())
iter := pl.Iterator()
for iter.Next() {
t.Error(iter.Value())
}
if pl.Get(0).GetValue() != 3 {
t.Error(pl.Get(0).GetValue())
for iter.Prev() {
t.Error(iter.Value())
}
if pl.Get(pl.Size()-1).GetValue() != 1 {
t.Error(pl.Get(pl.Size() - 1).GetValue())
}
if pl.Size() != 3 {
t.Error("size error, current is", pl.Size())
}
pl.Remove(pl.Get(2))
if pl.String() != "[3,2]" || pl.Size() != 2 {
t.Error("Remove error current is ", pl.String(), pl.Size())
}
pl.Remove(pl.GetReverse(0))
if pl.String() != "[3]" || pl.Size() != 1 {
t.Error("Remove error current is ", pl.String(), pl.Size())
}
pl.Remove(pl.Get(0))
if pl.String() != "[]" || pl.Size() != 0 {
t.Error("Remove error current is ", pl.String(), pl.Size())
}
pl.Insert(NewNodeInt(6))
pl.Insert(NewNodeInt(5))
pl.Insert(NewNodeInt(7))
pl.Insert(NewNodeInt(12))
pl.Insert(NewNodeInt(8))
if pl.String() != "[12,8,7,6,5]" || pl.Size() != 5 {
t.Error("Insert or String error, current is ", pl.String(), pl.Size())
}
pl.RemoveReverseIndex(3)
if pl.String() != "[12,7,6,5]" || pl.Size() != 4 {
t.Error("Remove error current is ", pl.String(), pl.Size())
}
size := pl.Size()
for i := 0; i < size; i++ {
pl.RemoveReverseIndex(0)
}
if pl.String() != "[]" || pl.Size() != 0 {
t.Error("Remove error current is ", pl.String(), pl.Size())
}
pl.Insert(NewNodeInt(6))
pl.Insert(NewNodeInt(1))
pl.Insert(NewNodeInt(9))
pl.Insert(NewNodeInt(15))
pl.Insert(NewNodeInt(12))
pl.Insert(NewNodeInt(8))
if pl.GetCompare(NewNodeInt(9)).GetValue() != 9 {
t.Error(pl.String(), pl.GetCompare(NewNodeInt(9)).GetValue())
}
if pl.GetCompareReverse(NewNodeInt(11)).GetValue() != 12 {
t.Error(pl.String(), pl.GetCompareReverse(NewNodeInt(11)).GetValue())
}
pl.Clear()
if pl.String() != "[]" || pl.Size() != 0 {
t.Error("Remove error current is ", pl.String(), pl.Size())
for i := 0; i < 20; i++ {
pl.Remove(0)
t.Error(pl.String())
}
}
func BenchmarkPriority(b *testing.B) {
pl := New(utils.IntComparator)
b.N = 10000
for i := 0; i < b.N; i++ {
pl.Insert(randomdata.Number(0, 100000))
}
}