Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Stack Implementierung mit doppelt verketteten Listen

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Projektvorstellungen
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
UEZ



Anmeldungsdatum: 24.06.2016
Beiträge: 149
Wohnort: Opel Stadt

BeitragVerfasst am: 05.01.2019, 03:07    Titel: Stack Implementierung mit doppelt verketteten Listen Antworten mit Zitat

Ich hatte mich gefragt, wie man in FB doppelt verketteten Listen erstellen kann (hatte wohl ein Flashback zu meiner Studienzeit, die verdammt lange zurück liegt lächeln).

Hier das Resultat als ein Stack.
Code:

'Stack (LIFO) v2.1 implementation using double linked lists
'Coded by UEZ build 2026-08-09 beta


'payload only - no link fields, so nothing internal leaks to the caller
Type Vector
   As Single x, y, z
End Type

'list node
Type VectorNode
   As Vector v
   As VectorNode Ptr pp, pn
End Type

Type _Stack
   Declare Constructor()
   Declare Constructor(ByRef rhs As _Stack)
   Declare Destructor()
   Declare Operator Let(ByRef rhs As _Stack)
   Declare Sub Push(x As Single, y As Single, z As Single)
   Declare Function Pop() As Vector
   Declare Function PeekTop() As Vector
   Declare Function Get(iPos As UInteger) As Vector
   Declare Sub DeleteItem(iPos As UInteger)
   Declare Sub Clear()
   Declare Sub Print()
   Declare Function Count() As UInteger
   Declare Function IsEmpty() As Integer
   Private:
   Declare Function NodeAt(iPos As UInteger) As VectorNode Ptr
   Declare Sub CopyFrom(ByRef rhs As _Stack)
   As UInteger counter
   As VectorNode Ptr start, last
End Type

Constructor _Stack()
   This.counter = 0
   This.start = 0
   This.last = 0
End Constructor

Constructor _Stack(ByRef rhs As _Stack)
   This.counter = 0
   This.start = 0
   This.last = 0
   This.CopyFrom(rhs)
End Constructor

Operator _Stack.Let(ByRef rhs As _Stack)
   If @rhs = @This Then Exit Operator      'guard against self assignment
   This.Clear()
   This.CopyFrom(rhs)
End Operator

Destructor _Stack()
   This.Clear()
End Destructor

Sub _Stack.CopyFrom(ByRef rhs As _Stack)      'deep copy
   Dim As VectorNode Ptr p = rhs.start
   While p
      This.Push(p->v.x, p->v.y, p->v.z)
      p = p->pn
   Wend
End Sub

Sub _Stack.Clear()
   Dim As VectorNode Ptr n, p = This.start
   While p
      n = p->pn
      Delete p
      p = n
   Wend
   This.start = 0
   This.last = 0
   This.counter = 0
End Sub

Sub _Stack.Push(x As Single, y As Single, z As Single)
   Dim As VectorNode Ptr pv = New VectorNode
   If pv = 0 Then Exit Sub            'out of memory - counter stays valid
   pv->v.x = x
   pv->v.y = y
   pv->v.z = z
   pv->pp = 0                  'never rely on New returning zeroed memory
   pv->pn = 0
   If This.last Then
      This.last->pn = pv            'link previous entry to current one
      pv->pp = This.last
   Else
      This.start = pv            'first element
   End If
   This.last = pv
   This.counter += 1
End Sub

Function _Stack.Pop() As Vector
   Dim As Vector r = Type<Vector>(0, 0, 0)
   If This.last = 0 Then Return r         'empty stack
   Dim As VectorNode Ptr c = This.last
   r = c->v
   This.last = c->pp
   If This.last Then
      This.last->pn = 0
   Else
      This.start = 0               'stack is empty now
   End If
   Delete c
   This.counter -= 1
   Return r
End Function

Function _Stack.PeekTop() As Vector         'top element without removing it
   If This.last = 0 Then Return Type<Vector>(0, 0, 0)
   Return This.last->v
End Function

Function _Stack.NodeAt(iPos As UInteger) As VectorNode Ptr
   If iPos < 1 Or iPos > This.counter Then Return 0   'iPos = 0 used to loop forever
   Dim As VectorNode Ptr p
   If iPos <= This.counter \ 2 Then         'walk from the nearer end
      p = This.start
      For i As UInteger = 2 To iPos
         p = p->pn
      Next
   Else
      p = This.last
      For i As UInteger = This.counter To iPos + 1 Step -1
         p = p->pp
      Next
   End If
   Return p
End Function

Function _Stack.Get(iPos As UInteger) As Vector
   Dim As VectorNode Ptr p = This.NodeAt(iPos)
   If p = 0 Then Return Type<Vector>(0, 0, 0)
   Return p->v
End Function

Sub _Stack.DeleteItem(iPos As UInteger)
   Dim As VectorNode Ptr p = This.NodeAt(iPos)
   If p = 0 Then Exit Sub
   If p->pp Then               'unlink on both sides
      p->pp->pn = p->pn
   Else
      This.start = p->pn
   End If
   If p->pn Then
      p->pn->pp = p->pp
   Else
      This.last = p->pp
   End If
   Delete p
   This.counter -= 1
End Sub

Function _Stack.Count() As UInteger
   Return This.counter
End Function

Function _Stack.IsEmpty() As Integer
   Return (This.counter = 0)
End Function

Sub _Stack.Print()                  'print stack elements to console
   If This.start = 0 Then
      ? "Stack is empty"
      Exit Sub
   End If
   Dim As VectorNode Ptr p = This.start
   While p                     'null terminated - no reliance on counter
      ? p->v.x, p->v.y, p->v.z
      p = p->pn
   Wend
End Sub


'Example
Dim Stack As _Stack
Dim As Vector Test

For i As UByte = 1 To 10
   Stack.Push(i, i, i)
Next

? "Print all stack elements:"
Stack.Print()
?

'remove last added element from stack
Stack.Pop()

? "Removed last pushed element. Remaining elements:"
Stack.Print()
?

'get 5th element from stack
Test = Stack.Get(5)
? "Print 5th element from stack:"
? Test.x, Test.y, Test.z
?

Stack.DeleteItem(5)
? "Remaining stack elements after 5th element was deleted:"
Stack.Print()
?

'delete first element - links must stay intact
Stack.DeleteItem(1)
? "Remaining stack elements after first element was deleted:"
Stack.Print()
?

? "Elements count: " & Stack.Count()
?

'edge cases which crashed in v2.0
Test = Stack.Get(0)
? "Get(0) returns: " & Test.x & ", " & Test.y & ", " & Test.z
Stack.DeleteItem(0)
Test = Stack.Get(Stack.Count() + 1)
? "Get(count + 1) returns: " & Test.x & ", " & Test.y & ", " & Test.z
?

'copying a stack is safe now
Dim As _Stack Stack2 = Stack
Stack2.Push(99, 99, 99)
? "Copy has " & Stack2.Count() & " elements, original has " & Stack.Count()
?

'empty the stack completely
While Not Stack.IsEmpty()
   Stack.Pop()
Wend
? "After popping everything:"
Stack.Print()
? "Pop() on empty stack returns: " & Stack.Pop().x

Sleep


Sollte funktionieren.
_________________
Gruß
UEZ


Zuletzt bearbeitet von UEZ am 19.08.2026, 22:34, insgesamt 4-mal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1297
Wohnort: Ruhrpott

BeitragVerfasst am: 05.01.2019, 16:21    Titel: Antworten mit Zitat

Eine Anwendung mit einer doppelt verketteten Liste hatten wir hier vor ein paar Jahren schon mal, als Baumstruktur (Type tNode) mit einem Eltern- und einer variablen Anzahl von Kindknoten. Hier der dazugehörige Thread.

Vielleicht sind ja einige (zusätzliche) Anregungen für dich dabei. lächeln

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
UEZ



Anmeldungsdatum: 24.06.2016
Beiträge: 149
Wohnort: Opel Stadt

BeitragVerfasst am: 05.01.2019, 19:33    Titel: Antworten mit Zitat

Danke @grindstone für dein Feedback. happy Ich werde mir den Thread durchschauen.

Ich hatte nach verkettete Listen gesucht, aber nichts gefunden, was in diese Richtung geht. ¯\_(ツ)_/¯

Wie auch immer, dann habe ich das Rad neu erfunden... lächeln
_________________
Gruß
UEZ
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1841
Wohnort: [JN58JR]

BeitragVerfasst am: 15.01.2019, 12:36    Titel: Antworten mit Zitat

@UEZ ... https://www.freebasic-portal.de/porticula/linkedlistbi-847.html


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Projektvorstellungen Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz