Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 09.06.2012, 22:16 Titel: Problem mit einfach verkettete Liste |
|
|
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  _________________
 |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 09.06.2012, 23:00 Titel: |
|
|
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 |
|
 |
Michael712 aka anfänger, programmierer
Anmeldungsdatum: 26.03.2005 Beiträge: 1593
|
Verfasst am: 09.06.2012, 23:04 Titel: |
|
|
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 |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 09.06.2012, 23:50 Titel: |
|
|
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 |
|
 |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 10.06.2012, 00:17 Titel: |
|
|
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 |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 10.06.2012, 01:41 Titel: |
|
|
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 |
|
 |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 10.06.2012, 02:45 Titel: |
|
|
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 |
|
 |
XOR
Anmeldungsdatum: 23.07.2010 Beiträge: 161
|
Verfasst am: 10.06.2012, 10:00 Titel: |
|
|
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 |
|
 |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 10.06.2012, 13:30 Titel: |
|
|
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
Meine Fenster werden mir nun endlich richtig sortiert, ob das nun 2,3 oder 10 sind, nun liegen sie endlich richtig
vielen dank _________________
 |
|
Nach oben |
|
 |
|