如果要保存最大值, 必须要Node交换不能值指针交换

This commit is contained in:
2019-03-25 01:40:12 +08:00
parent 51acc649a4
commit dd4c76f144
11 changed files with 1447 additions and 149 deletions

View File

@@ -3,8 +3,8 @@ package plist
import (
"strings"
"474420502.top/eson/structure/compare"
"github.com/davecgh/go-spew/spew"
"github.com/emirpasic/gods/utils"
)
type Node struct {
@@ -15,11 +15,11 @@ type Node struct {
type PriorityList struct {
head, tail *Node
size int
comparator utils.Comparator
Compare compare.Compare
}
func New(compartor utils.Comparator) *PriorityList {
pl := &PriorityList{head: &Node{}, tail: &Node{}, size: 0, comparator: compartor}
func New(Compare compare.Compare) *PriorityList {
pl := &PriorityList{head: &Node{}, tail: &Node{}, size: 0, Compare: Compare}
pl.head.next = pl.tail
pl.tail.prev = pl.head
return pl
@@ -57,9 +57,13 @@ func (pl *PriorityList) CircularIterator() *CircularIterator {
return &CircularIterator{pl: pl, cur: pl.head}
}
func (pl *PriorityList) Push(pvalue interface{}) {
func (pl *PriorityList) Size() int {
return pl.size
}
func (pl *PriorityList) Push(value interface{}) {
pl.size++
pnode := &Node{value: pvalue}
pnode := &Node{value: value}
if pl.size == 1 {
pl.head.next = pnode
pl.tail.prev = pnode
@@ -70,7 +74,7 @@ func (pl *PriorityList) Push(pvalue interface{}) {
cur := pl.head
for ; cur.next != pl.tail; cur = cur.next {
if pl.comparator(pvalue, cur.next.value) > 0 {
if pl.Compare(value, cur.next.value) > 0 {
cnext := cur.next
cur.next = pnode
@@ -88,16 +92,37 @@ func (pl *PriorityList) Push(pvalue interface{}) {
pl.tail.prev = pnode
}
func (pl *PriorityList) Get(idx int) interface{} {
return pl.GetNode(idx).value
func (pl *PriorityList) Top() (result interface{}, ok bool) {
if pl.size > 0 {
return pl.head.next.value, true
}
return nil, false
}
func (pl *PriorityList) GetNode(idx int) *Node {
func (pl *PriorityList) Pop() (result interface{}, ok bool) {
if pl.size > 0 {
pl.size--
temp := pl.head.next
temp.next.prev = pl.head
pl.head.next = temp.next
return temp.value, true
}
return nil, false
}
func (pl *PriorityList) Get(idx int) (interface{}, bool) {
if n, ok := pl.GetNode(idx); ok {
return n.value, true
}
return nil, false
}
func (pl *PriorityList) GetNode(idx int) (*Node, bool) {
if idx >= 0 {
cur := pl.head.next
for i := 0; cur != pl.tail; i++ {
if i == idx {
return cur
return cur, true
}
cur = cur.next
}
@@ -105,16 +130,18 @@ func (pl *PriorityList) GetNode(idx int) *Node {
cur := pl.tail.prev
for i := -1; cur != pl.head; i-- {
if i == idx {
return cur
return cur, true
}
cur = cur.prev
}
}
return nil
return nil, false
}
func (pl *PriorityList) RemoveWithIndex(idx int) {
pl.Remove(pl.GetNode(idx))
if n, ok := pl.GetNode(idx); ok {
pl.Remove(n)
}
}
func (pl *PriorityList) Remove(node *Node) {

View File

@@ -5,49 +5,11 @@ import (
"encoding/gob"
"io/ioutil"
"log"
"os"
"testing"
"github.com/Pallinder/go-randomdata"
"github.com/emirpasic/gods/utils"
"474420502.top/eson/structure/compare"
)
const CompartorSize = 100
const NumberMax = 50000000
func Save(t *testing.T) {
f, err := os.OpenFile("../l.log", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
if err != nil {
log.Println(err)
}
//fmt.Println(userBytes)
var l []int
// for i := 0; len(l) < 1000; i++ {
// v := randomdata.Number(0, 65535)
// l = append(l, v)
// }
//m := make(map[int]int)
for i := 0; len(l) < CompartorSize; i++ {
v := randomdata.Number(0, NumberMax)
// if _, ok := m[v]; !ok {
// m[v] = v
l = append(l, v)
// }
}
var result bytes.Buffer
encoder := gob.NewEncoder(&result)
encoder.Encode(l)
lbytes := result.Bytes()
f.Write(lbytes)
}
func loadTestData() []int {
data, err := ioutil.ReadFile("../l.log")
if err != nil {
@@ -60,7 +22,7 @@ func loadTestData() []int {
}
func TestInsert(t *testing.T) {
pl := New(utils.IntComparator)
pl := New(compare.Int)
for i := 0; i < 10; i++ {
pl.Push(i)
}
@@ -91,7 +53,7 @@ func TestInsert(t *testing.T) {
}
func TestIterator(t *testing.T) {
pl := New(utils.IntComparator)
pl := New(compare.Int)
for i := 0; i < 10; i++ {
pl.Push(i)
}
@@ -116,7 +78,7 @@ func TestIterator(t *testing.T) {
}
func TestCircularIterator(t *testing.T) {
pl := New(utils.IntComparator)
pl := New(compare.Int)
for i := 0; i < 10; i++ {
pl.Push(i)
}
@@ -160,58 +122,118 @@ func TestCircularIterator(t *testing.T) {
}
func TestGet(t *testing.T) {
pl := New(utils.IntComparator)
pl := New(compare.Int)
for i := 0; i < 10; i++ {
pl.Push(i)
}
for _, v := range []int{0, 9, 5, 7} {
if pl.Get(v) != (9 - v) {
t.Error(v, "Get == ", pl.Get(v))
if g, ok := pl.Get(v); ok {
if g != (9 - v) {
t.Error(v, "Get == ", g)
}
}
}
func() {
defer func() {
if err := recover(); err == nil {
t.Error("out index, but is not error")
}
}()
if n, ok := pl.Get(10); ok {
t.Error("index 10 is over size", n)
}
}
pl.Get(10)
}()
func TestTop(t *testing.T) {
pl := New(compare.Int)
for i := 0; i < 10; i++ {
pl.Push(i)
}
i := 0
for n, ok := pl.Pop(); ok; n, ok = pl.Pop() {
if (9 - i) != n {
t.Error("value is not equal ", i)
}
if top, tok := pl.Top(); tok {
if (9 - i - 1) != top {
t.Error("top is error cur i = ", i, "top is ", top)
}
}
i++
}
if pl.Size() != 0 {
t.Error("list size is not zero")
}
}
func TestPop(t *testing.T) {
pl := New(compare.Int)
for i := 0; i < 10; i++ {
pl.Push(i)
}
i := 0
for n, ok := pl.Pop(); ok; n, ok = pl.Pop() {
if (9 - i) != n {
t.Error("value is not equal ", i)
}
i++
}
if pl.Size() != 0 {
t.Error("list size is not zero")
}
for i := 9; i >= 0; i-- {
pl.Push(i)
}
i = 0
for n, ok := pl.Pop(); ok; n, ok = pl.Pop() {
if (9 - i) != n {
t.Error("value is not equal ", i)
}
i++
}
if pl.Size() != 0 {
t.Error("list size is not zero")
}
}
func TestRemove(t *testing.T) {
pl := New(utils.IntComparator)
pl := New(compare.Int)
for i := 0; i < 10; i++ {
pl.Push(i)
}
pl.RemoveWithIndex(0)
if pl.Get(0).(int) != 8 {
t.Error(pl.Get(0))
if g, ok := pl.Get(0); ok {
if g != 8 {
t.Error(g)
}
}
pl.RemoveWithIndex(-1)
if pl.Get(-1).(int) != 1 {
t.Error(pl.Get(-1))
if g, ok := pl.Get(-1); ok {
if g != 1 {
t.Error(g)
}
}
}
func BenchmarkGet(b *testing.B) {
pl := New(utils.IntComparator)
pl := New(compare.Int)
b.N = 100
l := loadTestData()
for i := 0; i < b.N; i++ {
v := randomdata.Number(0, 65535)
for _, v := range l {
pl.Push(v)
}
b.ResetTimer()
b.StartTimer()
b.N = len(l)
for i := 0; i < b.N; i++ {
if i%2 == 0 {
@@ -227,10 +249,10 @@ func BenchmarkInsert(b *testing.B) {
b.ResetTimer()
b.StartTimer()
execCount := 500
execCount := 1
b.N = len(l) * execCount
for i := 0; i < execCount; i++ {
pl := New(utils.IntComparator)
pl := New(compare.Int)
for _, v := range l {
pl.Push(v)
}