Sortierte Listen Einführung Einfügen Löschen

Informatik in Q1:
Sortierte Listen
Gierhardt
Einführung
Die Elemente einer sortierten Liste sind ähnlich angeordnet wie in einem Array. Allerdings
ergeben sich bei Strukturierung mit einem Array verschiedene Probleme:
• Beim Einfügen eines Elementes müssen alle nachfolgenden Elemente um eine Stelle
verschoben werden.
• Beim Löschen eines Elementes muss die Datenstruktur umgekehrt entsprechend
angepasst werden.
• Die Liste kann in einem Array nicht dynamisch wachsen und schrumpfen.
Die einfachste Form einer sortierten dynamischen Liste besteht aus Knoten mit Inhalt
und einem Verweis auf den nachfolgenden Knoten.
Diese Strukturierung ist durch Verweise auf den jeweiligen Vorgänger erweiterbar. Dann
erhält man eine doppelt verkettete Liste.
Einfügen
Beim Einfügen in eine sortierte Liste ergeben sich verschiedene Fälle, die beachtet werden
müssen:
1. Es wird in eine leere Liste eingefügt.
2. Es wird vor dem ersten Element der Liste eingefügt.
3. Es wird zwischen zwei Elementen eingefügt.
4. Es wird am Ende der Liste eingefügt.
Zeichne für jeden der vier Fälle eine Graphik mit Zeigern, die die Operationen der im
Anhang angegebenen Methode insert darstellt. Zeige damit die Korrektheit der Methode
für alle Fälle.
Löschen
Beim Löschen in einer sortierten Liste ergeben sich verschiedene Fälle, die beachtet
werden müssen:
1. Es wird versucht, in einer leeren Liste zu löschen.
2. Es wird das erste Element der Liste gelöscht.
3. Es wird zwischen zwei Elementen gelöscht.
1
4. Es wird am Ende der Liste gelöscht.
5. Es wird versucht, ein nicht vorhandenes Element zu löschen.
Zeichne für jeden der fünf Fälle eine Graphik mit Zeigern, die die Operationen der im
Anhang angegebenen Methode delete darstellt. Zeige damit die Korrektheit der Methode
für alle Fälle.
Suchen
Schreibe eine Methode, die feststellt, ob ein bestimmtes Element in der Liste vorhanden
ist.
Aufgabe
Schreibe geeignete Klassen für eine Telephonnummernliste (mit Namen). Informiere dich
dazu über geeignete Vergleichsoperationen für Strings und schreibe eine Methode, die als
booleschen Funktionswert angibt, ob ein String kleiner als ein anderer ist oder nicht.
Schreibe ein Hauptprogramm zum Testen der Klassen mit einer Menüstruktur zum
Einfügen, Löschen und Ansehen der Einträge.
Anhang
1
2
class ZahlenListenTest
{ ZahlenListe l i s t e ;
3
4
5
6
7
public Z a h l e n L i s t e n T e s t ( )
{ l i s t e = new Z a h l e n L i s t e ( ) ;
action ( ) ;
}
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public void a c t i o n ( )
{ l i s t e . gibAllesAus ( ) ;
liste . insert (3);
liste
liste . insert (7);
liste
liste . insert (12);
liste
liste . insert (2);
liste
liste . insert (8);
liste
liste . insert (13);
liste
l i s t e . delete (7);
liste
l i s t e . delete (2);
liste
l i s t e . delete (3);
liste
l i s t e . delete (12);
liste
l i s t e . delete (12);
liste
l i s t e . delete (13);
liste
l i s t e . delete (8);
liste
}
} // c l a s s Z a h l e n L i s t e n T e s t
. gibAllesAus
. gibAllesAus
. gibAllesAus
. gibAllesAus
. gibAllesAus
. gibAllesAus
. gibAllesAus
. gibAllesAus
. gibAllesAus
. gibAllesAus
. gibAllesAus
. gibAllesAus
. gibAllesAus
2
();
();
();
();
();
( ) ; // j e t z t l o e s c h e n
();
();
();
();
();
();
();
1
2
3
4
5
public c l a s s Knoten
{
private int wert ; // S t a r k v e r e i n f a c h t e r r Knoten !
// h i e r werden s p a e t e r s t a t t Zahlen
// b e l i e b i g e O b j e k t e v e r w a l t e t
6
7
private Knoten n a c h f o l g e r ;
8
9
10
11
12
public Knoten ( int z a h l , Knoten next )
{ wert = z a h l ;
n a c h f o l g e r = next ;
}
13
14
15
public void s e t N a c h f o l g e r ( Knoten next )
{ n a c h f o l g e r = next ; }
16
17
18
public Knoten g e t N a c h f o l g e r ( )
{ return n a c h f o l g e r ; }
19
20
21
public void setWert ( int z a h l )
{ wert = z a h l ; }
22
23
24
public int getWert ( )
{ return wert ; }
25
26
} // c l a s s Knoten
3
1
2
public c l a s s Z a h l e n L i s t e
{ private Knoten e r s t e r ;
3
4
5
public Z a h l e n L i s t e ( )
{ e r s t e r = null ; }
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void i n s e r t ( int z a h l )
{ Knoten l a u f
= erster ;
Knoten v o r h e r = null ;
while ( l a u f != null && z a h l >l a u f . getWert ( ) )
{ vorher = l a u f ;
lauf
= lauf . getNachfolger ( ) ;
}
// E i n f u e g e s t e l l e od er L i s t e n e n d e g e f u n d e n
Knoten neu = new Knoten ( z a h l , null ) ;
neu . s e t N a c h f o l g e r ( l a u f ) ;
// nach vorne " v e r k n o t e n "
i f ( l a u f==e r s t e r )
e r s t e r = neu ;
e l s e v o r h e r . s e t N a c h f o l g e r ( neu ) ; // von h i n t e n " v e r k n o t e n "
} // i n s e r t
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public void d e l e t e ( int z a h l )
{ Knoten l a u f
= erster ;
Knoten v o r h e r = null ;
while ( l a u f != null && z a h l != l a u f . getWert ( ) ) // k u r z e Auswertung
{ vorher = l a u f ;
lauf
= lauf . getNachfolger ( ) ;
}
// Ende d e r S c h l e i f e , wenn z a h l=l a u f . getWert ( ) ode r l a u f==n u l l
i f ( l a u f != null )
i f ( l a u f==e r s t e r )
erster = lauf . getNachfolger ( ) ;
else vorher . setNachfolger ( l a u f . getNachfolger ( ) ) ;
} // d e l e t e
35
36
37
38
39
40
41
42
43
44
45
46
47
public void g i b A l l e s A u s ( )
{ Knoten l a u f = e r s t e r ;
i f ( l a u f==null )
{ System . out . p r i n t l n ( " L i s t e ␣ i s t ␣ l e e r . " ) ;
return ;
}
while ( l a u f != null )
{ System . out . p r i n t ( l a u f . getWert ( ) + " ␣ ␣ " ) ;
lauf = lauf . getNachfolger ( ) ;
}
System . out . p r i n t l n ( ) ;
} // g i b A l l e s A u s
48
49
} // c l a s s Z a h l e n L i s t e
4