From a07c58bef4cfc12e4e672648a67c431def333693 Mon Sep 17 00:00:00 2001 From: eson <474420502@qq.com> Date: Fri, 21 Dec 2018 01:35:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BC=98=E5=85=88=E9=93=BE?= =?UTF-8?q?=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- priority_list/plist_node.go | 18 ++ priority_list/priority_list.go | 270 ++++++++++++++++++++++++++++ priority_list/priority_list_test.go | 77 ++++++++ 3 files changed, 365 insertions(+) create mode 100644 priority_list/plist_node.go create mode 100644 priority_list/priority_list.go create mode 100644 priority_list/priority_list_test.go diff --git a/priority_list/plist_node.go b/priority_list/plist_node.go new file mode 100644 index 0000000..eee306a --- /dev/null +++ b/priority_list/plist_node.go @@ -0,0 +1,18 @@ +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 +} diff --git a/priority_list/priority_list.go b/priority_list/priority_list.go new file mode 100644 index 0000000..f42eea3 --- /dev/null +++ b/priority_list/priority_list.go @@ -0,0 +1,270 @@ +package plist + +import ( + "github.com/davecgh/go-spew/spew" +) + +// INode 比较的必须继承的接口 +type INode interface { + Compare(v INode) bool + + // GetValue 获取值 + GetValue() interface{} + // SetValue 设置值 + SetValue(v interface{}) + + GetPrev() INode + SetPrev(INode) + GetNext() INode + SetNext(INode) +} + +// Node 优先链表的节点 +type Node struct { + INode + prev, next INode + // 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) +} + +// PriorityList 优先列表 +type PriorityList struct { + head INode + tail INode + + size int +} + +// Size 长度 +func (pl *PriorityList) Size() int { + return pl.size +} + +// Clear 清空链表, 如果外部有引用其中一个节点 要把节点Prev Next值为nil, 三色标记 +func (pl *PriorityList) Clear() { + pl.head = nil + pl.tail = nil + pl.size = 0 +} + +// Get 获取索引长度 +func (pl *PriorityList) Get(idx int) INode { + if idx >= pl.size { + return nil + } + cur := pl.head + for i := 0; i < idx; i++ { + cur = cur.GetNext() + } + return cur +} + +// 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)) + } + pl.size = 0 + return + } + + 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 + // if idx >= pl.size { + // return nil + // } + + // pl.size-- + + // var cur INode + // if pl.size == 1 { + // cur = pl.head + // pl.head = nil + // pl.tail = nil + + // if cur == nil { + // panic("why cur == nil?") + // } + + // return cur + // } + + // cur = pl.head + // for i := 0; i < idx; i++ { + // cur = cur.GetNext() + // } + + // prev := cur.GetPrev() + // next := cur.GetNext() + + // if prev == nil { + // pl.head = next + // pl.head.SetPrev(nil) + // } else if next == nil { + // pl.tail = prev + // pl.tail.SetNext(nil) + // } else { + // prev.SetNext(next) + // next.SetPrev(prev) + // } + + // cur.SetNext(nil) + // cur.SetPrev(nil) + + // if cur == nil { + // panic("why cur == nil?") + // } + + // return cur +} + +// 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() + } + + if content[len(content)-1:] == "," { + content = content[:len(content)-1] + } + + content += "]" + return content +} + +// Insert 插入节点 +func (pl *PriorityList) Insert(node INode) { + 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) + } + + return + } + + next := cur.GetNext() + if next == nil { + cur.SetNext(node) + node.SetPrev(cur) + pl.tail = node + return + } + cur = next + + } + +} + +// New 创建 PriorityList +func New() *PriorityList { + return new(PriorityList) +} diff --git a/priority_list/priority_list_test.go b/priority_list/priority_list_test.go new file mode 100644 index 0000000..5816675 --- /dev/null +++ b/priority_list/priority_list_test.go @@ -0,0 +1,77 @@ +package plist + +import "testing" + +func TestPriority(t *testing.T) { + pl := New() + + 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()) + } + + if pl.Get(0).GetValue() != 3 { + t.Error(pl.Get(0).GetValue()) + } + + 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()) + } + + t.Log("size is", pl.Size()) + size := pl.Size() + for i := 0; i < size; i++ { + pl.RemoveReverseIndex(0) + t.Log(i) + } + 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)) + + pl.Clear() + + if pl.String() != "[]" || pl.Size() != 0 { + t.Error("Remove error current is ", pl.String(), pl.Size()) + } +}