This is an idea for using pages placing values. Fast adding to both ends. Using index is easy because although we move from starting page to each page using a pointer, we know from the number of used items in the node if is the proper node which have the result from our index. Bigger page widrh faster, but bigger page for removing a value is slower.
' super stack v0.1
' st=SuperStack(12) ' number is the page length
' stack grows using nodes, each node has an array v()
' Data, Push, Peek(index from 1), Remove index from 1, Pop or Pop(), length
' When we pop values the nodes desgtroyed when not have values.
' Also when we delete items then nodes deleted if there are no values from v() in use
' data append to the end of stack (FIFO)
' push push to the start of stack (LIFO)
' pop always read from start - and remove item
' peek read at index
' you can combine peek and push to do OVER (like the statement of M2000 for stacks)
' yoy can combine peek, remove, push to do SHIFT (like the statement of M2000 for stacks)
' to do:
' insert at index ' so combined with peek, insert, remove you do the SHIFTBACK (like the statement of M2000 for stacks)
' split from index to a second stack
' merge two stacks
class superstack {
private:
Class Node {
{z=pointer()
Read p as integer=64, z, m as boolean=false
if m then p1=0 else p1=p
}
dim v(p)
integer level=p1
Integer low=-1
pRead=z
}
CurNode=Pointer()
pLast=Pointer()
pFirst=Pointer()
long counter
integer pagelen=64, ex=2
public:
Module Data {
if .pLast is type Null then
.pLast<=Pointer(.Node(.PageLen,,true))
.pFirst<=.pLast
end if
boolean NeedOne
thisnew=pointer()
while not empty
for .pLast, this {
while not empty
.low++
if .low=len(.v()) then
NeedOne=true
thisnew<=Pointer(..Node(len(.v())*..ex,,true)) '..pagelen
.pRead<=thisnew
exit
else
read .v(.low)
..counter++
end if
end while
}
if NeedOne then
.pLast<=thisnew:thisnew=pointer()
NeedOne~
end if
end while
}
Module Push {
Long many=stack.size
Boolean NeedOne
if .curNode is type Null Then
.curNode<=Pointer(.Node(.PageLen))
end if
while not empty
for .curNode {
while not empty
if .level=0 then NeedOne=true: Exit
.level--
read .v(.level)
end while
}
if NeedOne then
.CurNode<=Pointer(.Node(.pagelen, .CurNode))
NeedOne~
end if
end while
.counter+=many
}
Function Peek(where as long=1) {
if where<1 then Error "index too low"
if .CurNode is type Null and .pFirst is type Null then Error "Empty Stack"
if .counter=0 then Error "Empty Stack"
boolean newpage=true
z=pointer()
if .CurNode is type Null then
Usethis=.pFirst
else
UseThis=.CurNode
end if
newpage=false
onetime=true
while where>0 and useThis is type Node
for useThis, this {
lim=len(.v())
if .level=lim then
newpage=true
z=.pRead
if z is type null then
if onetime then z=..pfirst:onetime=false
end if
exit
end if
st=.level
w=len(.v())-st
if w<where then
newpage=true
where-=w
z=.pRead
if z is type null then
if onetime then z=..pfirst:onetime=false
end if
else
=.v(st+where-1)
where=0
end if
}
if newpage then
useThis=Z:Z=pointer()
newpage~
end if
end while
}
Module Remove (where as long=1) {
if .CurNode is type Null and .pFirst is type Null then Error "Empty Stack"
if .counter=0 then Error "Empty Stack"
boolean newpage=true
z=pointer()
if .CurNode is type Null then
Usethis=.pFirst
else
UseThis=.CurNode
end if
newpage=false
onetime=true
oldPointer=Pointer()
boolean removelastnode
while where>0 and useThis is type Node
for useThis, this {
lim=len(.v())
if .level=lim then
newpage=true
z=.pRead
if z is type null then
if onetime then z=..pfirst:onetime=false
end if
exit
end if
st=.level
w=len(.v())-st
if w<where then
newpage=true:
where-=w
z=.pRead
if z is type null then
if onetime then
z=..pfirst
onetime=false
end if
end if
else
uplim=st+where-1
if .level<uplim then
stock .v(.level) keep uplim-.level, .v(.level+1)
.level++
else
.v(st+where-1)=0
.level++
end if
..counter--
where=0
if .level>=len(.v()) then
z=.pRead
if z is type null then
if onetime then z=..pfirst:onetime=false
end if
removelastnode=true
end if
end if
}
if removelastnode then
newpage=false
if oldPointer is type null then
.CurNode<=z
else
oldPointer=>pRead=z
end if
else.if newpage then
oldPointer=useThis
useThis=Z:Z=pointer()
newpage~
end if
end while
}
Group Pop {
value {
link parent Pop() to p()
=p()
}
}
Function Pop() {
if .CurNode is type Null and .pFirst is type Null then Error "Empty Stack"
if .counter=0 then Error "Empty Stack"
boolean newpage=true, cur
z=pointer()
variant cl
if .CurNode is type Null then
Usethis=.pFirst
.pFirst<=Pointer()
else
UseThis=.CurNode
cur=true
.CurNode<=Pointer()
end if
onetime=true
while newpage and useThis is type Node
for useThis, this {
lim=len(.v())
if .level=lim then
// pen #ff2277 {print "<<>>",}
z=.pRead
if z is type null then
if onetime then z=..pfirst:onetime=false
end if
else
=.v(.level)
swap .v(.level), cl
cl=0
.level++
..counter--
newpage~
end if
}
if newpage then
useThis<=Z:Z=pointer()
Pen color(random(128,255),random(128,255),random(128,255))
end if
end While
if .counter=0 then
.curNode<=pointer()
.pFirst<=pointer()
.pLast<=pointer()
else.if cur then
.curNode<=UseThis
else
.pFirst<=UseThis
end if
}
Property Length {
value {
link parent counter to c
value=c
}
}=0&
class:
module superstack(.pagelen){
}
}
flush
a=superstack(12)
push(90)
popall()
push(45,45)
data(45)
// peekAll(-1)
Pen 14 {print "Remove from 1 x 60 times:"}
pen 15 {
for i=1 to 45
print i, a.peek(i)
a.remove i
pen 11 {peekall(i+1)}
// push key$ : drop
next
print
}
peekAll()
popall()
sub peekAll(k=-1)
print ">>>>>>>>>>> peek all"
for i=1 to a.length
if k=i then
pen 12 { print a.peek(i),}
else
print a.peek(i),
end if
next
print
end sub
sub data(many, toBase=1)
for k=many+toBase-1 to toBase
data k*10
next
print "data"
a.data
end sub
sub push(many, frombase=1)
for k=frombase to many+frombase-1
data k*10
next
print "push"
a.push
end sub
sub popall()
local i=1
print ">>>>>>>>>>> pop all"
while a.length>0
print a.pop,
i++
end while
print
end sub
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου
You can feel free to write any suggestion, or idea on the subject.