This commit is contained in:
Your Name
2023-10-03 23:28:51 +02:00
parent 9a83c28137
commit 42f2899bbf
162 changed files with 9 additions and 13 deletions

View File

@@ -0,0 +1 @@
![Alt text](https://cdn.discordapp.com/attachments/1017491520145854565/1090179777534623855/image.png)

View 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)

Binary file not shown.

View 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
View 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
View 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
View 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
View 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
View 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
View 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>

View 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) {
}
}

View 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;
}
}

View 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);
}
}

View 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();
}
}

View 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;
}
}

View 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;
}
}
}

View 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();
}
}
}

View 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();
}
}

View File

@@ -0,0 +1,9 @@
package UEB03;
public class ListeTest
{
public static void main(String[] args)
{
new ListeGUI().setVisible(true);
}
}

View 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);
}
}

View 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);
}
}

View 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;
}
}

View 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();
}

View 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();
}
}

View 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;
}
}

View 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);
}
}
}

View 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();
}
}
}
}
}
}

View File

@@ -0,0 +1,9 @@
package UEB06;
public class BaumTest
{
public static void main(String[] args)
{
new BaumGUI().setVisible(true);
}
}

View 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();
}
}

View 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();
}
}

View 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();
}
}

View 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);
}
}
}

View 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();
}
}
}
}
}
}

View File

@@ -0,0 +1,8 @@
package UEB07;
public class BaumTest
{
public static void main(String[] args)
{
new BaumGUI().setVisible(true);
}
}

View 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;
}
}

View 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!");
}
}

View 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;
}
}

View 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
}
}

View 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);
}
}
}

View 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);
}
}

View 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++];
}
}

View 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
}
}

View 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;
}
}

View 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;
}
}

View 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)));
}
}

View 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);
}

View 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;
}
}

View 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;
}
}

View 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();
}
}

View File

@@ -0,0 +1,16 @@
package UEB12;
public class Knoten
{
private String name;
public Knoten(String s)
{
name = s;
}
public String getName()
{
return name;
}
}

13
SS23/English/VL02.md Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 998 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

View 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:
![Alt text](https://cdn.discordapp.com/attachments/1017491520145854565/1090682843853758464/image.png)
### Meltdown:
![Alt text](https://cdn.discordapp.com/attachments/1017491520145854565/1090683294301044846/image.png)
### 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
![image info](20230331_10h28m24s_grim.png)
* Alternativ: ZAP interception
* Schritte von HTTP Proxies durchführen
![image info](20230331_17h00m06s_grim.png)
## 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
![image info](20230331_14h12m43s_grim.png)
## Developer Tools
### 1
* Seite Untersuchen
* Zu den Console Tab wechseln
* webgoat.customjs.phoneHome() eingeben
* Die zufällig generierte Zahl abgeben
![image info](20230331_16h17m48s_grim.png)
### 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
![image info](20230331_16h22m19s_grim.png)
## CIA Triad
### 1
Antworten:
* Frage 1
* Antwort 3
* Frage 2
* Antwort 1
* Frage 3
* Antwort 4
* Frage 4
* Antwort 2
![image info](20230331_16h29m50s_grim.png)

Binary file not shown.

View 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)