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:

Problem mit einfach verkettete Liste

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 09.06.2012, 22:16    Titel: Problem mit einfach verkettete Liste Antworten mit Zitat

Nachdem ich heute schon etliche Stunden damit verbracht habe 'banale' kleinigkeiten in meinem Code auszubügeln hänge ich grad mit einer, vermutlich simplen kleinigkeit, fest...

Ich habe ein schlichtes Type das in etwa so aussieht
Code:

Type irgendwas
   Werte as Integer
   Next as Irgendwas ptr
   Last as Irgendwas ptr
End Type


Das zusammenstellen und anhängen ist so recht einfach.
Nun will ich aber ein bestimmtest Element nach ganz nach hinten schieben, das heisst das Element davor (das ich gar nicht kenne) muss sein Next auf das übernächste (also das Next des gesuchten Elements) und das jetzt letzte sein Next auf das gesuchte element und alle müssen eben last auf das neue element setzen...

wie gesagt häng ich da grad ein bisschen fest...

Bin für jeden Tipp dankbar lächeln
_________________
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4704
Wohnort: ~/

BeitragVerfasst am: 09.06.2012, 23:00    Titel: Antworten mit Zitat

Wenn du es nicht doppelt verketten willst, bleibt dir nichts anderes übrig, als die Liste von Anfang an durchzulaufen, bis du auf das Element stößt, das auf das zu verschiebende zeigt.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Michael712
aka anfänger, programmierer


Anmeldungsdatum: 26.03.2005
Beiträge: 1593

BeitragVerfasst am: 09.06.2012, 23:04    Titel: Antworten mit Zitat

Das ist aber keine einfach verkettete, sondern eine doppelt verkettete Liste.

Dabei geht das dann so (node soll nach hinten verschoben werden)

Code:

Dim As irgendwas Ptr cur

cur = node;
node->last->next = cur->next
node->next->last = cur->last

cur->prev = liste->tail
cur->next = NULL
liste->tail->next = cur
liste->tail = cur


So sollte es eigentlich klappen, code ist jedoch ungeprüft.
Falls du doch eine einfach verkettete Liste verwenden solltest, dann musst du zuerst von vorne durch die Liste gehen, um das vorige Element zu kennen.
_________________
Code:
#include "signatur.bi"
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4704
Wohnort: ~/

BeitragVerfasst am: 09.06.2012, 23:50    Titel: Antworten mit Zitat

Ich hatte .last als letztes Element der gesamten Liste gelesen und nicht als vorheriges Element; auch wegen
Zitat:
das heisst das Element davor (das ich gar nicht kenne)

_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 10.06.2012, 00:17    Titel: Antworten mit Zitat

Ja mit 'last' war das letzte element gemeint, habs nun doch mal doppelt verkettet versucht...
habe also prev und next, das gefundene und immernoch last (letzte)

Wenn ich das gesuchte finde, habe ich im prinzip auch das davor, das nächste und das momentan letzte...

also hab ich nun mal eben, ohne weiter überprüfung ob es nun das erste oder letzte element ist ausgehend davon das es eines in der mitte ist folgenes gemacht wobei Temp das gesuchte bzw gefundene element ist das ans ende verschoben werden soll
Code:

                    Temp -> PrevWindow -> NextWindow = Temp -> NextWindow
                    Temp -> NextWindow -> PrevWindow = Temp -> PrevWindow
                    Temp -> LastWindow -> NextWindow = Temp


anschliessend lasse ich noch einmal durchlaufen und setze überall das letzte auf das neue letzte, also auf Temp

sollte meiner meinung nach funktionieren, aber nun verschwindet mir immer das 'gefundene' element (bei mir als fenster dargestellt sind diese dann einfach weg)

EDIT: Problem hat sich erledigt... hab vergessen dem neuen letzten element mitzuteilen das es selbst das letzte element ist... nu funzt alles (glaub ich)
_________________
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4704
Wohnort: ~/

BeitragVerfasst am: 10.06.2012, 01:41    Titel: Antworten mit Zitat

Das mit der Speicherung des letzten Elements - insb. das ständige Neuanpassen - ist doch ziemlich zeitaufwändig, das würde ich eher global speichern.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 10.06.2012, 02:45    Titel: Antworten mit Zitat

Funktionierte leider doch nur teilweise...

Wüsste auf anhieb nicht wie ich das global anders machen sollte...
Die ganze funktion wird eigentlich nur aufgerufen wenn geklickt und gefunden wurde... zum testen grad sehr häufig in der regel sollte ich aber wohl kaum mehr als 1-2 fenster nutzen.. empfand das als 'elegante' (sicherlich nicht beste) lösung

Dachte allerdings nicht das sowas triviales so nervig sein kann...
inzwischen wars kurzzeitig so das ein 'mittleres' Element problemlos nach hinten verschoben wurde, das letzte ist und bleibt das letzte also macht es auch keine probleme, das erste element will aber absolut nicht das was ich will, bei finden, klicken und neu sortieren verschwinden alle anderen elemente
_________________
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
XOR



Anmeldungsdatum: 23.07.2010
Beiträge: 161

BeitragVerfasst am: 10.06.2012, 10:00    Titel: Antworten mit Zitat

könnte es sein das du die variable in der das erste element gespeichert wird nicht überschreibst wenn ein element aus der liste nach vorne verschoben wird?

ansonsten hier noch ein schnell gecodeter code:
Code:
Type LinkList
   wert As Integer                        '' wert
   next As LinkList Ptr                     '' nextes listenelement
   prev As LinkList Ptr                     '' bevoriges listenelement
End Type

Declare Sub LinkListAdd(ByVal wert As Integer)
Declare Sub LinkListEnteryToTop(ByVal entery As LinkList Ptr)
Declare Sub LinkListEnteryToBottom(ByVal entery As LinkList Ptr)
Declare Sub LinkListDelete()
Declare Sub LinkListDeleteElement(ByVal entery As LinkList Ptr)
Declare Sub LinkListPrint()
Declare Function LinkListGetEnteryWithWert(ByVal wert As Integer) As LinkList Ptr

Dim Shared LinkListStart As LinkList Ptr   '' erstes listenelement
Dim Shared LinkListEnd As LinkList Ptr      '' letztes listenelement


LinkListAdd(1)
LinkListAdd(2)
LinkListAdd(3)

Print "Linklist"
LinkListPrint()
LinkListEnteryToTop(LinkListGetEnteryWithWert(1))
Print "Entery with wert 1 to Top"
LinkListPrint()
LinkListEnteryToTop(LinkListGetEnteryWithWert(2))
Print "Entery with wert 2 to Top"
LinkListPrint()
LinkListEnteryToBottom(LinkListGetEnteryWithWert(2))
Print "Entery with wert 2 to Bottom"
LinkListPrint()
LinkListDeleteElement(LinkListGetEnteryWithWert(3))
Print "Delete entery with wert 3"
LinkListPrint()
LinkListDelete()
Sleep

Sub LinkListAdd(ByVal wert As Integer)
   Dim As LinkList Ptr ll = New LinkList   '' neues entery
   ll->wert = wert
   ll->prev = 0                           '' da es an Top gesetzt wird ist prev = 0
   ll->Next = LinkListStart               '' das nächste element ist das bisher erste
   If(LinkListStart)Then                  '' wenn es schon andere listenelemente gibt
      LinkListStart->prev = ll            '' dann ist das vom nächsten das bevorige das neue
   Else
      LinkListEnd = ll                     '' ansonsten ist das das neue auch gleich das letzte
   EndIf
   LinkListStart = ll                     '' und das neue wird der anfang
End Sub

Sub LinkListEnteryToTop(ByVal entery As LinkList Ptr)
   If(entery = 0)Then                     '' wir wollen keine 0 pointer
      Exit Sub
   EndIf
   If(entery->next)Then                     '' wenn es ein nächstes element gibt
      entery->next->prev = entery->prev   '' diesem sagen das das neue bevor das bevor von entery ist
   Else
      LinkListEnd = entery->prev            '' ansonsten ist entery das letzte und das bevorige ist das neue letzte
   EndIf
   If(entery->prev)Then                     '' wenn es ein bevoriges element gibt
      entery->prev->next = entery->Next   '' diesem sagen das das neue nächste das nächste von entery ist
   Else
      LinkListStart = entery->next         '' ansonsten ist entery das erste und das nächste ist das neue erste
   EndIf
   entery->prev = 0                        '' da es an Top gesetzt wird ist prev = 0
   entery->next = LinkListStart            '' das nächste element ist das bisher erste
   If(LinkListStart)Then                  '' wenn es schon andere listenelemente gibt
      LinkListStart->prev = entery         '' dann ist das vom nächsten das bevorige das neue
   Else
      LinkListEnd = entery                  '' ansonsten ist das das neue auch gleich das letzte
   EndIf
   LinkListStart = entery                  '' und das neue wird der anfang
End Sub

Sub LinkListEnteryToBottom(ByVal entery As LinkList Ptr)
   If(entery = 0)Then                     '' wir wollen keine 0 pointer
      Exit Sub
   EndIf
   If(entery->next)Then                     '' wenn es ein nächstes element gibt
      entery->next->prev = entery->prev   '' diesem sagen das das neue bevor das bevor von entery ist
   Else
      LinkListEnd = entery->prev            '' ansonsten ist entery das letzte und das bevorige ist das neue letzte
   EndIf
   If(entery->prev)Then                     '' wenn es ein bevoriges element gibt
      entery->prev->next = entery->Next   '' diesem sagen das das neue nächste das nächste von entery ist
   Else
      LinkListStart = entery->next         '' ansonsten ist entery das erste und das nächste ist das neue erste
   EndIf
   entery->next = 0                        '' da es an Bottom gesetzt wird ist next = 0
   entery->prev = LinkListEnd               '' das bevorige element ist das bisher letzte
   If(LinkListEnd)Then                     '' wenn es schon andere listenelemente gibt
      LinkListEnd->next = entery            '' dann ist das vom bevorigen das nächste das neue
   Else
      LinkListStart = entery               '' ansonsten ist das das neue auch gleich das erste
   EndIf
   LinkListEnd = entery                     '' und das neue wird der schluss
End Sub

Sub LinkListDelete()
   Dim As LinkList Ptr entery, nextEntery
   entery = LinkListStart
   Do While(entery)                        '' solange entery <> 0
      nextEntery = entery->Next            '' das nächste zwischenspeichern
      Delete entery                        '' das element löschen
      entery = nextEntery
   Loop
   LinkListStart = 0
   LinkListEnd = 0
End Sub

Sub LinkListPrint()
   Dim As LinkList Ptr entery
   entery = LinkListStart
   Do While(entery)
      Print entery->wert;
      entery = entery->next
   Loop
   Print
End Sub

Function LinkListGetEnteryWithWert(ByVal wert As Integer) As LinkList Ptr
   Dim As LinkList Ptr entery
   entery = LinkListStart
   Do While(entery)
      If(entery->wert = wert)Then         '' solange suchen bis enertywert = wert
         Return entery
      EndIf
      entery = entery->next
   Loop
   Return 0
End Function

Sub LinkListDeleteElement(ByVal entery As LinkList Ptr)
   If(entery = 0)Then                     '' wir wollen keine 0 pointer
      Exit Sub
   EndIf
   If(entery->next)Then                     '' wenn es ein nächstes element gibt
      entery->next->prev = entery->prev   '' diesem sagen das das neue bevor das bevor von entery ist
   Else
      LinkListEnd = entery->prev            '' ansonsten ist entery das letzte und das bevorige ist das neue letzte
   EndIf
   If(entery->prev)Then                     '' wenn es ein bevoriges element gibt
      entery->prev->next = entery->Next   '' diesem sagen das das neue nächste das nächste von entery ist
   Else
      LinkListStart = entery->next         '' ansonsten ist entery das erste und das nächste ist das neue erste
   EndIf
   Delete entery
End Sub
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 10.06.2012, 13:30    Titel: Antworten mit Zitat

in Sub 'LinkListEnteryToBottom'
Code:
   LinkListEnd = entery->prev            '' ansonsten ist entery das letzte und das bevorige ist das neue letzte


Diese Zeile wollte mir einfach nicht in den Kopf und beim ersten Versuch natürlich gleich wieder weggelassen,
da ich immer von ausgegangen bin, WENN das Element bereits das letzte ist, dann muss ich doch sonst auch
nichts weiter machen, aber irgendwie gerät dann alles durcheinander... habs dann wiederwillen wieder rein
und siehe da, es funktioniert nun alles lächeln

Meine Fenster werden mir nun endlich richtig sortiert, ob das nun 2,3 oder 10 sind, nun liegen sie endlich richtig lächeln

vielen dank
_________________
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. 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