a
1
SS23/Algorithmen und Datenstrukturen/UEB01.md
Normal file
@@ -0,0 +1 @@
|
||||

|
||||
33
SS23/Algorithmen und Datenstrukturen/UEB02.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# 1
|
||||
## proz1
|
||||
- 200
|
||||
- 2n
|
||||
- O(n)
|
||||
## proz2
|
||||
- 10000
|
||||
- n^2
|
||||
- O(n^2)
|
||||
## proz3
|
||||
- 10
|
||||
- sqrt(n
|
||||
- O(sqrt(n)))
|
||||
## proz4
|
||||
- 100 * 9999 * 99 = 98990100
|
||||
- 100 * (n^2-1) * (n-1)
|
||||
- O(n^3)
|
||||
## proz5
|
||||
- 5050
|
||||
- sigma 1-> n (n*(n+1))/2
|
||||
- O(n^2)
|
||||
## proz6
|
||||
- 7
|
||||
- log(n) + 1
|
||||
- O(log(n))
|
||||
# 2
|
||||
## 1
|
||||
- O(n * log2(n))
|
||||
## 2
|
||||
- O(2^n)
|
||||
## 3
|
||||
- O(n^2)
|
||||
|
||||
BIN
SS23/Algorithmen und Datenstrukturen/UEB02.pdf
Normal file
@@ -0,0 +1,6 @@
|
||||
public class Main{
|
||||
public static void main(String[] args) {
|
||||
Link mittleresElement = new Link(T,"Test");
|
||||
|
||||
}
|
||||
}
|
||||
29
SS23/AuD/.gitignore
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
### IntelliJ IDEA ###
|
||||
out/
|
||||
!**/src/main/**/out/
|
||||
!**/src/test/**/out/
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
bin/
|
||||
!**/src/main/**/bin/
|
||||
!**/src/test/**/bin/
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
||||
8
SS23/AuD/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
6
SS23/AuD/.idea/misc.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_20" default="true" project-jdk-name="20" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
8
SS23/AuD/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/untitled.iml" filepath="$PROJECT_DIR$/untitled.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
SS23/AuD/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
11
SS23/AuD/AuD.iml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
10
SS23/AuD/src/UEB01/Main.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package UEB01;
|
||||
|
||||
// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
|
||||
// then press Enter. You can now see whitespace characters in your code.
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
21
SS23/AuD/src/UEB01/StopUhr.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package UEB01;
|
||||
|
||||
public class StopUhr
|
||||
{
|
||||
private long startTime, stopTime;
|
||||
|
||||
public void start()
|
||||
{
|
||||
startTime = System.nanoTime();
|
||||
}
|
||||
|
||||
public void stop()
|
||||
{
|
||||
stopTime = System.nanoTime();
|
||||
}
|
||||
|
||||
public long getDuration()
|
||||
{
|
||||
return stopTime - startTime;
|
||||
}
|
||||
}
|
||||
69
SS23/AuD/src/UEB01/Zeitmessung.java
Normal file
@@ -0,0 +1,69 @@
|
||||
package UEB01;
|
||||
|
||||
public class Zeitmessung
|
||||
{
|
||||
static int tuWasCounter = 0;
|
||||
private static double tuwas()
|
||||
{
|
||||
tuWasCounter++;
|
||||
return Math.random();
|
||||
}
|
||||
|
||||
// Linear
|
||||
public static double func1(int n)
|
||||
{
|
||||
double summe = 0;
|
||||
|
||||
for (int a = 0; a < n; a++)
|
||||
summe += tuwas();
|
||||
|
||||
return summe;
|
||||
}
|
||||
|
||||
// Quadratisch
|
||||
public static double func2(int n)
|
||||
{
|
||||
double summe = 0;
|
||||
|
||||
for (int a = 0; a < n; a++)
|
||||
for(int b = 0; b < n; b++)
|
||||
summe += tuwas();
|
||||
|
||||
return summe;
|
||||
}
|
||||
|
||||
// log2(n)
|
||||
public static double func6(int n)
|
||||
{
|
||||
double summe = 0;
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
summe += tuwas();
|
||||
n /= 2;
|
||||
}
|
||||
|
||||
return summe;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
StopUhr uhr = new StopUhr();
|
||||
final int n = 100000;
|
||||
tuWasCounter = 0;
|
||||
uhr.start();
|
||||
func1(n);
|
||||
uhr.stop();
|
||||
System.out.println("func1 "+"n="+n+" Zeit:"+uhr.getDuration()+" tuWasCounter:" + tuWasCounter);
|
||||
tuWasCounter = 0;
|
||||
uhr.start();
|
||||
func2(n);
|
||||
uhr.stop();
|
||||
System.out.println("func2 "+"n="+n+" Zeit:"+uhr.getDuration()+" tuWasCounter:" + tuWasCounter);
|
||||
tuWasCounter = 0;
|
||||
uhr.start();
|
||||
func6(n);
|
||||
uhr.stop();
|
||||
System.out.println("func6 "+"n="+n+" Zeit:"+uhr.getDuration()+" tuWasCounter:" + tuWasCounter);
|
||||
}
|
||||
}
|
||||
20
SS23/AuD/src/UEB03/Link.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package UEB03;
|
||||
|
||||
public class Link<T>
|
||||
{
|
||||
public T daten;
|
||||
public Link<T> naechster;
|
||||
|
||||
public Link(T daten, Link<T> naechster)
|
||||
{
|
||||
assert(daten != null);
|
||||
|
||||
this.daten = daten;
|
||||
this.naechster = naechster;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return daten.toString();
|
||||
}
|
||||
}
|
||||
275
SS23/AuD/src/UEB03/Liste.java
Normal file
@@ -0,0 +1,275 @@
|
||||
package UEB03;
|
||||
|
||||
public class Liste<T>
|
||||
{
|
||||
protected Link<T> anfang;
|
||||
protected Link<T> ende;
|
||||
|
||||
public Liste()
|
||||
{
|
||||
// Leere Liste: alle Zeiger sind null (Standardwerte)
|
||||
}
|
||||
|
||||
// Einfachster Fall und gleichzeitig Sonderfall:
|
||||
// Element am Anfang einf<6E>gen
|
||||
public void einfuegen(final T daten)
|
||||
{
|
||||
// Funktioniert immer
|
||||
anfang = new Link<T>(daten, anfang);
|
||||
|
||||
// Bei einer leeren Liste muss auch ende gesetzt werden
|
||||
if (ende == null)
|
||||
ende = anfang;
|
||||
}
|
||||
|
||||
// Einfachster Fall und gleichzeitig Sonderfall:
|
||||
// Element am Anfang entfernen
|
||||
public T entfernen()
|
||||
{
|
||||
T opfer = null;
|
||||
|
||||
// Clowns k<>nnten diese Methode bei leerer Liste aufrufen
|
||||
if (!istLeer())
|
||||
{
|
||||
// Bei einer Liste mit nur noch einem Element muss
|
||||
// auch ende gel<65>scht werden
|
||||
if (anfang == ende)
|
||||
ende = null;
|
||||
|
||||
opfer = anfang.daten;
|
||||
anfang = anfang.naechster;
|
||||
}
|
||||
|
||||
return opfer;
|
||||
}
|
||||
|
||||
// Einfacher Fall: Anf<6E>gen am Ende der Liste
|
||||
public void anfuegen(final T daten)
|
||||
{
|
||||
// Neuen Link anlegen
|
||||
Link<T> neu = new Link<T>(daten, null);
|
||||
|
||||
// Wenn die Liste leer ist, m<>ssen anfang und ende gesetzt werden
|
||||
if (istLeer())
|
||||
{
|
||||
// Neuen Link als anfang der Liste
|
||||
anfang = ende = neu;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Anf<6E>gen des Elements an das bisherige ende
|
||||
ende = ende.naechster = neu;
|
||||
}
|
||||
}
|
||||
|
||||
// EINF<4E>GEN AN EINER BESTIMMTEN STELLE
|
||||
// Der Programmcode ist so gestaltet, dass er fehlerhafte Eingaben
|
||||
// (z.B. eine negative oder zu hohe Position) elegant verarbeitet
|
||||
// ohne abzust<73>rzen.
|
||||
public void einfuegen(final T daten, int position)
|
||||
{
|
||||
// Wenn die Liste leer oder die Position 0 ist, entspricht dies
|
||||
// einem Einf<6E>gen am Anfang
|
||||
if (istLeer() || (position <= 0))
|
||||
{
|
||||
einfuegen(daten);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// VORG<52>NGER ZUR POSITION FINDEN
|
||||
// Dessen Vorg<72>nger muss es geben: lediglich bei einer leeren
|
||||
// Liste oder f<>r position==0 gibt es keinen. Genau diese F<>lle
|
||||
// wurden aber oben bereits behandelt! Wird eine zu hohe position
|
||||
// <20>bergeben, wird automatisch das letzte Element zum Vorg<72>nger.
|
||||
Link<T> vorgaenger = anfang;
|
||||
|
||||
while ((--position > 0) && (vorgaenger.naechster != null))
|
||||
vorgaenger = vorgaenger.naechster;
|
||||
|
||||
// Neues Element erzeugen
|
||||
vorgaenger.naechster = new Link<T>(daten, vorgaenger.naechster);
|
||||
|
||||
// Beim Einf<6E>gen als letztes Element muss auch ende gesetzt werden
|
||||
if (vorgaenger == ende)
|
||||
ende = vorgaenger.naechster;
|
||||
}
|
||||
|
||||
public T entfernen(int position)
|
||||
{
|
||||
// Wenn die Liste leer oder die position < 0 ist, wird kein Element
|
||||
// entfernt
|
||||
if (istLeer() || (position < 0))
|
||||
return null;
|
||||
|
||||
// Wenn die position 0 ist, wird am Anfang der Liste gel<65>scht
|
||||
if (position == 0)
|
||||
return entfernen();
|
||||
|
||||
// VORG<52>NGER ZUR POSITION FINDEN
|
||||
// Bei einer leeren Liste oder f<>r position==0 gibt es keinen Vorg<72>nger;
|
||||
// genau diese F<>lle wurden oben bereits behandelt. Es gibt aber auch
|
||||
// keinen Vorg<72>ner, wenn position zu gro<72> ist! In diesem Fall wird das
|
||||
// letzte Element NICHT Vorg<72>nger, damit nur tats<74>chlich existierende
|
||||
// Elemente aus der Liste entfernt werden.
|
||||
Link<T> vorgaenger = anfang;
|
||||
|
||||
while ((--position > 0) && (vorgaenger != null))
|
||||
vorgaenger = vorgaenger.naechster;
|
||||
|
||||
// Gibt es ein Element zum l<>schen?
|
||||
if ((vorgaenger == null) || (vorgaenger.naechster == null))
|
||||
return null;
|
||||
|
||||
final T opfer = vorgaenger.naechster.daten;
|
||||
|
||||
// Element l<>schen und ggf. ende anpassen beim L<>schen des letzten
|
||||
// Listen-Elements
|
||||
if ((vorgaenger.naechster = vorgaenger.naechster.naechster) == null)
|
||||
ende = vorgaenger;
|
||||
|
||||
return opfer;
|
||||
}
|
||||
|
||||
// Liefert die Position eines bestimmten Elements oder -1 zur<75>ck.
|
||||
// Existiert ein Element mehrfach, wird die Position des ersten Vorkommens
|
||||
// zur<75>ckgegeben.
|
||||
public int suchen(final T daten)
|
||||
{
|
||||
// Liste leer?
|
||||
if (istLeer())
|
||||
return -1;
|
||||
|
||||
Link<T> zeiger = anfang;
|
||||
int position = 0;
|
||||
|
||||
// Abfrage auf Gleichheit ist m<>glich mit equals (Operation von der Klasse Object)
|
||||
while ((zeiger != null) && !zeiger.daten.equals(daten))
|
||||
{
|
||||
position++;
|
||||
zeiger = zeiger.naechster;
|
||||
}
|
||||
|
||||
return (zeiger == null) ? -1 : position;
|
||||
}
|
||||
|
||||
public ListeIterator<T> iterator()
|
||||
{
|
||||
return new ListeIterator<T>(anfang, ende);
|
||||
}
|
||||
|
||||
// Pr<50>fen, ob Liste leer ist
|
||||
public boolean istLeer()
|
||||
{
|
||||
return anfang==null;
|
||||
}
|
||||
|
||||
public void verketten(Liste<T> zweiteListe)
|
||||
{
|
||||
assert(zweiteListe != null);
|
||||
|
||||
ende.naechster = zweiteListe.anfang;
|
||||
ende= zweiteListe.ende;
|
||||
zweiteListe.anfang = null;
|
||||
zweiteListe.ende = null;
|
||||
|
||||
}
|
||||
|
||||
public int entferneWerte(final T opfer)
|
||||
{
|
||||
int anzGeloeschte = 0;
|
||||
Link<T> currentLink = anfang;
|
||||
Link<T> before = new Link<T>(null,null);
|
||||
|
||||
while ((currentLink != null))
|
||||
{
|
||||
System.out.println("yote");
|
||||
if(currentLink.daten.equals(opfer)){
|
||||
if(currentLink == anfang){
|
||||
anfang = currentLink.naechster;
|
||||
System.out.println("anfang");
|
||||
}else if(currentLink == ende) {
|
||||
before.naechster = null;
|
||||
ende = before;
|
||||
System.out.println("ende");
|
||||
}else {
|
||||
before.naechster = currentLink.naechster;
|
||||
System.out.println("mitte");
|
||||
}
|
||||
anzGeloeschte++;
|
||||
}
|
||||
before = currentLink;
|
||||
currentLink = currentLink.naechster;
|
||||
|
||||
|
||||
}
|
||||
return anzGeloeschte;
|
||||
}
|
||||
|
||||
public int entferneWerte2(final T opfer)
|
||||
{
|
||||
int anzGeloeschte = 0;
|
||||
Link<T> currentLink = anfang;
|
||||
Link<T> before = new Link<T>(null,null);
|
||||
|
||||
while ((currentLink != null))
|
||||
{
|
||||
System.out.println("yote");
|
||||
if(currentLink.daten.equals(opfer)){
|
||||
if(currentLink == anfang){
|
||||
anfang = currentLink.naechster;
|
||||
System.out.println("anfang");
|
||||
}else if(currentLink == ende) {
|
||||
before.naechster = null;
|
||||
ende = before;
|
||||
System.out.println("ende");
|
||||
}else {
|
||||
before.naechster = currentLink.naechster;
|
||||
System.out.println("mitte");
|
||||
}
|
||||
anzGeloeschte++;
|
||||
}
|
||||
before = currentLink;
|
||||
currentLink = currentLink.naechster;
|
||||
|
||||
|
||||
}
|
||||
return anzGeloeschte;
|
||||
}
|
||||
|
||||
public T delete(int position)
|
||||
{
|
||||
// Wenn die Liste leer oder die position < 0 ist, wird kein Element
|
||||
// entfernt
|
||||
if (istLeer() || (position < 0))
|
||||
return null;
|
||||
|
||||
// Wenn die position 0 ist, wird am Anfang der Liste gel<65>scht
|
||||
if (position == 0)
|
||||
return entfernen();
|
||||
|
||||
// VORG<52>NGER ZUR POSITION FINDEN
|
||||
// Bei einer leeren Liste oder f<>r position==0 gibt es keinen Vorg<72>nger;
|
||||
// genau diese F<>lle wurden oben bereits behandelt. Es gibt aber auch
|
||||
// keinen Vorg<72>ner, wenn position zu gro<72> ist! In diesem Fall wird das
|
||||
// letzte Element NICHT Vorg<72>nger, damit nur tats<74>chlich existierende
|
||||
// Elemente aus der Liste entfernt werden.
|
||||
Link<T> vorgaenger = anfang;
|
||||
|
||||
while ((--position > 0) && (vorgaenger != null))
|
||||
vorgaenger = vorgaenger.naechster;
|
||||
|
||||
// Gibt es ein Element zum l<>schen?
|
||||
if ((vorgaenger == null) || (vorgaenger.naechster == null))
|
||||
return null;
|
||||
|
||||
final T opfer = vorgaenger.naechster.daten;
|
||||
|
||||
// Element l<>schen und ggf. ende anpassen beim L<>schen des letzten
|
||||
// Listen-Elements
|
||||
if ((vorgaenger.naechster = vorgaenger.naechster.naechster) == null)
|
||||
ende = vorgaenger;
|
||||
|
||||
return opfer;
|
||||
}
|
||||
}
|
||||
47
SS23/AuD/src/UEB03/ListeCanvas.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package UEB03;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class ListeCanvas extends Canvas
|
||||
{
|
||||
private Liste eineListe;
|
||||
|
||||
public void zeichneNeu(Liste eineListe)
|
||||
{
|
||||
this.eineListe = eineListe;
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
ListeIterator it = eineListe.iterator();
|
||||
int x = 0;
|
||||
int y = 30;
|
||||
int position = 0;
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
g.setColor(new Color(0xE8, 0xE8, 0xFF));
|
||||
g.fillRect(x+1, y+1, 30, 20);
|
||||
|
||||
g.setColor(Color.blue);
|
||||
g.drawRect(x, y, 30, 20);
|
||||
|
||||
g.drawString(it.next().toString(), x + 1, y + 19);
|
||||
|
||||
if (it.hasNext())
|
||||
{
|
||||
g.setColor(Color.black);
|
||||
g.drawLine(x + 30, y + 10, x + 45, y + 10);
|
||||
g.drawLine(x + 45, y + 10, x + 40, y + 5);
|
||||
g.drawLine(x + 45, y + 10, x + 40, y + 15);
|
||||
}
|
||||
|
||||
g.setColor(Color.gray);
|
||||
g.drawString("" + position++, x - 1, y + 35);
|
||||
|
||||
x = x + 45;
|
||||
}
|
||||
}
|
||||
}
|
||||
200
SS23/AuD/src/UEB03/ListeGUI.java
Normal file
@@ -0,0 +1,200 @@
|
||||
package UEB03;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
public class ListeGUI extends Frame
|
||||
{
|
||||
//Attribute
|
||||
protected Label wertFuehrungstext;
|
||||
protected TextField wertTextfeld;
|
||||
protected Label positionFuehrungstext;
|
||||
protected TextField positionTextfeld;
|
||||
protected Button einfuegenDruckknopf;
|
||||
protected Button anhaengenDruckknopf;
|
||||
protected Button entfernenDruckknopf;
|
||||
protected Button alleEntfernenDruckknopf;
|
||||
protected Button traversierenDruckknopf;
|
||||
protected Button suchenDruckknopf;
|
||||
protected Label ausgabeFuehrungstext;
|
||||
protected TextArea ausgabeTextbereich;
|
||||
|
||||
protected Liste<Character> eineListe;
|
||||
protected ListeCanvas eineZeichenflaeche; //Zeichenfl<66>che f<>r die Animation
|
||||
|
||||
//Operationen
|
||||
public ListeGUI()
|
||||
{
|
||||
setTitle("Verkettete Liste");
|
||||
setLayout(null);
|
||||
setSize(492,315);
|
||||
add(eineZeichenflaeche = new ListeCanvas());
|
||||
eineZeichenflaeche.setBounds(32,32,430,80);
|
||||
add(wertFuehrungstext= new Label());
|
||||
wertFuehrungstext.setText("Wert:");
|
||||
wertFuehrungstext.setBounds(30,112,58,23);
|
||||
add(wertTextfeld = new TextField());
|
||||
wertTextfeld.setBounds(90,112,45,23);
|
||||
add(positionFuehrungstext= new Label());
|
||||
positionFuehrungstext.setText("Position:");
|
||||
positionFuehrungstext.setBounds(30,137,58,23);
|
||||
add(positionTextfeld = new TextField());
|
||||
positionTextfeld.setBounds(90,137,45,23);
|
||||
add(einfuegenDruckknopf = new Button());
|
||||
einfuegenDruckknopf.setLabel("Einf<EFBFBD>gen");
|
||||
einfuegenDruckknopf.setBounds(30,170,100,23);
|
||||
add(anhaengenDruckknopf = new Button());
|
||||
anhaengenDruckknopf.setLabel("Anh<EFBFBD>ngen");
|
||||
anhaengenDruckknopf.setBounds(140,170,100,23);
|
||||
add(entfernenDruckknopf = new Button());
|
||||
entfernenDruckknopf.setLabel("Entfernen");
|
||||
entfernenDruckknopf.setBounds(250,170,100,23);
|
||||
add(alleEntfernenDruckknopf = new Button());
|
||||
alleEntfernenDruckknopf.setLabel("Alle entfernen");
|
||||
alleEntfernenDruckknopf.setBounds(360,170,100,23);
|
||||
add(traversierenDruckknopf = new Button());
|
||||
traversierenDruckknopf.setLabel("Traversieren");
|
||||
traversierenDruckknopf.setBounds(30,220,100,23);
|
||||
add(suchenDruckknopf = new Button());
|
||||
suchenDruckknopf.setLabel("Suchen");
|
||||
suchenDruckknopf.setBounds(140,220,100,23);
|
||||
add(ausgabeFuehrungstext= new Label());
|
||||
ausgabeFuehrungstext.setText("Ausgabe:");
|
||||
ausgabeFuehrungstext.setBounds(30,255,58,23);
|
||||
add(ausgabeTextbereich = new TextArea("", 1, 1000, TextArea.SCROLLBARS_NONE));
|
||||
ausgabeTextbereich.setBounds(90,255,370,23);
|
||||
ausgabeTextbereich.setEnabled(false);
|
||||
|
||||
// Registrieren der Ereignisabh<62>rer
|
||||
AktionsAbhoerer einAktionsAbhoerer = new AktionsAbhoerer();
|
||||
einfuegenDruckknopf.addActionListener(einAktionsAbhoerer);
|
||||
anhaengenDruckknopf.addActionListener(einAktionsAbhoerer);
|
||||
entfernenDruckknopf.addActionListener(einAktionsAbhoerer);
|
||||
alleEntfernenDruckknopf.addActionListener(einAktionsAbhoerer);
|
||||
suchenDruckknopf.addActionListener(einAktionsAbhoerer);
|
||||
traversierenDruckknopf.addActionListener(einAktionsAbhoerer);
|
||||
|
||||
// Test f<>r Verkettung zweier Listen
|
||||
eineListe = new Liste<Character>();
|
||||
eineListe.anfuegen(new Character('A'));
|
||||
eineListe.anfuegen(new Character('B'));
|
||||
Liste<Character> zweiteListe = new Liste<Character>();
|
||||
zweiteListe.anfuegen(new Character('C'));
|
||||
zweiteListe.anfuegen(new Character('D'));
|
||||
eineListe.verketten(zweiteListe);
|
||||
|
||||
eineZeichenflaeche.zeichneNeu(eineListe);
|
||||
|
||||
addWindowListener(
|
||||
new WindowAdapter()
|
||||
{
|
||||
public void windowClosing(WindowEvent e)
|
||||
{
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
//Innere Klasse f<>r die Ereignisabh<62>rer
|
||||
class AktionsAbhoerer implements ActionListener
|
||||
{
|
||||
private Character getCharacter()
|
||||
{
|
||||
final String s = wertTextfeld.getText();
|
||||
|
||||
return (s.length() > 0) ? s.charAt(0) : '?';
|
||||
}
|
||||
|
||||
private int getPosition()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Integer.valueOf(positionTextfeld.getText());
|
||||
}
|
||||
catch(NumberFormatException e)
|
||||
{
|
||||
ausgabeTextbereich.setText("Es wurde kein Position angegeben. Standardwert: 0 (Listenanfang)");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void finish()
|
||||
{
|
||||
wertTextfeld.setText("");
|
||||
positionTextfeld.setText("");
|
||||
|
||||
eineZeichenflaeche.zeichneNeu(eineListe);
|
||||
}
|
||||
|
||||
private void finish(final String ausgabe)
|
||||
{
|
||||
ausgabeTextbereich.setText(ausgabe);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent event)
|
||||
{
|
||||
Object o = event.getSource();
|
||||
ausgabeTextbereich.setText("");
|
||||
|
||||
if (o == einfuegenDruckknopf)
|
||||
{
|
||||
eineListe.einfuegen(getCharacter(), getPosition());
|
||||
finish();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == anhaengenDruckknopf)
|
||||
{
|
||||
eineListe.anfuegen(getCharacter());
|
||||
finish();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == entfernenDruckknopf)
|
||||
{
|
||||
if (eineListe.entfernen(getPosition()) == null)
|
||||
ausgabeTextbereich.setText("Es wurde kein Opfer gefunden!");
|
||||
|
||||
finish();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == suchenDruckknopf)
|
||||
{
|
||||
final int position = eineListe.suchen(getCharacter());
|
||||
finish(position == -1 ? "Der Wert wurde nicht gefunden." : "Der gesuchte Wert wird zum ersten Mal an Position " + position + " gefunden.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == alleEntfernenDruckknopf)
|
||||
{
|
||||
finish(eineListe.entferneWerte(getCharacter()) + " Elemente wurden entfernt.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == traversierenDruckknopf)
|
||||
{
|
||||
String ausgabe = "";
|
||||
|
||||
ListeIterator<Character> e = eineListe.iterator();
|
||||
while (e.hasNext())
|
||||
ausgabe += e.next() + " ";
|
||||
|
||||
finish(ausgabe);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
33
SS23/AuD/src/UEB03/ListeIterator.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package UEB03;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ListeIterator<T> implements Iterator
|
||||
{
|
||||
private Link<T> zeiger;
|
||||
private Link<T> ende;
|
||||
|
||||
ListeIterator(Link<T> start, Link<T> ende)
|
||||
{
|
||||
zeiger = start;
|
||||
this.ende = ende;
|
||||
}
|
||||
|
||||
public boolean hasNext()
|
||||
{
|
||||
return zeiger != null;
|
||||
}
|
||||
|
||||
public T next()
|
||||
{
|
||||
final T daten = zeiger.daten;
|
||||
zeiger = zeiger.naechster;
|
||||
|
||||
return daten;
|
||||
}
|
||||
|
||||
public void remove()
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
9
SS23/AuD/src/UEB03/ListeTest.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package UEB03;
|
||||
|
||||
public class ListeTest
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new ListeGUI().setVisible(true);
|
||||
}
|
||||
}
|
||||
10
SS23/AuD/src/UEB03/Main.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package UEB03;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Link<String> ende = new Link<String>("Letzter", null);
|
||||
Link<String> mittleresElement = new Link<String>("Test", ende);
|
||||
Link<String> anfang= new Link<String>("TErster", mittleresElement);
|
||||
|
||||
}
|
||||
}
|
||||
72
SS23/AuD/src/UEB04/Aufgabe3/ListInterfaceAufgabe.java
Normal file
@@ -0,0 +1,72 @@
|
||||
package UEB04.Aufgabe3;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ListInterfaceAufgabe
|
||||
{
|
||||
// Elemente in Liste einfgen
|
||||
static void fillList(List<String> list)
|
||||
{
|
||||
// Zahlen von 0 bis 20 als Zeichenketten (Strings) einfgen
|
||||
for (int a = 0; a <= 20; a++)
|
||||
list.add("" + a);
|
||||
|
||||
// Element an der Position 3 entfernen
|
||||
list.remove(3);
|
||||
|
||||
// Erstes Element in der Liste entfernen, das gleich "6" ist
|
||||
list.remove("6");
|
||||
}
|
||||
|
||||
// Liste vom Anfang bis zum Ende mit einer
|
||||
// foreach-Schleife iterieren und Elemente ausgeben
|
||||
static void printList(List<String> list)
|
||||
{
|
||||
for(String s:list){
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
|
||||
// Alle Elemente aus der Liste entfernen, die durch 5 teilbar sind
|
||||
static void remove5List(List<String> list)
|
||||
{
|
||||
Iterator i = list.iterator();
|
||||
int counter = 0;
|
||||
while( i.hasNext()){
|
||||
if (Integer.parseInt((String) i.next())%5==0){
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// Erzeugen der LinkedList
|
||||
LinkedList<String> list1 = new LinkedList<String>();
|
||||
fillList(list1);
|
||||
System.out.println("\nAusgabe der ersten Liste(list1)");
|
||||
printList(list1);
|
||||
|
||||
remove5List(list1);
|
||||
System.out.println("\nlist1 nach dem Entfernen der durch 5 teilbaren Zahlen");
|
||||
printList(list1);
|
||||
|
||||
// Erzeugen der ArrayList
|
||||
ArrayList<String> list2 = new ArrayList<String>();
|
||||
fillList(list2);
|
||||
|
||||
System.out.println("\nAusgabe der zweiten Liste(list2)");
|
||||
printList(list2);
|
||||
|
||||
System.out.println("\nAusgabe der dritten Liste(list2)");
|
||||
List<String> list3 = list2.subList(5,12);
|
||||
printList(list3);
|
||||
list3.remove("11");
|
||||
System.out.println("\n");
|
||||
printList(list3);
|
||||
|
||||
System.out.println("\nAusgabe der zweiten Liste(list2)");
|
||||
printList(list2);
|
||||
|
||||
}
|
||||
}
|
||||
65
SS23/AuD/src/UEB04/Aufgabe4/ArrayStack.java
Normal file
@@ -0,0 +1,65 @@
|
||||
package UEB04.Aufgabe4;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ArrayStack<E> implements StackI<E>
|
||||
{
|
||||
// Array, in dem die Elemente des Stacks gespeichert werden.
|
||||
// Das oberes Ende des Stacks liegt an Position pos-1.
|
||||
// Ein Array mit Elementen vom Typ E kann zwar deklariert, aber
|
||||
// nicht <20>ber new erzugt werden (Java-Mangel)!
|
||||
private Object[] st;
|
||||
|
||||
// N<>chste freie Position im Array
|
||||
// Gleichzeitig Anzahl der im Array/Stack gespeicherten Elemente
|
||||
private int pos;
|
||||
List<E> yeet = new ArrayList<E>();
|
||||
|
||||
// Erzeugt ein Stack-Objekt, in dem maximal size Elemente
|
||||
// abgespeichert werden k<>nnen
|
||||
public ArrayStack(int size)
|
||||
{
|
||||
st = new Object[size];
|
||||
}
|
||||
|
||||
// Legt <20>bergebenes Element auf den Stack, sofern noch Platz
|
||||
// vorhanen ist. Das Element wird an Position pos gespeichert.
|
||||
public void push(E element)
|
||||
{
|
||||
st[size() +1] = element;
|
||||
}
|
||||
|
||||
// Holt oberstes Element vom Stack, sofern der Stack nicht leer ist.
|
||||
public E pop()
|
||||
{
|
||||
E element = top();
|
||||
st[size()]=null;
|
||||
return element;
|
||||
|
||||
}
|
||||
|
||||
// Gibt oberstes Element auf dem Stack zur<75>ck, sofern der Stack nicht
|
||||
// leer ist. Bei leerem Stack wird null zur<75>ckgegeben.
|
||||
public E top()
|
||||
{
|
||||
return (E) st[size()];
|
||||
}
|
||||
|
||||
public int size(){
|
||||
int counter = 0;
|
||||
while (st[counter]!=null){
|
||||
if(st.length == counter){
|
||||
return counter;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
// Gibt true zur<75>ck, falls der Stack leer ist
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return st[0]==null;
|
||||
}
|
||||
}
|
||||
9
SS23/AuD/src/UEB04/Aufgabe4/StackI.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package UEB04.Aufgabe4;// Abstrakte Datenstruktur Stack, realisiert als Java-Interface
|
||||
|
||||
interface StackI<E>
|
||||
{
|
||||
public void push(E element);
|
||||
public E pop();
|
||||
public E top();
|
||||
public boolean isEmpty();
|
||||
}
|
||||
39
SS23/AuD/src/UEB04/Aufgabe4/StackTest.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package UEB04.Aufgabe4;
|
||||
|
||||
public class StackTest
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
ArrayStack<Integer> st = new ArrayStack<Integer>(10);
|
||||
|
||||
System.out.println("Ablegen auf dem Stapel: 5 Elemente");
|
||||
for (int a = 1; a <= 5; a++)
|
||||
{
|
||||
System.out.print(a + " ");
|
||||
st.push(a);
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
System.out.println("Entnehmen vom Stapel: 3 Elemente");
|
||||
for (int a = 1; a <= 3; a++)
|
||||
{
|
||||
System.out.print(st.pop() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
System.out.println("Versuch: Ablegen auf dem Stapel: 10 Elemente");
|
||||
for (int a = 6; a <= 15; a++)
|
||||
{
|
||||
System.out.print(a + " ");
|
||||
st.push(a);
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
System.out.println("Entnehmen vom Stapel bis Stapel leer");
|
||||
while (!st.isEmpty())
|
||||
{
|
||||
System.out.print(st.pop() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
436
SS23/AuD/src/UEB06/Baum.java
Normal file
@@ -0,0 +1,436 @@
|
||||
package UEB06;
|
||||
|
||||
public class Baum<T extends Comparable<T>>
|
||||
{
|
||||
private Knoten<T> wurzel;
|
||||
|
||||
// Wird nur f<>r grafische Oberfl<66>che ben<65>tigt, ohne
|
||||
// diese Methode k<>nnte die gesamte Implementierung
|
||||
// des Baumes geheim gehalten werden. Alle <20>ffentlichen
|
||||
// Methoden sind parameterlos oder besitzen als
|
||||
// einzigen Parameter einen Schl<68>sselwert
|
||||
public Knoten<T> getWurzel()
|
||||
{
|
||||
return wurzel;
|
||||
}
|
||||
|
||||
public boolean istLeer()
|
||||
{
|
||||
return (wurzel == null);
|
||||
}
|
||||
|
||||
public void attach(Knoten<T> einKnoten)
|
||||
{
|
||||
wurzel = einKnoten;
|
||||
}
|
||||
|
||||
|
||||
// Methoden zum Suchen
|
||||
|
||||
public boolean suchen(final T daten)
|
||||
{
|
||||
return istLeer() ? false : suchenKnoten(daten, wurzel);
|
||||
// Effiziente Kurzform f<>r:
|
||||
// if (istLeer()) { return false; } else { return suchenKnoten(daten, wurzel); }
|
||||
}
|
||||
|
||||
private boolean suchenKnoten(final T daten, Knoten<T> teilbaum)
|
||||
{
|
||||
if (teilbaum == null)
|
||||
return false;
|
||||
|
||||
// Vergleichs-Ergebnis zwischenspeichern, da compareTo()
|
||||
// aufw<66>ndig sein kann, und das Ergebnis mehrfach ben<65>tigt
|
||||
// wird
|
||||
final int cmp = daten.compareTo(teilbaum.getDaten());
|
||||
|
||||
return (cmp == 0) ? true : suchenKnoten(daten, (cmp < 0) ? teilbaum.getKnotenLinks() : teilbaum.getKnotenRechts());
|
||||
// Effiziente Kurzform f<>r:
|
||||
// if (cmp == 0) { return true; }
|
||||
// else if (cmp < 0) { return suchenKnoten(daten, teilbaum.getKnotenLinks()); }
|
||||
// else { return suchenKnoten(daten, teilbaum.getKnotenRechts()); }
|
||||
}
|
||||
|
||||
|
||||
// Methoden zum Einf<6E>gen
|
||||
|
||||
public void einfuegen(final T daten)
|
||||
{
|
||||
if (istLeer())
|
||||
{
|
||||
// Sonderfall, analog zu verketteten Listen
|
||||
wurzel = new Knoten<T>(daten, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
einfuegenKnoten(daten, wurzel);
|
||||
}
|
||||
}
|
||||
|
||||
// Generiert einen neuen Knoten mit <20>bergebenen Daten und f<>gt
|
||||
// ihn (die Suchbaumeigenschaft erhaltend) als Blatt in den
|
||||
// Baum ein, sofern die Daten noch nicht vorhanden sind.
|
||||
private void einfuegenKnoten(final T daten, Knoten<T> teilbaum)
|
||||
{
|
||||
// Vergleichs-Ergebnis zwischenspeichern, da compareTo()
|
||||
// aufw<66>ndig sein kann, und das Ergebnis mehrfach ben<65>tigt
|
||||
// wird
|
||||
final int cmp = daten.compareTo(teilbaum.getDaten());
|
||||
|
||||
// Daten schon vorhanden?
|
||||
// Falls ja: alles erledigt!
|
||||
if (cmp == 0)
|
||||
return;
|
||||
|
||||
if (cmp < 0)
|
||||
{
|
||||
// Einzuf<75>gende Daten sind KLEINER als Daten im aktuellen Knoten
|
||||
// und m<>ssen daher im LINKEN Teilbaum eingef<65>gt werden
|
||||
if (teilbaum.getKnotenLinks() == null)
|
||||
{
|
||||
// Es gibt keinen linken Teilbaum -> neuen Knoten erzeugen
|
||||
teilbaum.setKnotenLinks(new Knoten<T>(daten, null, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Es existiert ein linker Teilbaum -> rekursiv weiter
|
||||
einfuegenKnoten(daten, teilbaum.getKnotenLinks());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Einzuf<75>gende Daten sind GROESSER als Daten im aktuellen Knoten
|
||||
// und m<>ssen daher im RECHTEN Teilbaum eingef<65>gt werden
|
||||
if (teilbaum.getKnotenRechts() == null)
|
||||
{
|
||||
// Es gibt keinen rechten Teilbaum -> neuen Knoten erzeugen
|
||||
teilbaum.setKnotenRechts(new Knoten<T>(daten, null, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Es existiert ein rechter Teilbaum -> rekursiv weiter
|
||||
einfuegenKnoten(daten, teilbaum.getKnotenRechts());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Methoden zum Entfernen
|
||||
|
||||
public void entfernen(final T daten)
|
||||
{
|
||||
// Leerer Baum?
|
||||
// Falls ja, gibt es nicht zu entfernen!
|
||||
if (istLeer())
|
||||
return;
|
||||
|
||||
// Vergleichs-Ergebnis zwischenspeichern, da compareTo()
|
||||
// aufw<66>ndig sein kann, und das Ergebnis mehrfach ben<65>tigt
|
||||
// wird
|
||||
final int cmp = daten.compareTo(wurzel.getDaten());
|
||||
|
||||
if (cmp == 0)
|
||||
{
|
||||
// Der Wurzel-Knoten muss entfernt werden!
|
||||
// Sonderfall, analog zu verketteten Listen
|
||||
entfernenWurzel();
|
||||
}
|
||||
else
|
||||
if (cmp < 0)
|
||||
{
|
||||
// Zu l<>schende Daten kleiner als Daten in Wurzel;
|
||||
// im linken Teilbaum weitersuchen falls existent
|
||||
if (wurzel.getKnotenLinks() != null)
|
||||
entfernenKnoten(daten, wurzel, wurzel.getKnotenLinks(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Zu l<>schende Daten gr<67><72>er als Daten in Wurzel;
|
||||
// im rechten Teilbaum weitersuchen falls existent
|
||||
if (wurzel.getKnotenRechts() != null)
|
||||
entfernenKnoten(daten, wurzel, wurzel.getKnotenRechts(), false);
|
||||
}
|
||||
}
|
||||
|
||||
private void entfernenWurzel()
|
||||
{
|
||||
if (wurzel.getKnotenLinks() == null)
|
||||
{
|
||||
// Wurzel hat h<>chstens einen rechten Nachfolger.
|
||||
// Der wird zur neuen Wurzel!
|
||||
wurzel = wurzel.getKnotenRechts();
|
||||
}
|
||||
else
|
||||
if (wurzel.getKnotenRechts() == null)
|
||||
{
|
||||
// Wurzel hat h<>chstens einen linken Nachfolger.
|
||||
// Der wird zur neuen Wurzel!
|
||||
wurzel = wurzel.getKnotenLinks();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Rechter und linker Teilbaum nicht leer; zwei Nachfolger.
|
||||
// Wurzel durch gr<67><72>ten Knoten im linken Teilbaum ersetzen!
|
||||
ersetzeKnoten(wurzel);
|
||||
}
|
||||
}
|
||||
|
||||
// Sofern <20>bergebene Daten im Teilbaum vorhanden sind, werden sie gel<65>scht.
|
||||
// Elternknoten wird ben<65>tigt, da dessen rechter bzw. linker Nachfolger ggf. auf
|
||||
// den rechten bzw. linken Nachfolger des zu l<>schenden Knotens umgesetzt werden muss
|
||||
// Ist linkerTeilbaum == true, wurde der linke Nachfolger des Elternknotens <20>bergeben,
|
||||
// sonst der rechte. Wird ben<65>tigt, um zu entscheiden, ob der linke oder rechte
|
||||
// Nachfolger des Elternknotens ge<67>ndert werden muss.
|
||||
private void entfernenKnoten(final T daten, Knoten<T> elternknoten, Knoten<T> teilbaum, final boolean linkerTeilbaum)
|
||||
{
|
||||
// Vergleichs-Ergebnis zwischenspeichern, da compareTo()
|
||||
// aufw<66>ndig sein kann, und das Ergebnis mehrfach ben<65>tigt
|
||||
// wird
|
||||
final int cmp = daten.compareTo(teilbaum.getDaten());
|
||||
|
||||
if (cmp == 0)
|
||||
{
|
||||
// Der Knoten mit den zu l<>schenden Daten wurde gefunden
|
||||
if (teilbaum.getKnotenLinks() == null)
|
||||
{
|
||||
// Zu l<>schender Knoten hat h<>chstens einen rechten Nachfolger.
|
||||
// Auf diesen vom Elternknoten aus verweisen!
|
||||
if (linkerTeilbaum)
|
||||
{
|
||||
elternknoten.setKnotenLinks(teilbaum.getKnotenRechts());
|
||||
}
|
||||
else
|
||||
{
|
||||
elternknoten.setKnotenRechts(teilbaum.getKnotenRechts());
|
||||
}
|
||||
}
|
||||
else
|
||||
if (teilbaum.getKnotenRechts() == null)
|
||||
{
|
||||
// Zu l<>schender Knoten hat h<>chstens einen linken Nachfolger.
|
||||
// Auf diesen vom Elternknoten aus verweisen!
|
||||
if (linkerTeilbaum)
|
||||
{
|
||||
elternknoten.setKnotenLinks(teilbaum.getKnotenLinks());
|
||||
}
|
||||
else
|
||||
{
|
||||
elternknoten.setKnotenRechts(teilbaum.getKnotenLinks());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Rechter und linker Teilbaum nicht leer; zwei Nachfolger!
|
||||
// Zu l<>schenden Knoten durch gr<67><72>ten Knoten im linken Teilbaum ersetzten
|
||||
ersetzeKnoten(teilbaum);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (cmp < 0)
|
||||
{
|
||||
// Zu l<>schende Daten kleiner als Daten im aktuellen Knoten;
|
||||
// im linken Teilbaum weitersuchen falls existent
|
||||
if (teilbaum.getKnotenLinks() != null)
|
||||
entfernenKnoten(daten, teilbaum, teilbaum.getKnotenLinks(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Zu l<>schende Daten gr<67><72>er als Daten im aktuellen Knoten;
|
||||
// im rechten Teilbaum weitersuchen falls existent
|
||||
if (teilbaum.getKnotenRechts() != null)
|
||||
entfernenKnoten(daten, teilbaum, teilbaum.getKnotenRechts(), false);
|
||||
}
|
||||
}
|
||||
|
||||
// Ersetzt zu l<>schenden Knoten durch gr<67><72>ten Knoten im linken Teilbaum,
|
||||
// indem Daten des gr<67><72>ten Knotens in zu l<>schenden Knoten kopiert werden.
|
||||
// Vom Elternknoten des gr<67><72>ten Knotens aus muss auf den linken Teilbaum
|
||||
// des gr<67><72>ten Knotens verwiesen werden. Der rechten Teilbaum des gr<67><72>ten
|
||||
// Knotens ist immer leer (Def. gr<67><72>ter Knoten)
|
||||
private void ersetzeKnoten(Knoten<T> zuLoeschenderKnoten)
|
||||
{
|
||||
// Gr<47><72>ten Knoten suchen; dessen rechter Nachfolger ist null.
|
||||
// Daher kann rechter Nachfolger des zu l<>schenden Knotens <20>bernommen werden.
|
||||
Knoten<T> elternknoten = zuLoeschenderKnoten;
|
||||
Knoten<T> teilbaum = zuLoeschenderKnoten.getKnotenLinks();
|
||||
Knoten<T> groessterKnoten = teilbaum;
|
||||
|
||||
while (teilbaum.getKnotenRechts() != null)
|
||||
{
|
||||
elternknoten = teilbaum;
|
||||
teilbaum = teilbaum.getKnotenRechts();
|
||||
groessterKnoten = teilbaum;
|
||||
}
|
||||
|
||||
// Daten des gr<67><72>ten Knotens werden in zu l<>schenden Knoten kopiert
|
||||
zuLoeschenderKnoten.setDaten(groessterKnoten.getDaten());
|
||||
|
||||
if (elternknoten == zuLoeschenderKnoten) // Gr<47><72>ter Knoten ist Wurzel des linken Teilbaums des zu L<>schenden
|
||||
{
|
||||
// Zu l<>schender Knoten ist gleichzeitig Elternknoten des gr<67><72>ten Knotens
|
||||
// Rechter Teilbaum des zu l<>schenden Knotens muss erhalten bleiben
|
||||
// Linken Teilbaum des zu loeschenden Knotens auf linken Teilbaum des gr<67><72>ten Knotens setzen
|
||||
// Das sind die einzigen Nachfolger des gr<67><72>ten Knotens, da dessen rechter Teilbaum ja
|
||||
// immer leer ist.
|
||||
zuLoeschenderKnoten.setKnotenLinks(groessterKnoten.getKnotenLinks());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Rechten, freiwerdenden Teilbaum des Elternknotens des gr<67><72>ten Knotens
|
||||
// auf linken Teilbaum des gr<67><72>ten Knotens setzen
|
||||
// Das sind die einzigen Nachfolger des gr<67><72>ten Knotens, da dessen rechter Teilbaum ja
|
||||
// immer leer ist.
|
||||
elternknoten.setKnotenRechts(groessterKnoten.getKnotenLinks());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Methoden zum Traversieren
|
||||
|
||||
// Pre-Order
|
||||
public String traversierePreOrder()
|
||||
{
|
||||
return (wurzel != null) ? traversierePreOrder(wurzel) : "Der Baum ist leer.";
|
||||
}
|
||||
|
||||
private String traversierePreOrder(final Knoten<T> einKnoten)
|
||||
{
|
||||
assert(einKnoten != null);
|
||||
|
||||
String nodes = "";
|
||||
nodes += einKnoten.getDaten();
|
||||
|
||||
if(einKnoten.getKnotenLinks() != null){
|
||||
nodes += traversierePreOrder(einKnoten.getKnotenLinks());
|
||||
}
|
||||
|
||||
|
||||
if(einKnoten.getKnotenRechts() != null){
|
||||
nodes += traversierePreOrder(einKnoten.getKnotenRechts());
|
||||
}
|
||||
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
|
||||
// In-Order
|
||||
public String traversiereInOrder()
|
||||
{
|
||||
return (wurzel != null) ? traversiereInOrder(wurzel) : "Der Baum ist leer.";
|
||||
}
|
||||
|
||||
private String traversiereInOrder(final Knoten<T> einKnoten)
|
||||
{
|
||||
String nodes = "";
|
||||
assert(einKnoten != null);
|
||||
|
||||
|
||||
if(einKnoten.getKnotenLinks() != null){
|
||||
nodes += traversiereInOrder(einKnoten.getKnotenLinks());
|
||||
}
|
||||
|
||||
nodes += einKnoten.getDaten();
|
||||
|
||||
if(einKnoten.getKnotenRechts() != null){
|
||||
nodes += traversiereInOrder(einKnoten.getKnotenRechts());
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// public String traversiereInOrder()
|
||||
// {
|
||||
// return (wurzel != null) ? traversiereInOrder(wurzel,"") : "Der Baum ist leer.";
|
||||
// }
|
||||
//
|
||||
// private String traversiereInOrder(final Knoten<T> einKnoten, String nodes)
|
||||
// {
|
||||
// assert(einKnoten != null);
|
||||
//
|
||||
//
|
||||
// if(einKnoten.getKnotenLinks() != null){
|
||||
// nodes = traversiereInOrder(einKnoten.getKnotenLinks(),nodes);
|
||||
// }
|
||||
//
|
||||
// nodes += einKnoten.getDaten();
|
||||
//
|
||||
// if(einKnoten.getKnotenRechts() != null){
|
||||
// nodes = traversiereInOrder(einKnoten.getKnotenRechts(),nodes);
|
||||
// }
|
||||
//
|
||||
// return nodes;
|
||||
// }
|
||||
|
||||
|
||||
// Post-Order
|
||||
public String traversierePostOrder()
|
||||
{
|
||||
return (wurzel != null) ? traversierePostOrder(wurzel) : "Der Baum ist leer.";
|
||||
}
|
||||
|
||||
private String traversierePostOrder(final Knoten<T> einKnoten)
|
||||
{
|
||||
assert(einKnoten != null);
|
||||
String nodes = "";
|
||||
if(einKnoten.getKnotenLinks() != null){
|
||||
nodes += traversierePostOrder(einKnoten.getKnotenLinks());
|
||||
}
|
||||
|
||||
|
||||
if(einKnoten.getKnotenRechts() != null){
|
||||
nodes += traversierePostOrder(einKnoten.getKnotenRechts());
|
||||
}
|
||||
|
||||
nodes += einKnoten.getDaten();
|
||||
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
|
||||
// Methoden zur Bestimmung der H<>he
|
||||
|
||||
public int hoehe()
|
||||
{
|
||||
if (wurzel != null){
|
||||
return hoeheRek(wurzel);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
// private int hoeheRek(final Knoten<T> einKnoten)
|
||||
// {
|
||||
//
|
||||
// assert(einKnoten != null);
|
||||
// int out = 1;
|
||||
// if(einKnoten.getKnotenLinks()!=null && einKnoten.getKnotenRechts() != null){
|
||||
// if(hoeheRek(einKnoten.getKnotenLinks())>hoeheRek(einKnoten.getKnotenRechts())){
|
||||
// out += hoeheRek(einKnoten.getKnotenLinks());
|
||||
// }
|
||||
// else {
|
||||
// out += hoeheRek(einKnoten.getKnotenRechts());
|
||||
// }
|
||||
// } else if (einKnoten.getKnotenLinks()!=null && einKnoten.getKnotenRechts() == null) {
|
||||
// out += hoeheRek(einKnoten.getKnotenLinks());
|
||||
// } else if (einKnoten.getKnotenLinks()==null && einKnoten.getKnotenRechts() != null) {
|
||||
// out += hoeheRek(einKnoten.getKnotenRechts());
|
||||
// }
|
||||
//
|
||||
// return out;
|
||||
// }
|
||||
|
||||
private int hoeheRek(final Knoten<T> einKnoten) {
|
||||
|
||||
int hoehe = 0;
|
||||
|
||||
if (einKnoten != null) {
|
||||
return Math.max(hoeheRek(einKnoten.getKnotenRechts()), hoeheRek(einKnoten.getKnotenLinks())) + 1;
|
||||
}
|
||||
return hoehe;
|
||||
}
|
||||
}
|
||||
41
SS23/AuD/src/UEB06/BaumAnsicht.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package UEB06;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class BaumAnsicht
|
||||
{
|
||||
private Baum<Character> einBaum;
|
||||
|
||||
public BaumAnsicht(Baum<Character> einBaum)
|
||||
{
|
||||
this.einBaum = einBaum;
|
||||
}
|
||||
|
||||
public void ausgeben(int xLinks, int xRechts, int y, Graphics g)
|
||||
{
|
||||
g.setColor(new Color(240, 240, 240));
|
||||
g.fillRect(xLinks, 100, xRechts, 190);
|
||||
|
||||
ausgebenTeilbaum(einBaum.getWurzel(), -1, -1, xLinks, xRechts, y, g);
|
||||
}
|
||||
|
||||
public void ausgebenTeilbaum(Knoten teilbaum, int xParent, int yParent, int xLinks, int xRechts, int y, Graphics g)
|
||||
{
|
||||
if (teilbaum != null)
|
||||
{
|
||||
final int mitte = (xLinks + xRechts) / 2;
|
||||
|
||||
g.setColor(Color.black);
|
||||
g.drawString(teilbaum.toString(), mitte - 2, y);
|
||||
|
||||
if ((xParent != -1) && (yParent != -1))
|
||||
{
|
||||
g.setColor(new Color(192, 192, 192));
|
||||
g.drawLine(xParent, yParent, mitte, y-12);
|
||||
}
|
||||
|
||||
ausgebenTeilbaum(teilbaum.getKnotenLinks(), mitte, y + 4, xLinks + 4, mitte - 4, y + 30, g);
|
||||
ausgebenTeilbaum(teilbaum.getKnotenRechts(), mitte, y + 4, mitte + 4, xRechts + 4, y + 30, g);
|
||||
}
|
||||
}
|
||||
}
|
||||
199
SS23/AuD/src/UEB06/BaumGUI.java
Normal file
@@ -0,0 +1,199 @@
|
||||
package UEB06;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
|
||||
public class BaumGUI extends Frame
|
||||
{
|
||||
private Baum<Character> einBaum;
|
||||
private BaumAnsicht eineBaumAnsicht;
|
||||
|
||||
private java.awt.Label zeichenFuehrungstext = new java.awt.Label();
|
||||
private java.awt.TextField zeichenTextfeld = new java.awt.TextField();
|
||||
private java.awt.Button suchenDruckknopf = new java.awt.Button();
|
||||
private java.awt.Button einfuegenDruckknopf = new java.awt.Button();
|
||||
private java.awt.Button entfernenDruckknopf = new java.awt.Button();
|
||||
private java.awt.Button demoDruckknopf = new java.awt.Button();
|
||||
private java.awt.Checkbox enthaltenKontrollkaestchen = new java.awt.Checkbox();
|
||||
private java.awt.Label infoLabel = new java.awt.Label();
|
||||
private java.awt.Button traversierenDruckknopf = new java.awt.Button();
|
||||
private java.awt.TextArea ausgabeTextfeld = new java.awt.TextArea("",0,0,TextArea.SCROLLBARS_NONE);
|
||||
|
||||
public BaumGUI()
|
||||
{
|
||||
setLayout(null);
|
||||
setSize(530,505);
|
||||
zeichenFuehrungstext.setText("Zeichen:");
|
||||
zeichenFuehrungstext.setAlignment(java.awt.Label.RIGHT);
|
||||
add(zeichenFuehrungstext);
|
||||
zeichenFuehrungstext.setBounds(12,32,48,24);
|
||||
add(zeichenTextfeld);
|
||||
zeichenTextfeld.setBounds(72,32,48,24);
|
||||
suchenDruckknopf.setLabel("Suchen");
|
||||
add(suchenDruckknopf);
|
||||
suchenDruckknopf.setBackground(java.awt.Color.lightGray);
|
||||
suchenDruckknopf.setBounds(132,32,84,24);
|
||||
einfuegenDruckknopf.setLabel("Einf<EFBFBD>gen");
|
||||
add(einfuegenDruckknopf);
|
||||
einfuegenDruckknopf.setBackground(java.awt.Color.lightGray);
|
||||
einfuegenDruckknopf.setBounds(228,32,84,24);
|
||||
entfernenDruckknopf.setLabel("Entfernen");
|
||||
add(entfernenDruckknopf);
|
||||
entfernenDruckknopf.setBackground(java.awt.Color.lightGray);
|
||||
entfernenDruckknopf.setBounds(324,32,84,24);
|
||||
demoDruckknopf.setLabel("Demo-Baum");
|
||||
add(demoDruckknopf);
|
||||
demoDruckknopf.setBackground(java.awt.Color.lightGray);
|
||||
demoDruckknopf.setBounds(418,32,84,24);
|
||||
enthaltenKontrollkaestchen.setLabel("Im Baum enthalten");
|
||||
enthaltenKontrollkaestchen.setEnabled(false);
|
||||
add(enthaltenKontrollkaestchen);
|
||||
enthaltenKontrollkaestchen.setBounds(132,68,132,24);
|
||||
add(infoLabel);
|
||||
infoLabel.setBounds(14,292,500,20);
|
||||
traversierenDruckknopf.setLabel("Traversieren");
|
||||
add(traversierenDruckknopf);
|
||||
traversierenDruckknopf.setBackground(java.awt.Color.lightGray);
|
||||
traversierenDruckknopf.setBounds(14,320,127,26);
|
||||
add(ausgabeTextfeld);
|
||||
ausgabeTextfeld.setBounds(14,350,500,144);
|
||||
|
||||
AktionsAbhoerer einAktionsAbhoerer = new AktionsAbhoerer();
|
||||
suchenDruckknopf.addActionListener(einAktionsAbhoerer);
|
||||
einfuegenDruckknopf.addActionListener(einAktionsAbhoerer);
|
||||
entfernenDruckknopf.addActionListener(einAktionsAbhoerer);
|
||||
demoDruckknopf.addActionListener(einAktionsAbhoerer);
|
||||
TastaturAbhoerer einTastaturAbhoerer = new TastaturAbhoerer();
|
||||
zeichenTextfeld.addKeyListener(einTastaturAbhoerer);
|
||||
traversierenDruckknopf.addActionListener(einAktionsAbhoerer);
|
||||
|
||||
addWindowListener(
|
||||
new WindowAdapter()
|
||||
{
|
||||
public void windowClosing(WindowEvent event)
|
||||
{
|
||||
setVisible(false);
|
||||
dispose();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
einBaum = new Baum<Character>();
|
||||
eineBaumAnsicht = new BaumAnsicht(einBaum);
|
||||
|
||||
updateBaumInfo();
|
||||
}
|
||||
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
eineBaumAnsicht.ausgeben(15, 500, 120, g);
|
||||
}
|
||||
|
||||
public void updateBaumInfo()
|
||||
{
|
||||
final int h = einBaum.hoehe();
|
||||
|
||||
infoLabel.setText("Der Baum hat eine H<>he von " + h + ".");
|
||||
}
|
||||
|
||||
// Innere Klassen
|
||||
class AktionsAbhoerer implements java.awt.event.ActionListener
|
||||
{
|
||||
public void actionPerformed(java.awt.event.ActionEvent event)
|
||||
{
|
||||
Object object = event.getSource();
|
||||
if ((object == einfuegenDruckknopf) || (object == entfernenDruckknopf) || (object == suchenDruckknopf))
|
||||
{
|
||||
String text = zeichenTextfeld.getText();
|
||||
if ((text != null) && (text.length() > 0))
|
||||
{
|
||||
char zeichen = text.charAt(0);
|
||||
|
||||
if (object == einfuegenDruckknopf)
|
||||
{
|
||||
einBaum.einfuegen(zeichen);
|
||||
zeichenTextfeld.setText("");
|
||||
repaint();
|
||||
updateBaumInfo();
|
||||
}
|
||||
else
|
||||
if (object == entfernenDruckknopf)
|
||||
{
|
||||
einBaum.entfernen(zeichen);
|
||||
repaint();
|
||||
updateBaumInfo();
|
||||
}
|
||||
else
|
||||
if (object == suchenDruckknopf)
|
||||
{
|
||||
enthaltenKontrollkaestchen.setState(einBaum.suchen(zeichen));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (object == traversierenDruckknopf)
|
||||
{
|
||||
ausgabeTextfeld.setText("Pre-Order:\n");
|
||||
ausgabeTextfeld.append(einBaum.traversierePreOrder());
|
||||
ausgabeTextfeld.append("\n\nIn-Order:\n");
|
||||
ausgabeTextfeld.append(einBaum.traversiereInOrder());
|
||||
ausgabeTextfeld.append("\n\nPost-Order:\n");
|
||||
ausgabeTextfeld.append(einBaum.traversierePostOrder());
|
||||
}
|
||||
else
|
||||
if (object == demoDruckknopf)
|
||||
{
|
||||
System.out.println("XXX");
|
||||
einBaum.attach(
|
||||
new Knoten<Character>('E',
|
||||
new Knoten<Character>('D',
|
||||
new Knoten<Character>('A',
|
||||
null,
|
||||
null),
|
||||
null),
|
||||
new Knoten<Character>('S',
|
||||
new Knoten<Character>('O',
|
||||
null,
|
||||
new Knoten<Character>('P',
|
||||
null,
|
||||
new Knoten<Character>('R',
|
||||
new Knoten<Character>('Q',
|
||||
null,
|
||||
null),
|
||||
null))),
|
||||
new Knoten<Character>('Z',
|
||||
null,
|
||||
null))));
|
||||
|
||||
repaint();
|
||||
updateBaumInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TastaturAbhoerer extends java.awt.event.KeyAdapter
|
||||
{
|
||||
public void keyReleased(java.awt.event.KeyEvent event)
|
||||
{
|
||||
if (event.getSource() == zeichenTextfeld)
|
||||
{
|
||||
String text = zeichenTextfeld.getText();
|
||||
if ((text != null) && (text.length() > 0))
|
||||
{
|
||||
char zeichen = text.charAt(0);
|
||||
|
||||
if (event.getKeyCode() == java.awt.event.KeyEvent.VK_ENTER)
|
||||
{
|
||||
einBaum.einfuegen(zeichen);
|
||||
zeichenTextfeld.setText("");
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
SS23/AuD/src/UEB06/BaumTest.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package UEB06;
|
||||
|
||||
public class BaumTest
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new BaumGUI().setVisible(true);
|
||||
}
|
||||
}
|
||||
50
SS23/AuD/src/UEB06/Knoten.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package UEB06;
|
||||
|
||||
public class Knoten<T>
|
||||
{
|
||||
private T daten;
|
||||
private Knoten<T> teilbaumLinks;
|
||||
private Knoten<T> teilbaumRechts;
|
||||
|
||||
public Knoten(T daten, Knoten<T> teilbaumLinks, Knoten<T> teilbaumRechts)
|
||||
{
|
||||
this.daten = daten;
|
||||
this.teilbaumLinks = teilbaumLinks;
|
||||
this.teilbaumRechts = teilbaumRechts;
|
||||
}
|
||||
|
||||
public T getDaten()
|
||||
{
|
||||
return daten;
|
||||
}
|
||||
|
||||
public Knoten<T> getKnotenLinks()
|
||||
{
|
||||
return teilbaumLinks;
|
||||
}
|
||||
|
||||
public Knoten<T> getKnotenRechts()
|
||||
{
|
||||
return teilbaumRechts;
|
||||
}
|
||||
|
||||
public void setDaten(T daten)
|
||||
{
|
||||
this.daten = daten;
|
||||
}
|
||||
|
||||
public void setKnotenLinks(Knoten<T> teilbaumLinks)
|
||||
{
|
||||
this.teilbaumLinks = teilbaumLinks;
|
||||
}
|
||||
|
||||
public void setKnotenRechts(Knoten<T> teilbaumRechts)
|
||||
{
|
||||
this.teilbaumRechts = teilbaumRechts;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return this.daten.toString();
|
||||
}
|
||||
}
|
||||
307
SS23/AuD/src/UEB07/AVLBaum.java
Normal file
@@ -0,0 +1,307 @@
|
||||
package UEB07;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class AVLBaum<T extends Comparable<T>>
|
||||
{
|
||||
private AVLKnoten<T> wurzel;
|
||||
private boolean hoeheGeaendert;
|
||||
|
||||
// Wird nur f<>r grafische Oberfl<66>che ben<65>tigt, ohne
|
||||
// diese Methode k<>nnte die gesamte Implementierung
|
||||
// des Baumes geheim gehalten werden. Alle <20>ffentlichen
|
||||
// Methoden sind parameterlos oder besitzen als
|
||||
// einzigen Parameter einen Schl<68>sselwert
|
||||
public AVLKnoten<T> getWurzel()
|
||||
{
|
||||
return wurzel;
|
||||
}
|
||||
|
||||
public boolean istLeer()
|
||||
{
|
||||
return (wurzel == null);
|
||||
}
|
||||
|
||||
|
||||
// Methoden zum Suchen
|
||||
|
||||
public boolean suchen(final T daten)
|
||||
{
|
||||
AVLKnoten<T> current = wurzel;
|
||||
System.out.println("a");
|
||||
while(current.getKnotenLinks()!=null && current.getKnotenRechts() != null){
|
||||
if(current.getDaten().equals(daten)){
|
||||
return true;
|
||||
}
|
||||
System.out.println(current.getDaten().compareTo(daten));
|
||||
switch (current.getDaten().compareTo(daten)) {
|
||||
case -1:
|
||||
System.out.println("-1");
|
||||
current = current.getKnotenRechts();
|
||||
break;
|
||||
case 0:
|
||||
System.out.println("0");
|
||||
return true;
|
||||
case 1:
|
||||
System.out.println("1");
|
||||
current = current.getKnotenLinks();
|
||||
break;
|
||||
}
|
||||
System.out.println("check");
|
||||
if(current.getDaten().equals(daten)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
System.out.println("a");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Methoden zum Einf<6E>gen
|
||||
|
||||
public void einfuegen(final T daten)
|
||||
{
|
||||
// Setzen der Merker-Variable hoeheGeandert auf false
|
||||
// Das wird zwar nach einem Links- oder Rechts-Ausgleich gemacht,
|
||||
// aber diese finden nicht statt, wenn ein bereits existierender
|
||||
// Schl<68>ssel wiederholt eingef<65>gt wird!
|
||||
hoeheGeaendert = false;
|
||||
|
||||
// Beim Einf<6E>gen wird der Baum neu zusammengesetzt, um Rotationen
|
||||
// zu erm<72>glichen. Daher tritt hier kein Sonderfall auf, aber die
|
||||
// Wurzel muss neu zugewiesen werden.
|
||||
wurzel = einfuegenKnoten(daten, wurzel);
|
||||
}
|
||||
|
||||
private AVLKnoten<T> einfuegenKnoten(final T daten, AVLKnoten<T> teilbaum)
|
||||
{
|
||||
if (teilbaum == null)
|
||||
{
|
||||
hoeheGeaendert = true;
|
||||
|
||||
return new AVLKnoten<T>(daten, null, null);
|
||||
}
|
||||
|
||||
// Vergleichs-Ergebnis zwischenspeichern, da compareTo()
|
||||
// aufw<66>ndig sein kann, und das Ergebnis mehrfach ben<65>tigt
|
||||
// wird
|
||||
final int cmp = daten.compareTo(teilbaum.getDaten());
|
||||
|
||||
if (cmp < 0)
|
||||
{
|
||||
// Einzuf<75>gende Daten sind KLEINER als Daten im aktuellen Knoten
|
||||
// und m<>ssen daher im LINKEN Teilbaum eingef<65>gt werden
|
||||
teilbaum.setKnotenLinks(einfuegenKnoten(daten, teilbaum.getKnotenLinks()));
|
||||
if (hoeheGeaendert)
|
||||
teilbaum = linksAusgleich(teilbaum);
|
||||
}
|
||||
else
|
||||
if (cmp > 0)
|
||||
{
|
||||
// Einzuf<75>gende Daten sind GROESSER als Daten im aktuellen Knoten
|
||||
// und m<>ssen daher im RECHTEN Teilbaum eingef<65>gt werden
|
||||
teilbaum.setKnotenRechts(einfuegenKnoten(daten, teilbaum.getKnotenRechts()));
|
||||
if (hoeheGeaendert)
|
||||
teilbaum = rechtsAusgleich(teilbaum);
|
||||
}
|
||||
|
||||
return teilbaum;
|
||||
}
|
||||
|
||||
private AVLKnoten<T> linksAusgleich(AVLKnoten<T> k)
|
||||
{
|
||||
AVLKnoten<T> x;
|
||||
|
||||
switch (k.getBalance())
|
||||
{
|
||||
case +1:
|
||||
{
|
||||
k.setBalance(0); // Der mit k beginnende Teilbaum ist jetzt balanciert
|
||||
hoeheGeaendert = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0: // Der mit k beginnende Teilbaum ist jetzt linkslastig
|
||||
{
|
||||
k.setBalance(-1);
|
||||
break;
|
||||
}
|
||||
|
||||
case -1: // Ausgleich notwendig
|
||||
{
|
||||
x = k.getKnotenLinks();
|
||||
|
||||
if (x.getBalance() == -1) // Fall 3a
|
||||
{
|
||||
k = rechtsRotation(k, x);
|
||||
}
|
||||
else
|
||||
if (x.getBalance() == +1) // Fall 3b
|
||||
{
|
||||
k = lrDoppelRotation(k, x);
|
||||
k.setBalance(0);
|
||||
}
|
||||
|
||||
k.setBalance(0);
|
||||
hoeheGeaendert = false;
|
||||
}
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
private AVLKnoten<T> rechtsAusgleich(AVLKnoten<T> k)
|
||||
{
|
||||
AVLKnoten<T> x;
|
||||
|
||||
switch (k.getBalance())
|
||||
{
|
||||
case -1:
|
||||
{
|
||||
k.setBalance(0); // Der mit k beginnende Teilbaum ist jetzt balanciert
|
||||
hoeheGeaendert = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0: // Der mit k beginnende Teilbaum ist jetzt rechtslastig
|
||||
{
|
||||
k.setBalance(+1);
|
||||
break;
|
||||
}
|
||||
|
||||
case +1: // Ausgleich notwendig
|
||||
{
|
||||
x = k.getKnotenRechts();
|
||||
|
||||
if (x.getBalance() == +1) // Fall 3a
|
||||
{
|
||||
k = linksRotation(k, x);
|
||||
}
|
||||
else
|
||||
if (x.getBalance() == -1) // Fall 3b
|
||||
{
|
||||
k = rlDoppelRotation(k, x);
|
||||
}
|
||||
|
||||
k.setBalance(0);
|
||||
hoeheGeaendert = false;
|
||||
}
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
private AVLKnoten<T> rechtsRotation(AVLKnoten<T> k, AVLKnoten<T> x)
|
||||
{
|
||||
k.setKnotenLinks(x.getKnotenRechts());
|
||||
x.setKnotenRechts(k);
|
||||
k.setBalance(0);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
private AVLKnoten<T> lrDoppelRotation(AVLKnoten<T> k, AVLKnoten<T> x)
|
||||
{
|
||||
AVLKnoten<T> y = x.getKnotenRechts();
|
||||
x.setKnotenRechts(y.getKnotenLinks());
|
||||
y.setKnotenLinks(x);
|
||||
k.setKnotenLinks(y.getKnotenRechts());
|
||||
y.setKnotenRechts(k);
|
||||
|
||||
switch (y.getBalance())
|
||||
{
|
||||
case -1:
|
||||
{
|
||||
k.setBalance(+1);
|
||||
x.setBalance(0);
|
||||
break;
|
||||
}
|
||||
case +1:
|
||||
{
|
||||
k.setBalance(0);
|
||||
x.setBalance(-1);
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
k.setBalance(0);
|
||||
x.setBalance(0);
|
||||
}
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
private AVLKnoten<T> linksRotation(AVLKnoten<T> k, AVLKnoten<T> x)
|
||||
{
|
||||
k.setKnotenRechts(x.getKnotenLinks());
|
||||
x.setKnotenLinks(k);
|
||||
k.setBalance(0);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
private AVLKnoten<T> rlDoppelRotation(AVLKnoten<T> k, AVLKnoten<T> x)
|
||||
{
|
||||
AVLKnoten<T> y = x.getKnotenLinks();
|
||||
x.setKnotenLinks(y.getKnotenRechts());
|
||||
y.setKnotenRechts(x);
|
||||
k.setKnotenRechts(y.getKnotenLinks());
|
||||
y.setKnotenLinks(k);
|
||||
|
||||
switch (y.getBalance())
|
||||
{
|
||||
case +1:
|
||||
{
|
||||
k.setBalance(-1);
|
||||
x.setBalance(0);
|
||||
break;
|
||||
}
|
||||
case -1:
|
||||
{
|
||||
k.setBalance(0);
|
||||
x.setBalance(+1);
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
k.setBalance(0);
|
||||
x.setBalance(0);
|
||||
}
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
// Methode zum Traversieren
|
||||
|
||||
// Pre-Order
|
||||
public String traversierePreOrder()
|
||||
{
|
||||
if (wurzel == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
Deque<AVLKnoten> nodeStack = new LinkedList<>();
|
||||
nodeStack.push(wurzel);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
while (!nodeStack.isEmpty()) {
|
||||
AVLKnoten node = nodeStack.pop();
|
||||
sb.append(node.getDaten()).append(" ");
|
||||
|
||||
if (node.getKnotenRechts() != null) {
|
||||
nodeStack.push(node.getKnotenRechts());
|
||||
}
|
||||
if (node.getKnotenLinks() != null) {
|
||||
nodeStack.push(node.getKnotenLinks());
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
}
|
||||
61
SS23/AuD/src/UEB07/AVLKnoten.java
Normal file
@@ -0,0 +1,61 @@
|
||||
package UEB07;
|
||||
public class AVLKnoten<T>
|
||||
{
|
||||
private T daten;
|
||||
private AVLKnoten<T> teilbaumLinks;
|
||||
private AVLKnoten<T> teilbaumRechts;
|
||||
private int balance; // -1 linkslastig; 0 ausgeglichen; +1 rechtslastig
|
||||
|
||||
public AVLKnoten(T daten, AVLKnoten<T> teilbaumLinks, AVLKnoten<T> teilbaumRechts)
|
||||
{
|
||||
this.daten = daten;
|
||||
this.teilbaumLinks = teilbaumLinks;
|
||||
this.teilbaumRechts = teilbaumRechts;
|
||||
this.balance = 0;
|
||||
}
|
||||
|
||||
public T getDaten()
|
||||
{
|
||||
return daten;
|
||||
}
|
||||
|
||||
public AVLKnoten<T> getKnotenLinks()
|
||||
{
|
||||
return teilbaumLinks;
|
||||
}
|
||||
|
||||
public AVLKnoten<T> getKnotenRechts()
|
||||
{
|
||||
return teilbaumRechts;
|
||||
}
|
||||
|
||||
public int getBalance()
|
||||
{
|
||||
return balance;
|
||||
}
|
||||
|
||||
public void setDaten(T daten)
|
||||
{
|
||||
this.daten = daten;
|
||||
}
|
||||
|
||||
public void setKnotenLinks(AVLKnoten<T> teilbaumLinks)
|
||||
{
|
||||
this.teilbaumLinks = teilbaumLinks;
|
||||
}
|
||||
|
||||
public void setKnotenRechts(AVLKnoten<T> teilbaumRechts)
|
||||
{
|
||||
this.teilbaumRechts = teilbaumRechts;
|
||||
}
|
||||
|
||||
public void setBalance(int balance)
|
||||
{
|
||||
this.balance = balance;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return this.daten.toString();
|
||||
}
|
||||
}
|
||||
40
SS23/AuD/src/UEB07/BaumAnsicht.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package UEB07;
|
||||
import java.awt.*;
|
||||
|
||||
public class BaumAnsicht
|
||||
{
|
||||
private AVLBaum<Character> einBaum;
|
||||
|
||||
public BaumAnsicht(AVLBaum<Character> einBaum)
|
||||
{
|
||||
this.einBaum = einBaum;
|
||||
}
|
||||
|
||||
public void ausgeben(int xLinks, int xRechts, int y, Graphics g)
|
||||
{
|
||||
g.setColor(new Color(240, 240, 240));
|
||||
g.fillRect(xLinks, 100, xRechts, 190);
|
||||
|
||||
ausgebenTeilbaum(einBaum.getWurzel(), -1, -1, xLinks, xRechts, y, g);
|
||||
}
|
||||
|
||||
public void ausgebenTeilbaum(AVLKnoten teilbaum, int xParent, int yParent, int xLinks, int xRechts, int y, Graphics g)
|
||||
{
|
||||
if (teilbaum != null)
|
||||
{
|
||||
final int mitte = (xLinks + xRechts) / 2;
|
||||
|
||||
g.setColor(Color.black);
|
||||
g.drawString(teilbaum.toString(), mitte - 2, y);
|
||||
|
||||
if ((xParent != -1) && (yParent != -1))
|
||||
{
|
||||
g.setColor(new Color(192, 192, 192));
|
||||
g.drawLine(xParent, yParent, mitte, y-12);
|
||||
}
|
||||
|
||||
ausgebenTeilbaum(teilbaum.getKnotenLinks(), mitte, y + 4, xLinks + 4, mitte - 4, y + 30, g);
|
||||
ausgebenTeilbaum(teilbaum.getKnotenRechts(), mitte, y + 4, mitte + 4, xRechts + 4, y + 30, g);
|
||||
}
|
||||
}
|
||||
}
|
||||
133
SS23/AuD/src/UEB07/BaumGUI.java
Normal file
@@ -0,0 +1,133 @@
|
||||
package UEB07;
|
||||
import java.awt.*;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
|
||||
public class BaumGUI extends Frame
|
||||
{
|
||||
private AVLBaum<Character> einBaum;
|
||||
private BaumAnsicht eineBaumAnsicht;
|
||||
|
||||
private java.awt.Label zeichenFuehrungstext = new java.awt.Label();
|
||||
private java.awt.TextField zeichenTextfeld = new java.awt.TextField();
|
||||
private java.awt.Button einfuegenDruckknopf = new java.awt.Button();
|
||||
private java.awt.Button suchenDruckknopf = new java.awt.Button();
|
||||
private java.awt.Checkbox enthaltenKontrollkaestchen = new java.awt.Checkbox();
|
||||
private java.awt.TextArea ausgabeTextfeld = new java.awt.TextArea("",0,0,TextArea.SCROLLBARS_NONE);
|
||||
private java.awt.Button traversierenDruckknopf = new java.awt.Button();
|
||||
|
||||
public BaumGUI()
|
||||
{
|
||||
setLayout(null);
|
||||
setSize(530,485);
|
||||
zeichenFuehrungstext.setText("Zeichen:");
|
||||
zeichenFuehrungstext.setAlignment(java.awt.Label.RIGHT);
|
||||
add(zeichenFuehrungstext);
|
||||
zeichenFuehrungstext.setBounds(12,32,48,24);
|
||||
add(zeichenTextfeld);
|
||||
zeichenTextfeld.setBounds(72,32,48,24);
|
||||
einfuegenDruckknopf.setLabel("Einf<EFBFBD>gen");
|
||||
add(einfuegenDruckknopf);
|
||||
einfuegenDruckknopf.setBackground(java.awt.Color.lightGray);
|
||||
einfuegenDruckknopf.setBounds(228,32,84,24);
|
||||
suchenDruckknopf.setLabel("Suchen");
|
||||
add(suchenDruckknopf);
|
||||
suchenDruckknopf.setBackground(java.awt.Color.lightGray);
|
||||
suchenDruckknopf.setBounds(132,32,84,24);
|
||||
enthaltenKontrollkaestchen.setLabel("Im Baum enthalten");
|
||||
enthaltenKontrollkaestchen.setEnabled(false);
|
||||
add(enthaltenKontrollkaestchen);
|
||||
enthaltenKontrollkaestchen.setBounds(132,68,132,24);
|
||||
add(ausgabeTextfeld);
|
||||
ausgabeTextfeld.setBounds(14,330,500,144);
|
||||
traversierenDruckknopf.setLabel("Traversieren");
|
||||
add(traversierenDruckknopf);
|
||||
traversierenDruckknopf.setBackground(java.awt.Color.lightGray);
|
||||
traversierenDruckknopf.setBounds(14,300,127,26);
|
||||
|
||||
AktionsAbhoerer einAktionsAbhoerer = new AktionsAbhoerer();
|
||||
einfuegenDruckknopf.addActionListener(einAktionsAbhoerer);
|
||||
suchenDruckknopf.addActionListener(einAktionsAbhoerer);
|
||||
TastaturAbhoerer einTastaturAbhoerer = new TastaturAbhoerer();
|
||||
zeichenTextfeld.addKeyListener(einTastaturAbhoerer);
|
||||
traversierenDruckknopf.addActionListener(einAktionsAbhoerer);
|
||||
|
||||
addWindowListener(
|
||||
new WindowAdapter()
|
||||
{
|
||||
public void windowClosing(WindowEvent event)
|
||||
{
|
||||
setVisible(false);
|
||||
dispose();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
einBaum = new AVLBaum<Character>();
|
||||
eineBaumAnsicht = new BaumAnsicht(einBaum);
|
||||
}
|
||||
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
eineBaumAnsicht.ausgeben(15, 500, 120, g);
|
||||
}
|
||||
|
||||
// Innere Klassen
|
||||
class AktionsAbhoerer implements java.awt.event.ActionListener
|
||||
{
|
||||
public void actionPerformed(java.awt.event.ActionEvent event)
|
||||
{
|
||||
Object object = event.getSource();
|
||||
if ((object == einfuegenDruckknopf) || (object == suchenDruckknopf))
|
||||
{
|
||||
String text = zeichenTextfeld.getText();
|
||||
if ((text != null) && (text.length() > 0))
|
||||
{
|
||||
char zeichen = text.charAt(0);
|
||||
|
||||
if (object == einfuegenDruckknopf)
|
||||
{
|
||||
einBaum.einfuegen(zeichen);
|
||||
zeichenTextfeld.setText("");
|
||||
repaint();
|
||||
}
|
||||
else
|
||||
if (object == suchenDruckknopf)
|
||||
{
|
||||
enthaltenKontrollkaestchen.setState(einBaum.suchen(zeichen));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (object == traversierenDruckknopf)
|
||||
{
|
||||
ausgabeTextfeld.setText("Pre-Order:\n" + einBaum.traversierePreOrder());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TastaturAbhoerer extends java.awt.event.KeyAdapter
|
||||
{
|
||||
public void keyReleased(java.awt.event.KeyEvent event)
|
||||
{
|
||||
if (event.getSource() == zeichenTextfeld)
|
||||
{
|
||||
String text = zeichenTextfeld.getText();
|
||||
if ((text != null) && (text.length() > 0))
|
||||
{
|
||||
char zeichen = text.charAt(0);
|
||||
|
||||
if(event.getKeyCode() == java.awt.event.KeyEvent.VK_ENTER)
|
||||
{
|
||||
einBaum.einfuegen(zeichen);
|
||||
zeichenTextfeld.setText("");
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8
SS23/AuD/src/UEB07/BaumTest.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package UEB07;
|
||||
public class BaumTest
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new BaumGUI().setVisible(true);
|
||||
}
|
||||
}
|
||||
63
SS23/AuD/src/UEB08/BBaum.java
Normal file
@@ -0,0 +1,63 @@
|
||||
package UEB08;
|
||||
class BBaum<T extends Comparable<T>>
|
||||
{
|
||||
public BKnoten<T> wurzel;
|
||||
|
||||
public BBaum(BKnoten<T> wurzel)
|
||||
{
|
||||
assert(wurzel != null);
|
||||
|
||||
this.wurzel = wurzel;
|
||||
}
|
||||
|
||||
// Wrapper-Methode
|
||||
public void traversieren()
|
||||
{
|
||||
traversieren(wurzel);
|
||||
}
|
||||
|
||||
// Eigentliche Implementierung
|
||||
private void traversieren(BKnoten<T> knoten)
|
||||
{
|
||||
assert(knoten != null);
|
||||
int i = 0;
|
||||
if(knoten.kinder.length!=0){
|
||||
//System.out.println(knoten.kinder.length +" "+ knoten.elemente.length);
|
||||
for(i = 0; i < knoten.elemente.length;i++){
|
||||
if (knoten.kinder[i]!=null){
|
||||
traversieren(knoten.kinder[i]);
|
||||
}
|
||||
System.out.println(knoten.elemente[i]);
|
||||
}
|
||||
if (knoten.kinder[i]!=null){
|
||||
traversieren(knoten.kinder[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper-Methode
|
||||
public boolean suchen(final T daten)
|
||||
{
|
||||
assert(daten != null);
|
||||
|
||||
return suchen(daten, wurzel);
|
||||
}
|
||||
|
||||
// Eigentliche Implementierung
|
||||
private boolean suchen(final T daten, BKnoten<T> knoten)
|
||||
{
|
||||
for(int i=0;i<knoten.elemente.length;i++){
|
||||
if(knoten.elemente[i].equals(daten)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (int i = 0;i<knoten.kinder.length;i++){
|
||||
if(knoten.kinder[i]!= null){
|
||||
if(suchen(daten,knoten.kinder[i])){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
44
SS23/AuD/src/UEB08/BBaumTest.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package UEB08;
|
||||
public class BBaumTest
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// B-Baum erzeugen
|
||||
BBaum<Integer> baum = new BBaum<Integer>(
|
||||
new BKnoten<Integer>(new Integer[]{ 19, 34 }, new BKnoten[]{
|
||||
new BKnoten<Integer>(new Integer[]{ 4, 7, 10, 14 }, new BKnoten[]{
|
||||
new BKnoten<Integer>(new Integer[]{ 1, 2, 3 } ),
|
||||
new BKnoten<Integer>(new Integer[]{ 5, 6 } ),
|
||||
new BKnoten<Integer>(new Integer[]{ 8, 9 } ),
|
||||
new BKnoten<Integer>(new Integer[]{ 11, 12, 13 } ),
|
||||
new BKnoten<Integer>(new Integer[]{ 15, 16, 17, 18 } )
|
||||
} ),
|
||||
new BKnoten<Integer>(new Integer[]{ 22, 27, 30 }, new BKnoten[]{
|
||||
new BKnoten<Integer>(new Integer[]{ 20, 21 } ),
|
||||
new BKnoten<Integer>(new Integer[]{ 23, 24, 25, 26 } ),
|
||||
new BKnoten<Integer>(new Integer[]{ 28, 29 } ),
|
||||
new BKnoten<Integer>(new Integer[]{ 31, 32, 33 } )
|
||||
} ),
|
||||
new BKnoten<Integer>(new Integer[]{ 39, 42 }, new BKnoten[]{
|
||||
new BKnoten<Integer>(new Integer[]{ 35, 36, 37, 38 } ),
|
||||
new BKnoten<Integer>(new Integer[]{ 40, 41 } ),
|
||||
new BKnoten<Integer>(new Integer[]{ 43, 44, 45 } )
|
||||
} )
|
||||
} )
|
||||
);
|
||||
|
||||
// B-Baum traversieren
|
||||
System.out.println("Traversieren:");
|
||||
|
||||
baum.traversieren();
|
||||
|
||||
// Nach Elementen suchen
|
||||
System.out.println("\n\nSuchen:");
|
||||
|
||||
boolean suchen = true;
|
||||
for (int a = -50; a < 100; a++)
|
||||
suchen &= (baum.suchen(a) == ((a >=1 ) && (a <= 45)));
|
||||
|
||||
System.out.println(suchen ? "Ok" : "Fehler!");
|
||||
}
|
||||
}
|
||||
26
SS23/AuD/src/UEB08/BKnoten.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package UEB08;
|
||||
public class BKnoten<T>
|
||||
{
|
||||
public T[] elemente;
|
||||
public BKnoten<T>[] kinder;
|
||||
|
||||
// F<>r Bl<42>tter
|
||||
public BKnoten(final T[] elemente)
|
||||
{
|
||||
assert(elemente!=null);
|
||||
|
||||
this.elemente = elemente;
|
||||
this.kinder = (BKnoten<T>[])new BKnoten[elemente.length + 1];
|
||||
}
|
||||
|
||||
// F<>r innere Knoten
|
||||
public BKnoten(final T[] elemente, final BKnoten<T>[] kinder)
|
||||
{
|
||||
assert(elemente != null);
|
||||
assert(kinder != null);
|
||||
assert(elemente.length+1 == kinder.length);
|
||||
|
||||
this.elemente = elemente;
|
||||
this.kinder = kinder;
|
||||
}
|
||||
}
|
||||
38
SS23/AuD/src/UEB10/BasicSort.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package UEB10;
|
||||
|
||||
public class BasicSort
|
||||
{
|
||||
// Selectionsort:
|
||||
// Sortiere das Teilfeld von array beginnend mit Index links bis einschlie<69>lich Index rechts
|
||||
public static void selectionsort(int[] array, final int links, final int rechts)
|
||||
{
|
||||
for (int i = links; i < rechts; i++)
|
||||
{
|
||||
// Kleinstes Element im unsortierten Teil finden
|
||||
int min = i;
|
||||
|
||||
for (int j = i + 1; j <= rechts; j++)
|
||||
if (array[min] > array[j])
|
||||
min = j;
|
||||
|
||||
// Elemente tauschen
|
||||
int temp = array[min];
|
||||
array[min] = array[i];
|
||||
array[i] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// Insertionsort:
|
||||
// Sortiere das Teilfeld von array beginnend mit Index links bis einschlie<69>lich Index rechts
|
||||
public static void insertionsort(int[] array, final int links, final int rechts)
|
||||
{
|
||||
// TODO: Praktikum 9
|
||||
}
|
||||
|
||||
// Bubblesort:
|
||||
// Sortiere das Teilfeld von array beginnend mit Index links bis einschlie<69>lich Index rechts
|
||||
public static void bubblesort(int[] array, final int links, final int rechts)
|
||||
{
|
||||
// TODO: Praktikum 9
|
||||
}
|
||||
}
|
||||
43
SS23/AuD/src/UEB10/HeapSort.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package UEB10;
|
||||
public class HeapSort {
|
||||
// Versickere das Element mit Index pos in dem Teilfeld von Index links bis einschlie<69>lich Index rechts
|
||||
public static void versickere(int[] array, final int links, int pos, final int rechts) {
|
||||
int groesster = pos;
|
||||
int l = 2 * (pos - links) + 1 + links;
|
||||
int r = 2 * (pos - links) + 2 + links;
|
||||
|
||||
if (l <= rechts && array[l] > array[groesster])
|
||||
groesster = l;
|
||||
|
||||
if (r <= rechts && array[r] > array[groesster])
|
||||
groesster = r;
|
||||
|
||||
if (groesster != pos) {
|
||||
int swap = array[pos];
|
||||
array[pos] = array[groesster];
|
||||
array[groesster] = swap;
|
||||
|
||||
versickere(array, links, groesster, rechts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void heapsort(int[] array, final int links, final int rechts) {
|
||||
int n = rechts - links + 1;
|
||||
|
||||
// Heap aufbauen
|
||||
for (int i = links + n / 2 - 1; i >= links; i--)
|
||||
versickere(array, links, i, rechts);
|
||||
|
||||
// Eines nach dem anderen ein Element aus dem Heap extrahieren
|
||||
for (int i = rechts; i >= links; i--) {
|
||||
// Aktuelle Wurzel ans Ende verschieben
|
||||
int temp = array[links];
|
||||
array[links] = array[i];
|
||||
array[i] = temp;
|
||||
|
||||
// max heapify auf dem reduzierten Heap aufrufen
|
||||
versickere(array, links, links, i - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
128
SS23/AuD/src/UEB10/Main.java
Normal file
@@ -0,0 +1,128 @@
|
||||
package UEB10;
|
||||
public class Main
|
||||
{
|
||||
public static final int SELECTIONSORT = 0;
|
||||
public static final int INSERTIONSORT = 1;
|
||||
public static final int BUBBLESORT = 2;
|
||||
public static final int QUICKSORT = 3;
|
||||
public static final int HEAPSORT = 4;
|
||||
public static final int MERGESORT = 5;
|
||||
|
||||
public static final int ANZAHLALGORITHMEN = 6;
|
||||
public static final int N = 10000;
|
||||
|
||||
public static final String[] sortNames =
|
||||
{
|
||||
"Selection Sort",
|
||||
"Insertion Sort",
|
||||
"Bubblesort",
|
||||
"Quicksort",
|
||||
"Heapsort",
|
||||
"Mergesort"
|
||||
};
|
||||
|
||||
// Gibt ein Array mit n Elementen und zuf<75>lligen Zahlen zur<75>ck
|
||||
public static int[] getRandomArray(final int n)
|
||||
{
|
||||
int[] array = new int[n];
|
||||
|
||||
for (int a = 0; a < n ; a++)
|
||||
array[a] = (int)(Math.random()*10*n);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
// Pr<50>ft, ob ein Array korrekt sortiert ist
|
||||
public static boolean checkArray(int[] array)
|
||||
{
|
||||
for (int a = 0; a < array.length-1; a++)
|
||||
if (array[a] > array[a+1])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Pr<50>ft einen Algorithmus, und gibt die Laufzeiten aus
|
||||
public static void checkSortAlgorithmus(final int algorithmus)
|
||||
{
|
||||
StopUhr stopUhr = new StopUhr();
|
||||
|
||||
boolean isCorrect = true;
|
||||
long minTime = 0;
|
||||
long maxTime = 0;
|
||||
long sumTime = 0;
|
||||
|
||||
// Wir testen mit 100 zuf<75>llig erzeugten Feldern
|
||||
for (int a = 0; a < 100; a++)
|
||||
{
|
||||
int[] array = getRandomArray(N);
|
||||
|
||||
// Zeitmessung beginnen
|
||||
stopUhr.start();
|
||||
|
||||
// Array sortieren
|
||||
switch (algorithmus)
|
||||
{
|
||||
case INSERTIONSORT:
|
||||
BasicSort.insertionsort(array, 0, array.length - 1);
|
||||
break;
|
||||
|
||||
case SELECTIONSORT:
|
||||
BasicSort.selectionsort(array, 0, array.length - 1);
|
||||
break;
|
||||
|
||||
case BUBBLESORT:
|
||||
BasicSort.bubblesort(array, 0, array.length - 1);
|
||||
break;
|
||||
|
||||
case QUICKSORT:
|
||||
QuickSort.quicksort(array, 0, array.length - 1);
|
||||
break;
|
||||
|
||||
case HEAPSORT:
|
||||
HeapSort.heapsort(array, 0, array.length - 1);
|
||||
break;
|
||||
|
||||
case MERGESORT:
|
||||
MergeSort.mergesort(array, 0, array.length - 1);
|
||||
break;
|
||||
}
|
||||
|
||||
// Zeitmessung stoppen
|
||||
stopUhr.stop();
|
||||
|
||||
// Ergebnis auswerten
|
||||
if (!(isCorrect &= checkArray(array)))
|
||||
break;
|
||||
|
||||
if ((a==0) || (stopUhr.getDuration()<minTime))
|
||||
minTime = stopUhr.getDuration();
|
||||
|
||||
if (stopUhr.getDuration()>maxTime)
|
||||
maxTime = stopUhr.getDuration();
|
||||
|
||||
sumTime += stopUhr.getDuration();
|
||||
}
|
||||
|
||||
// Ausgabe
|
||||
if (isCorrect)
|
||||
{
|
||||
System.out.format("%16s %10.4f %10.4f %10.4f\n",
|
||||
sortNames[algorithmus], minTime / 1000000.0, sumTime / 100000000.0, maxTime / 1000000.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.format("%16s %10s\n", sortNames[algorithmus], "-");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
System.out.println("Arraygr<EFBFBD><EFBFBD>e n = " + N + "\n");
|
||||
System.out.println(" Algorithmus Laufzeit (ms)");
|
||||
System.out.println(" minimal durchschnittlich maximal");
|
||||
|
||||
for (int algorithmus = 0; algorithmus < ANZAHLALGORITHMEN; algorithmus++)
|
||||
checkSortAlgorithmus(algorithmus);
|
||||
}
|
||||
}
|
||||
88
SS23/AuD/src/UEB10/MergeSort.java
Normal file
@@ -0,0 +1,88 @@
|
||||
|
||||
package UEB10;
|
||||
public class MergeSort
|
||||
{
|
||||
public static void mergesort(int[] array, final int links, final int rechts)
|
||||
{
|
||||
int[] hilfsarray = new int[array.length];
|
||||
|
||||
mergesortBU(array, hilfsarray, links, rechts);
|
||||
}
|
||||
|
||||
// Top-Down-Mergesort entsprechend der Vorlesung
|
||||
public static void mergesortTD(int[] array, int[] hilfsarray, final int links, final int rechts)
|
||||
{
|
||||
if (links < rechts)
|
||||
{
|
||||
// mindestens 2 Elemente
|
||||
int mitte = (links + rechts)/2;
|
||||
// Feld in der Mitte teilen und rekursive Aufrufe f<>r Teilfelder
|
||||
mergesortTD(array, hilfsarray, links, mitte);
|
||||
mergesortTD(array, hilfsarray, mitte+1, rechts);
|
||||
// Sortierte Teilfelder mischen
|
||||
merge(array, hilfsarray, links, mitte, rechts);
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom-Up-Mergesort
|
||||
public static void mergesortBU(int[] array, int[] hilfsarray, final int links, final int rechts)
|
||||
{
|
||||
int n = rechts - links + 1;
|
||||
for (int len = 1; len < n; len *= 2) {
|
||||
for (int lo = links; lo < rechts - len + 1; lo += len+len) {
|
||||
int mid = lo+len-1;
|
||||
int hi = Math.min(lo+len+len-1, rechts);
|
||||
merge(array, hilfsarray, lo, mid, hi);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Mischen der Teilfelder array[links]...array[mitte] und array[mitte+1]...array[rechts]
|
||||
private static void merge(int[] array, int[] hilfsarray, final int links, final int mitte, final int rechts)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
i = links;
|
||||
j = mitte+1;
|
||||
|
||||
// Mischen in Hilfsarray
|
||||
for (int k=links; k <= rechts; k++)
|
||||
{
|
||||
if (i>mitte)
|
||||
hilfsarray[k] = array[j++]; // 1. Teilfeld schon zu Ende
|
||||
else if (j>rechts)
|
||||
hilfsarray[k] = array[i++]; // 2. Zeilfeld schon zu Ende
|
||||
else if(array[i] < array[j])
|
||||
hilfsarray[k] = array[i++]; // Element aus 1. Teilfeld <20>bernehmen
|
||||
else
|
||||
hilfsarray[k] = array[j++]; // Element aus 2. teilfeld <20>bernehmen
|
||||
}
|
||||
|
||||
|
||||
for (int k = links; k <= rechts; k++)
|
||||
{
|
||||
array[k] = hilfsarray[k];
|
||||
}
|
||||
}
|
||||
|
||||
// Alternative Metdode zum Mischen
|
||||
private static void merge2(int[] array, int[] hilfsarray, final int links, final int mitte, final int rechts)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
// 1. Teilfeld kopieren
|
||||
for (i = mitte+1; i > links; i--)
|
||||
hilfsarray[i-1] = array[i-1];
|
||||
// 2. Teilfeld in umgekehrter Reihenfolge kopieren
|
||||
for (j = mitte; j < rechts; j++)
|
||||
hilfsarray[rechts+mitte-j] = array[j+1];
|
||||
|
||||
// Zeiger i und j gegeneinander laufen lassen
|
||||
for (int k = links; k <= rechts; k++ )
|
||||
if (hilfsarray[j] < hilfsarray[i])
|
||||
array[k] = hilfsarray[j--];
|
||||
else
|
||||
array[k] = hilfsarray[i++];
|
||||
}
|
||||
}
|
||||
8
SS23/AuD/src/UEB10/QuickSort.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package UEB10;
|
||||
public class QuickSort
|
||||
{
|
||||
public static void quicksort(int[] array, final int links, final int rechts)
|
||||
{
|
||||
// TODO: Praktikum 9
|
||||
}
|
||||
}
|
||||
20
SS23/AuD/src/UEB10/StopUhr.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package UEB10;
|
||||
public class StopUhr
|
||||
{
|
||||
private long startTime, stopTime;
|
||||
|
||||
public void start()
|
||||
{
|
||||
startTime = System.nanoTime();
|
||||
}
|
||||
|
||||
public void stop()
|
||||
{
|
||||
stopTime = System.nanoTime();
|
||||
}
|
||||
|
||||
public long getDuration()
|
||||
{
|
||||
return stopTime - startTime;
|
||||
}
|
||||
}
|
||||
125
SS23/AuD/src/UEB11/HashTable.java
Normal file
@@ -0,0 +1,125 @@
|
||||
package UEB11;
|
||||
public class HashTable
|
||||
{
|
||||
private static final int START_TABELLENGROESSE = 10; // Standardgr<67><72>e
|
||||
|
||||
private IHashable[] table; // Array f<>r Hash-Objekte
|
||||
private int currentSize; // Die Anzahl der belegten Slots
|
||||
|
||||
public HashTable()
|
||||
{
|
||||
this(START_TABELLENGROESSE);
|
||||
}
|
||||
|
||||
// Konstruktor mit expliziter Gr<47><72>enangabe
|
||||
public HashTable(final int groesse)
|
||||
{
|
||||
assert(groesse > 0);
|
||||
|
||||
table = new IHashable[groesse];
|
||||
clear();
|
||||
}
|
||||
|
||||
// F<>gt ein Objekt in die Hashtabelle ein.
|
||||
// Falls der Eintrag bereits existiert passiert NICHTS!
|
||||
public void insert(final IHashable o)
|
||||
{
|
||||
assert(o != null);
|
||||
|
||||
final int currentPos = findePosition(o);
|
||||
|
||||
if (table[currentPos] == null)
|
||||
{
|
||||
table[currentPos] = o;
|
||||
|
||||
if (++currentSize > table.length / 2)
|
||||
rehash();
|
||||
}
|
||||
}
|
||||
|
||||
// Erweiterung der Hashtabelle
|
||||
private void rehash()
|
||||
{
|
||||
// Debug-Ausgabe
|
||||
System.out.println("rehash(" + table.length+ ")");
|
||||
|
||||
// Kopie der alten Hashtabelle anlegen
|
||||
IHashable[] oldTable = table;
|
||||
|
||||
// Erzeuge table mit mindestens der doppelten Gr<47><72>e
|
||||
// (f<>hrt zu O(log n) Vergr<67><72>erungs-Operationen f<>r n Objekte)
|
||||
table = new IHashable[nextPrime(2 * oldTable.length)];
|
||||
|
||||
currentSize = 0;
|
||||
|
||||
// Einsortieren der Elemente ins neue Array
|
||||
for (int a = 0; a < oldTable.length; a++)
|
||||
if (oldTable[a] != null)
|
||||
insert(oldTable[a]);
|
||||
}
|
||||
|
||||
// Quadratisches Sondieren
|
||||
public int findePosition(IHashable o)
|
||||
{
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Findet ein Objekt in der Hashtabelle
|
||||
public IHashable find(IHashable o)
|
||||
{
|
||||
return table[findePosition(o)];
|
||||
}
|
||||
|
||||
// L<>schen der gesamten Hashtabelle
|
||||
public void clear()
|
||||
{
|
||||
for (int a = 0; a < table.length; a++)
|
||||
table[a] = null;
|
||||
|
||||
currentSize = 0;
|
||||
}
|
||||
|
||||
// Test-Methode
|
||||
public IHashable getEntry(final int pos)
|
||||
{
|
||||
return table[pos];
|
||||
}
|
||||
|
||||
// Test-Methode
|
||||
public int getSize()
|
||||
{
|
||||
return table.length;
|
||||
}
|
||||
|
||||
// Private Funktion, die zu einer vorgegebenen Zahl n die n<>chsth<74>here Primzahl findet
|
||||
private static int nextPrime(int n)
|
||||
{
|
||||
assert(n >= 0);
|
||||
|
||||
// N<>chste ungerade Zahl
|
||||
n |= 1;
|
||||
|
||||
while (!isPrime(n))
|
||||
n += 2;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
// Testet, ob eine Zahl eine Primzahl ist (einfache, aber ineffiziente Implementierung)
|
||||
private static boolean isPrime(final int n)
|
||||
{
|
||||
if ((n == 2) || (n == 3))
|
||||
return true;
|
||||
|
||||
if ((n == 1) || ((n & 1) == 0))
|
||||
return false;
|
||||
|
||||
for (int a = 3; a * a <= n; a += 2)
|
||||
if ((n % a) == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
75
SS23/AuD/src/UEB11/HashTableTest.java
Normal file
@@ -0,0 +1,75 @@
|
||||
package UEB11;
|
||||
|
||||
public class HashTableTest
|
||||
{
|
||||
private static String[][] Profs =
|
||||
{
|
||||
{"Bab", "8305"},
|
||||
{"B<EFBFBD>ckmann", "6728"},
|
||||
{"Cleven", "6732"},
|
||||
{"Ecke-Sch<63>th", "6784"},
|
||||
{"Engels", "6777"},
|
||||
{"Friedrich", "6796"},
|
||||
{"Haake", "6766"},
|
||||
{"Haas", "6719"},
|
||||
{"Hagen", "6782"},
|
||||
{"Hamburg", "6708"},
|
||||
{"Harrer", "6748"},
|
||||
{"Hesseler", "6732"},
|
||||
{"Hessel-von Molo", "6779"},
|
||||
{"Hirsch", "6835"},
|
||||
{"Hoffmann", "0"},
|
||||
{"J<EFBFBD>rges", "6741"},
|
||||
{"Kamsties", "6816"},
|
||||
{"Kienle", "9777"},
|
||||
{"K<EFBFBD>nisgmann", "6776"},
|
||||
{"Kuhnt", "8935"},
|
||||
{"Kukuk", "6715"},
|
||||
{"Kunau", "8906"},
|
||||
{"K<EFBFBD>nemund", "6764"},
|
||||
{"Lauenroth", "0"},
|
||||
{"Lenze", "6729"},
|
||||
{"Lu", "6758"},
|
||||
{"Preis", "6756"},
|
||||
{"Recker", "6783"},
|
||||
{"Reimann", "6786"},
|
||||
{"Rettinger", "6797"},
|
||||
{"R<EFBFBD>hrig", "8100"},
|
||||
{"Saatz", "6765"},
|
||||
{"Sachweh", "6760"},
|
||||
{"Sch<EFBFBD>nberg", "8919"},
|
||||
{"Schuster", "8903"},
|
||||
{"Stark", "6747"},
|
||||
{"Teschler-Nunkesser", "6785"},
|
||||
{"Vollmer", "6737"},
|
||||
{"Wiesmann", "8918"},
|
||||
{"Wolff", "0"},
|
||||
{"Zeppenfeld", "0"}
|
||||
};
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
HashTable h = new HashTable(10);
|
||||
|
||||
System.out.println("Hashtablle mit " + Profs.length + " Objekten anlegen:");
|
||||
|
||||
// Professorendaten in Hashtabelle eintragen
|
||||
for (int a = 0; a < Profs.length; a++)
|
||||
h.insert(new Professor(Profs[a][0], Integer.parseInt(Profs[a][1])));
|
||||
|
||||
// Gespeicherte Professorendaten nacheinander aus der Tabelle
|
||||
// auslesen und den jeweils zugeh<65>rigen Namen ausgeben
|
||||
System.out.println("\nHash-Tabelle:");
|
||||
for (int a = 0; a < h.getSize(); a++)
|
||||
{
|
||||
final Professor p = (Professor)h.getEntry(a);
|
||||
if (p != null)
|
||||
System.out.println(a + " " + p.getName());
|
||||
}
|
||||
|
||||
System.out.println("\nZuordnung per Roundtrip <20>ber den Hashwert testen:");
|
||||
for (int a = 0; a < h.getSize(); a++)
|
||||
if ((Professor)h.getEntry(a) != null)
|
||||
System.out.println("" + a + " <---> " + h.findePosition(h.getEntry(a)));
|
||||
}
|
||||
}
|
||||
7
SS23/AuD/src/UEB11/IHashable.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package UEB11;
|
||||
public interface IHashable
|
||||
{
|
||||
// Es wird gefordert, dass von den Objekten, die gespeichert werden sollen,
|
||||
// eine Methode zur Berechnung des Hash-Wertes angeboten wird.
|
||||
int hash(final int tableSize);
|
||||
}
|
||||
54
SS23/AuD/src/UEB11/Professor.java
Normal file
@@ -0,0 +1,54 @@
|
||||
package UEB11;
|
||||
public class Professor implements IHashable
|
||||
{
|
||||
private String name;
|
||||
private long hausruf;
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public long getHausruf()
|
||||
{
|
||||
return hausruf;
|
||||
}
|
||||
|
||||
public Professor(String name, int Hausruf)
|
||||
{
|
||||
this.name = name;
|
||||
this.hausruf = Hausruf;
|
||||
}
|
||||
|
||||
// Hash-Wert
|
||||
public int hash(final int tableSize)
|
||||
{
|
||||
char c1 = name.charAt(0);
|
||||
char c2 = name.charAt(1);
|
||||
|
||||
int h1 = c1 - '0';
|
||||
int h2 = c2 - '0';
|
||||
int h = (h1 + h2) % tableSize;
|
||||
|
||||
// Debug-Ausgabe zu Testzwecken
|
||||
// System.out.println("Name:" + Name + " Hashwert:" + h);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
// In diesem Beispiel nur Professor-Objekte zulassen
|
||||
if (!(o instanceof Professor))
|
||||
return false;
|
||||
|
||||
final Professor p = (Professor)o;
|
||||
|
||||
return ((p.name).equals(this.name) && (p.hausruf == this.hausruf));
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
61
SS23/AuD/src/UEB11/StringSearch.java
Normal file
@@ -0,0 +1,61 @@
|
||||
package UEB11;
|
||||
|
||||
public class StringSearch {
|
||||
public static void main(String[] args) {
|
||||
String[] words = {
|
||||
"aardvark", "abandon", "ability", "academy", "acorn",
|
||||
"action", "adventure", "aerial", "aerodynamic", "affection",
|
||||
"algorithm", "alpine", "amber", "analogy", "anchor",
|
||||
"antique", "aquarium", "arboreal", "architect", "arctic",
|
||||
"argument", "armor", "artistic", "asteroid", "athletic",
|
||||
"atmosphere", "auction", "audio", "authority", "automobile",
|
||||
"avalanche", "ballad", "banquet", "barrier", "bathtub",
|
||||
"beacon", "beholder", "biography", "blossom", "blueprint",
|
||||
"boulder", "broccoli", "brother", "buffalo", "butterfly",
|
||||
"cabbage", "calculator", "camouflage", "campfire", "candle",
|
||||
"carnation", "carousel", "cathedral", "cavalry", "celestial",
|
||||
"chameleon", "character", "cherry", "chestnut", "chimpanzee",
|
||||
"chronicle", "circus", "cobweb", "compass", "compendium",
|
||||
"conductor", "constellation", "contraption", "conundrum", "coral",
|
||||
"corkscrew", "crabapple", "crescendo", "cricket", "crimson",
|
||||
"cruise", "crystal", "cucumber", "curriculum", "cylinder",
|
||||
"daffodil", "daisy", "dandelion", "darkness", "daylight",
|
||||
"demonstration", "desert", "dictionary", "dinosaur", "direction",
|
||||
"dolphin", "dragonfly", "dream", "dune", "dwarf",
|
||||
"dynamite", "eagle", "earthquake", "echo", "eclipse",
|
||||
"education", "electricity", "elephant", "embassy", "engine",
|
||||
"escalator", "eucalyptus", "exploration", "falcon", "ferry",
|
||||
"firework", "flamingo", "flower", "fossil", "galaxy"
|
||||
};
|
||||
|
||||
|
||||
|
||||
String search = "aardvark" ;
|
||||
System.out.println(binaereSuche(words,search));
|
||||
}
|
||||
|
||||
static boolean binaereSuche(final String[] worte, final String begriff){
|
||||
int left = 0;
|
||||
int right = worte.length;
|
||||
int midIndex = worte.length/2;
|
||||
|
||||
int i=0;
|
||||
int goal = (int)Math.log(worte.length)+2;
|
||||
while(i <= goal){
|
||||
i++;
|
||||
System.out.println(worte[midIndex]);
|
||||
int comp = worte[midIndex].compareTo(begriff);
|
||||
System.out.println(comp);
|
||||
if (comp > 0) {
|
||||
right = midIndex-1;
|
||||
midIndex = (left+right)/2;
|
||||
} else if (comp < 0) {
|
||||
left = midIndex+1;
|
||||
midIndex = (left+right)/2;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
57
SS23/AuD/src/UEB12/Graph.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package UEB12;
|
||||
|
||||
public class Graph
|
||||
{
|
||||
private static final int KNOTENZAHL = 7;
|
||||
private static boolean[] besucht;
|
||||
private Knoten[] knoten;
|
||||
private boolean[][] matrix = {
|
||||
{false, true, false, false, false, false, false},
|
||||
{false, false, true, false, false, false, false},
|
||||
{false, true, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, false},
|
||||
{false, false, false, true, false, false, false},
|
||||
{false, true, true, false, false, false, false},
|
||||
{false, false, false, false, false, false, false},
|
||||
};
|
||||
|
||||
public Graph()
|
||||
{
|
||||
knoten = new Knoten[KNOTENZAHL];
|
||||
knoten[0] = new Knoten("A");
|
||||
knoten[1] = new Knoten("B");
|
||||
knoten[2] = new Knoten("C");
|
||||
knoten[3] = new Knoten("D");
|
||||
knoten[4] = new Knoten("E");
|
||||
knoten[5] = new Knoten("F");
|
||||
knoten[6] = new Knoten("G");
|
||||
}
|
||||
|
||||
private boolean isKante(int k1, int k2)
|
||||
{
|
||||
// TODO
|
||||
return true;
|
||||
}
|
||||
|
||||
// Tiefensuche
|
||||
private void rekDfs(final int k)
|
||||
{
|
||||
// TODO
|
||||
// Rekursive Tiefensuche mit Hilfe der Methode isKante implementieren
|
||||
|
||||
}
|
||||
|
||||
public void zusammenhangskomponenten()
|
||||
{
|
||||
besucht = new boolean [KNOTENZAHL];
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Graph().zusammenhangskomponenten();
|
||||
}
|
||||
}
|
||||
16
SS23/AuD/src/UEB12/Knoten.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package UEB12;
|
||||
|
||||
public class Knoten
|
||||
{
|
||||
private String name;
|
||||
|
||||
public Knoten(String s)
|
||||
{
|
||||
name = s;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
0
SS23/Communications and Computer Networks/VL01.md
Normal file
13
SS23/English/VL02.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# p8
|
||||
## 1
|
||||
### a
|
||||
- 1 Personalabteilung: HR
|
||||
- 2 Vertrieb: Sales and Marketing
|
||||
- 3 Hardware support: Hardware Support
|
||||
- 4 Forschung und Entwicklung: R&D
|
||||
- 5 Qualitätssicherung: Quality Assurance
|
||||
- 6 Rechtsabteilung: Legal department
|
||||
- 7 Kundendiests: Customer service
|
||||
- 8 Softwareentwicklung: Software development
|
||||
### b
|
||||
Q
|
||||
BIN
SS23/Informationssicherheit/20230330_19h30m31s_grim.png
Normal file
|
After Width: | Height: | Size: 998 KiB |
BIN
SS23/Informationssicherheit/20230330_19h34m13s_grim.png
Normal file
|
After Width: | Height: | Size: 436 KiB |
BIN
SS23/Informationssicherheit/20230331_07h21m13s_grim.png
Normal file
|
After Width: | Height: | Size: 440 KiB |
BIN
SS23/Informationssicherheit/20230331_10h28m24s_grim.png
Normal file
|
After Width: | Height: | Size: 474 KiB |
BIN
SS23/Informationssicherheit/20230331_10h28m43s_grim.png
Normal file
|
After Width: | Height: | Size: 477 KiB |
BIN
SS23/Informationssicherheit/20230331_14h12m43s_grim.png
Normal file
|
After Width: | Height: | Size: 411 KiB |
BIN
SS23/Informationssicherheit/20230331_16h17m48s_grim.png
Normal file
|
After Width: | Height: | Size: 392 KiB |
BIN
SS23/Informationssicherheit/20230331_16h21m51s_grim.png
Normal file
|
After Width: | Height: | Size: 505 KiB |
BIN
SS23/Informationssicherheit/20230331_16h22m19s_grim.png
Normal file
|
After Width: | Height: | Size: 499 KiB |
BIN
SS23/Informationssicherheit/20230331_16h29m50s_grim.png
Normal file
|
After Width: | Height: | Size: 452 KiB |
BIN
SS23/Informationssicherheit/20230331_17h00m06s_grim.png
Normal file
|
After Width: | Height: | Size: 342 KiB |
208
SS23/Informationssicherheit/Ueb01.md
Normal file
@@ -0,0 +1,208 @@
|
||||
## 1.1
|
||||
|
||||
## a) Was ist das Hauptziel von CVE? Wie werden Verwundbarkeiten standardmäßig beschrieben? Wer ist Betreiber von CVE und welche Organisationen finanzieren das Projekt?
|
||||
|
||||
### Betreiber
|
||||
|
||||
* Der Betreiber ist die Mitre Corporation, eine Non-Profit-Organisation, die aus Verschiedenen Forschungsinstituten besteht und sich aus einer Abspaltung vom MIT gebildet hat. Ihr „Auftraggeber“ sind die USA.
|
||||
Eines ihrer Institute ist z.B. das „Homeland Security Systems Engineering and Development Institute “.
|
||||
|
||||
### Finanzierung
|
||||
|
||||
* Das CVE-Programm von der MITRE Corporation wird von der CISA (Cybersecurity and Infrastructure Security Agency) finanziert die dem bereits genanntem U.S. Department of Homeland Security.
|
||||
|
||||
## b) Was umfasst NVD im Vergleich zu CVE und wie werden Verwundbarkeiten standardmäßig beschrieben? Wer ist Betreiber von NVD und welche Organisationen finanzieren das Projekt?
|
||||
|
||||
### NVD
|
||||
|
||||
* NVD baut auf CVE auf und erweitert CVE um z.B. Analysen und Gegenmaßnahmen.
|
||||
* NVD wird vom National Institute of Standards and Technology (NIST) betrieben und unter anderem von der US-Regierung finanziert.
|
||||
* Beurteilt werden die Verwundbarkeiten mit Hilfe des Common Vulnerability Scoring System (CVSS), einem einheitlichen System für Beurteilung
|
||||
* Weitere bereitgestellte Informationen sind:
|
||||
* Betroffene Software bzw. Versionen
|
||||
* Schweregrad
|
||||
* Auswirkungen
|
||||
* Gegenmaßnahmen
|
||||
|
||||
## c)
|
||||
nvd angegebener score: 7,5
|
||||
|
||||
## d)
|
||||
|
||||
#### Was ist das Ziel von CWE?:
|
||||
Häufig vorkommende schwachstellen zu vermeiden.
|
||||
Sie bieten eine liste von den häufigsten schwachstellen für software firmware hardward und servies.
|
||||
|
||||
#### Wie werden Verwundbarkeitstypen standardmäßig beschrieben?:
|
||||
|
||||
|
||||
Jede schwachstelle wird kategoresiert und hat jeweils folgende eigenschaften:
|
||||
\- WeaknessID
|
||||
\- Abstraktion Typ
|
||||
\- Struktur Typ
|
||||
\- Beschreibung
|
||||
|
||||
Und noch einige, die nicht immer auftauchen wie:
|
||||
\- Erweiterte beschreibung
|
||||
\- Alternativer Name
|
||||
\- Abhängigkeiten
|
||||
\- Beispiele
|
||||
|
||||
#### Wer ist Betreiber von CWE?
|
||||
CWE wird von seiner communinty betrieben. Darunter gehören auch Apple, Intel und Microsoft
|
||||
|
||||
## e) Was für ein Verwundbarkeitstyp ist Heartbleed laut CWE?
|
||||
|
||||
CWE-126: Buffer Over-read
|
||||
|
||||
* Entsteht, wenn eine Anwendung versucht, Daten von einem Puffer oder Speicherbereich zu lesen, der kleiner ist als die angeforderte Datenmen
|
||||
* Führt dazu, dass die Anwendung auf Speicher zugreift, der außerhalb des zugewiesenen Bereichs liegt und möglicherweise Daten liest, die nicht für sie vorgesehen sind
|
||||
* Kann zu unerwartetem Verhalten, einschließlich Abstürzen oder Sicherheitslücken führen
|
||||
|
||||
## f) Lernen Sie weitere Details zu Heartbleed, bspw. hinsichtlich Gegenmaßnahmen, Exploits, betroffener Software und ähnlichen Verwundbarkeiten.
|
||||
|
||||
Betroffene Software: Heartbleed betraf die OpenSSL-Bibliothek, die von vielen Webservern, E-Mail-Servern, VPN-Gateways und anderen Netzwerkdiensten verwendet wird.
|
||||
|
||||
Gegenmaßnahmen:
|
||||
|
||||
* Als Unternehmen/Seitenbetriber: Um gegen Heartbleed geschützt zu sein, mussten betroffene Organisationen schnell reagieren, indem sie ihre OpenSSL-Versionen auf eine nicht anfällige Version aktualisierten.
|
||||
* Als Entwickler: eine if-Abfrage
|
||||
|
||||
Exploits
|
||||
|
||||
* Entschlüsselung archivierter Daten
|
||||
* Entschlüsselung während der Webserver-Verbindungsaufnahme
|
||||
* Entschlüsselung der Verbindungsaufnahme an VoIP-Telefonen, Netzwerkdruckern und Routern
|
||||
|
||||
Ähnliche Schwachstellen, wie Heartbleed, die auf unsicheren Speicheroperationen beruhen:
|
||||
|
||||
* "Buffer Overflow"-Schwachstelle
|
||||
* Schwachstelle, die auftritt, wenn ein Programm versucht, mehr Daten in einen Puffer oder Speicherbereich zu schreiben, als dieser aufnehmen kann.
|
||||
* "Catastrophic Backtracking" in OpenSSL (CVE-2015-0291),
|
||||
* ermöglichte Angreifern, den SSL-Server durch Senden eines speziell gestalteten Pakets zum Absturz zu bringen
|
||||
|
||||
## 1.2
|
||||
|
||||
## a) Um welche Verwundbarkeit handelt es sich genau? Um welchen Verwundbarkeitstyp handelt es sich?
|
||||
|
||||
Die Schwachstelle mit der CVE-2017-5754 wird auch als Meltdown bezeichnet und betrifft Prozessoren von Intel sowie einige ARM- und IBM-Power-Prozessoren. Es handelt sich bei dieser Schwachstelle um eine Hardware-Schwachstelle, die aufgrund eines Designfehlers in der Prozessorarchitektur entstanden ist.
|
||||
|
||||
## b) Was ist die Ursache der Verwundbarkeit und wie kann sie ausgenutzt werden?
|
||||
|
||||
Die Ursache für die Schwachstelle CVE-2017-5754, auch bekannt als Meltdown, liegt in der Art und Weise, wie moderne Prozessoren Speicherzugriffe optimieren, um eine höhere Leistung zu erzielen. Aufgrund dieser Optimierungen werden Speicherzugriffe teilweise vor der Berechtigungsprüfung durchgeführt, was es einem Angreifer ermöglicht, vertrauliche Informationen auszulesen, auf die er normalerweise keinen Zugriff hätte.
|
||||
|
||||
Ein Angreifer kann diese Schwachstelle ausnutzen, indem er einen speziell präparierten Programmcode ausführt, der es ihm erlaubt, den Inhalt des Speichers auszulesen, der normalerweise für andere Prozesse oder das Betriebssystem zugänglich ist. Durch die Ausnutzung dieser Schwachstelle kann ein Angreifer vertrauliche Informationen wie Passwörter, Kryptoschlüssel oder andere sensible Daten auslesen.
|
||||
|
||||
Es ist wichtig zu beachten, dass ein Angreifer bereits Zugriff auf das System haben und speziell präparierten Code ausführen muss, um diese Schwachstelle auszunutzen.
|
||||
|
||||
## c) Welche Produkte sind von der Verwundbarkeit betroffen?
|
||||
|
||||
Die Schwachstelle betrifft hauptsächlich Prozessoren von Intel sowie einige ARM- und IBM-Power-Prozessoren, die seit 1995 entwickelt wurden. Die Schwachstelle wurde im Januar 2018 öffentlich bekannt gemacht und wurde als eine der schwersten Sicherheitslücken in der Geschichte der IT-Industrie eingestuft.
|
||||
|
||||
## d) Welche Gegenmaßnahmen wurden ergriffen?
|
||||
|
||||
* Hardware-Hersteller haben Mikrocode-Updates und Firmware-Updates bereitgestellt, um die Anfälligkeit ihrer Chips gegenüber Meltdown zu verringern. Diese Updates beheben nicht den Designfehler, helfen jedoch dabei, die Auswirkungen der Verwundbarkeit zu begrenzen.
|
||||
* Betriebssystemhersteller haben Sicherheitspatches und Updates veröffentlicht, um ihre Systeme gegen Meltdown zu schützen. Diese Updates beinhalten Kernel Page Table Isolation oder ähnliche Techniken, um den Kernel-Speicher vom Benutzerspeicher zu isolieren und so den Zugriff auf geschützte Speicherbereiche zu verhindern.
|
||||
|
||||
## e)
|
||||
|
||||
Berechnen Sie den CVSS Score mit dem ”Common Vulnerability Scoring System Calculator Version 3.1“. Welche qualitativen Unterschiede zum CVSS 3.1 Score von Heartbleed können Sie dabei feststellen?
|
||||
|
||||
### Heartbleed:
|
||||
|
||||

|
||||
|
||||
### Meltdown:
|
||||
|
||||

|
||||
|
||||
### Angriffsvektor
|
||||
|
||||
* Heartbleed: Über das Netzwerk
|
||||
* Meltdown: Lokal
|
||||
|
||||
### erforderliche Privilegien
|
||||
|
||||
* Meltdown erfordert niedrige Privilegien
|
||||
* Heartbleed benötigt keine Privilegien
|
||||
|
||||
### CVSS Score
|
||||
|
||||
* Meltdown: Base Score von 5.6(Medium)
|
||||
* Heartbleed: Base Score von 7.5(High)
|
||||
|
||||
## 1.3
|
||||
|
||||
## HTTP Basics
|
||||
|
||||
### 1
|
||||
|
||||
* Name eingeben
|
||||
* Output wird zurückgegeben
|
||||
|
||||
### 2
|
||||
|
||||
* Mit Untersuchen nachgucken
|
||||
* Network Tab auswälen
|
||||
* POST request finden (attack2)
|
||||
* Im request Tab Daten auslesen
|
||||
|
||||

|
||||
|
||||
* Alternativ: ZAP interception
|
||||
* Schritte von HTTP Proxies durchführen
|
||||
|
||||

|
||||
|
||||
## HTTP Proxies
|
||||
|
||||
### 1
|
||||
|
||||
* Breakpoint filter erstellen
|
||||
* auf Request Header Contains POST setzen
|
||||
* auf "Submit" drücken
|
||||
* POST mit GET ersetzen
|
||||
* 'x-request-intercepted:true' einfügen
|
||||
* "doesn't+matter+really" mit "Requests are tampered easily" ersetzen
|
||||
* auf "Continue" drücken
|
||||
|
||||

|
||||
|
||||
## Developer Tools
|
||||
|
||||
### 1
|
||||
|
||||
* Seite Untersuchen
|
||||
* Zu den Console Tab wechseln
|
||||
* webgoat.customjs.phoneHome() eingeben
|
||||
* Die zufällig generierte Zahl abgeben
|
||||
|
||||

|
||||
|
||||
### 2
|
||||
|
||||
* Seite Untersuchen
|
||||
* Zu den Network Tab wechseln
|
||||
* Auf "Go" drücken
|
||||
* POST request finden (der Name ist Network)
|
||||
* Zum Request Tab wechsel
|
||||
* NetworkNum auslesen
|
||||
|
||||

|
||||
|
||||
## CIA Triad
|
||||
|
||||
### 1
|
||||
|
||||
Antworten:
|
||||
|
||||
* Frage 1
|
||||
* Antwort 3
|
||||
* Frage 2
|
||||
* Antwort 1
|
||||
* Frage 3
|
||||
* Antwort 4
|
||||
* Frage 4
|
||||
* Antwort 2
|
||||
|
||||

|
||||
BIN
SS23/Informationssicherheit/Ueb01.pdf
Normal file
17
SS23/Informationssicherheit/VL02/VL02.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# A4
|
||||
- Mathematische Definition
|
||||
- 5+8n+13n^2 <= 5n^2 + 8n^2 + 13n^2 = 26n^2
|
||||
- Grenzwertbetrachtung
|
||||
- lim n-> inf (5+8n+13n^2)/n^2 = lim n-> inf ((5/n^2)+(8/n)+13)/1 = 13
|
||||
- Methode der 7 Worte
|
||||
- 5+8n+13n^2
|
||||
|
||||
# A5
|
||||
## a)
|
||||
4+3+2+1 = 10
|
||||
|
||||
## b)
|
||||
Sig 1..n-1 ((n-1)n)/2
|
||||
|
||||
## c)
|
||||
O(n^2)
|
||||