eson
368447c31d
new file: LICENSE new file: README.md new file: compare/compare.go new file: for_test.go new file: heap/heap.go new file: heap/heap_test.go new file: interface.go new file: lastack/lastack.go new file: lastack/lastack_test.go new file: list/list.go new file: list/list_test.go new file: map/hashmap/hashmap.go new file: map/hashmap/hashmap_test.go new file: priority_list/iterator.go new file: priority_list/priority_list.go new file: priority_list/priority_list_test.go new file: priority_queue/iterator.go new file: priority_queue/priority_queue.go new file: priority_queue/priority_queue_test.go new file: priority_queue/vbt.go new file: priority_queue/vbt_test.go new file: priority_queuekey/iterator.go new file: priority_queuekey/priority_queuekey.go new file: priority_queuekey/priority_queuekey_test.go new file: priority_queuekey/vbt.go new file: priority_queuekey/vbt_test.go new file: set/hashset/hashset.go new file: set/hashset/hashset_test.go new file: set/treeset/treeset.go new file: set/treeset/treeset_test.go new file: sparse_array/array2/array2.go new file: sparse_array/array2/array2_test.go new file: sparse_array/array3/array3.go new file: sparse_array/array3/array3_test.go new file: sparse_array/arrayn/arrayn.go new file: sparse_array/arrayn/arrayn_test.go new file: stack/stack.go new file: stack/stack_test.go new file: tree/avl/avl.go new file: tree/avl/avl_test.go new file: tree/avl/iterator.go new file: tree/avldup/avldup.go new file: tree/avldup/avldup_test.go new file: tree/avldup/iterator.go new file: tree/avlkey/avlkey.go new file: tree/avlkey/avlkey_test.go new file: tree/avlkey/iterator.go new file: tree/avlkeydup/avlkeydup.go new file: tree/avlkeydup/avlkeydup_test.go new file: tree/avlkeydup/iterator.go new file: tree/vbt/iterator.go new file: tree/vbt/vbt.go new file: tree/vbt/vbt_test.go new file: tree/vbtkey/iterator.go new file: tree/vbtkey/vbtkey.go new file: tree/vbtkey/vbtkey_test.go
230 lines
4.5 KiB
Go
230 lines
4.5 KiB
Go
package avl
|
|
|
|
import (
|
|
"474420502.top/eson/structure/lastack"
|
|
)
|
|
|
|
type Iterator struct {
|
|
dir int
|
|
up *Node
|
|
cur *Node
|
|
tstack *lastack.Stack
|
|
// curnext *Node
|
|
}
|
|
|
|
func initIterator(avltree *Tree) *Iterator {
|
|
iter := &Iterator{tstack: lastack.New()}
|
|
iter.up = avltree.root
|
|
return iter
|
|
}
|
|
|
|
func NewIterator(n *Node) *Iterator {
|
|
iter := &Iterator{tstack: lastack.New()}
|
|
iter.up = n
|
|
return iter
|
|
}
|
|
|
|
func NewIteratorWithCap(n *Node, cap int) *Iterator {
|
|
iter := &Iterator{tstack: lastack.NewWithCap(cap)}
|
|
iter.up = n
|
|
return iter
|
|
}
|
|
|
|
func (iter *Iterator) SetNode(n *Node) {
|
|
iter.up = n
|
|
iter.dir = 0
|
|
iter.tstack.Clear()
|
|
}
|
|
|
|
func (iter *Iterator) Value() interface{} {
|
|
return iter.cur.value
|
|
}
|
|
|
|
func (iter *Iterator) Left() bool {
|
|
if iter.cur.children[0] != nil {
|
|
iter.dir = 0
|
|
iter.cur = iter.cur.children[0]
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (iter *Iterator) Right() bool {
|
|
if iter.cur.children[1] != nil {
|
|
iter.dir = 0
|
|
iter.cur = iter.cur.children[1]
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (iter *Iterator) GetNext(cur *Node, idx int) *Node {
|
|
|
|
// iter := NewIterator(cur)
|
|
iter.SetNode(cur)
|
|
iter.curPushNextStack(iter.up)
|
|
iter.up = iter.getNextUp(iter.up)
|
|
|
|
for i := 0; i < idx; i++ {
|
|
|
|
if iter.tstack.Size() == 0 {
|
|
if iter.up == nil {
|
|
return nil
|
|
}
|
|
iter.tstack.Push(iter.up)
|
|
iter.up = iter.getNextUp(iter.up)
|
|
}
|
|
|
|
if v, ok := iter.tstack.Pop(); ok {
|
|
iter.cur = v.(*Node)
|
|
if i == idx-1 {
|
|
return iter.cur
|
|
}
|
|
iter.curPushNextStack(iter.cur)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
return cur
|
|
}
|
|
|
|
func (iter *Iterator) Next() (result bool) {
|
|
|
|
if iter.dir > -1 {
|
|
if iter.dir == 1 && iter.cur != nil {
|
|
iter.tstack.Clear()
|
|
iter.curPushNextStack(iter.cur)
|
|
iter.up = iter.getNextUp(iter.cur)
|
|
}
|
|
iter.dir = -1
|
|
}
|
|
|
|
if iter.tstack.Size() == 0 {
|
|
if iter.up == nil {
|
|
return false
|
|
}
|
|
iter.tstack.Push(iter.up)
|
|
iter.up = iter.getNextUp(iter.up)
|
|
}
|
|
|
|
if v, ok := iter.tstack.Pop(); ok {
|
|
iter.cur = v.(*Node)
|
|
iter.curPushNextStack(iter.cur)
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
func (iter *Iterator) GetPrev(cur *Node, idx int) *Node {
|
|
|
|
// iter := NewIterator(cur)
|
|
iter.SetNode(cur)
|
|
iter.curPushPrevStack(iter.up)
|
|
iter.up = iter.getPrevUp(iter.up)
|
|
|
|
for i := 0; i < idx; i++ {
|
|
|
|
if iter.tstack.Size() == 0 {
|
|
if iter.up == nil {
|
|
return nil
|
|
}
|
|
iter.tstack.Push(iter.up)
|
|
iter.up = iter.getPrevUp(iter.up)
|
|
}
|
|
|
|
if v, ok := iter.tstack.Pop(); ok {
|
|
iter.cur = v.(*Node)
|
|
if i == idx-1 {
|
|
return iter.cur
|
|
}
|
|
iter.curPushPrevStack(iter.cur)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
return cur
|
|
}
|
|
|
|
func (iter *Iterator) Prev() (result bool) {
|
|
|
|
if iter.dir < 1 { // 非 1(next 方向定义 -1 为 prev)
|
|
if iter.dir == -1 && iter.cur != nil { // 如果上次为prev方向, 则清空辅助计算的栈
|
|
iter.tstack.Clear()
|
|
iter.curPushPrevStack(iter.cur) // 把当前cur计算的逆向回朔
|
|
iter.up = iter.getPrevUp(iter.cur) // cur 寻找下个要计算up
|
|
}
|
|
iter.dir = 1
|
|
}
|
|
|
|
// 如果栈空了, 把up的递归计算入栈, 重新计算 下次的up值
|
|
if iter.tstack.Size() == 0 {
|
|
if iter.up == nil {
|
|
return false
|
|
}
|
|
iter.tstack.Push(iter.up)
|
|
iter.up = iter.getPrevUp(iter.up)
|
|
}
|
|
|
|
if v, ok := iter.tstack.Pop(); ok {
|
|
iter.cur = v.(*Node)
|
|
iter.curPushPrevStack(iter.cur)
|
|
return true
|
|
}
|
|
|
|
// 如果再次计算的栈为空, 则只能返回false
|
|
return false
|
|
}
|
|
|
|
func getRelationship(cur *Node) int {
|
|
if cur.parent.children[1] == cur {
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (iter *Iterator) getPrevUp(cur *Node) *Node {
|
|
for cur.parent != nil {
|
|
if getRelationship(cur) == 1 { // next 在 降序 小值. 如果child在右边, parent 比 child 小, parent才有效, 符合降序
|
|
return cur.parent
|
|
}
|
|
cur = cur.parent
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (iter *Iterator) curPushPrevStack(cur *Node) {
|
|
Prev := cur.children[0] // 当前的左然后向右找, 找到最大, 就是最接近cur 并且小于cur的值
|
|
|
|
if Prev != nil {
|
|
iter.tstack.Push(Prev)
|
|
for Prev.children[1] != nil {
|
|
Prev = Prev.children[1]
|
|
iter.tstack.Push(Prev) // 入栈 用于回溯
|
|
}
|
|
}
|
|
}
|
|
|
|
func (iter *Iterator) getNextUp(cur *Node) *Node {
|
|
for cur.parent != nil {
|
|
if getRelationship(cur) == 0 { // Prev 在 降序 大值. 如果child在左边, parent 比 child 大, parent才有效 , 符合降序
|
|
return cur.parent
|
|
}
|
|
cur = cur.parent
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (iter *Iterator) curPushNextStack(cur *Node) {
|
|
next := cur.children[1]
|
|
|
|
if next != nil {
|
|
iter.tstack.Push(next)
|
|
for next.children[0] != nil {
|
|
next = next.children[0]
|
|
iter.tstack.Push(next)
|
|
}
|
|
}
|
|
}
|