Algoritmer och datastructurer
-Sökträd, naiva och balancerade lösningar
-HashTable
-- Kapitel 19, 20.
För utveckling av verksamhet, produkter och livskvalitet.
Speciella träd -Binära Sökträd
Har ordnade element
Mindre värde till
vänster
Högre värde till höger
7
2
1
9
5
3
För utveckling av verksamhet, produkter och livskvalitet.
11
Är det ett sökträd?
7
2
1
9
11
5
3
8
För utveckling av verksamhet, produkter och livskvalitet.
Implementation – noden
3
class Node <AnyType>
{
AnyType element;
Node left;
Node right;
Node( AnyType data)
{
element=data;
left=right=null;
}
}
För utveckling av verksamhet, produkter och livskvalitet.
...och BinarySearchTree
public class BinarySearchTree <AnyType extends
Comparable<? super AnyType> >
{
Node <AnyType> root;
public BinarySearchTree()
{ root=null; }
-public void insert
-public nbrOfNodes
-public remove
-public find , findMin, findMax
}
För utveckling av verksamhet, produkter och livskvalitet.
Insert ()
6
7
2
1
9
5
3
För utveckling av verksamhet, produkter och livskvalitet.
11
Insert ()
6
7
2
1
9
5
3
För utveckling av verksamhet, produkter och livskvalitet.
11
Insert ()
6
7
2
1
9
5
3
För utveckling av verksamhet, produkter och livskvalitet.
11
Insert ()
7
2
9
6
1
5
3
För utveckling av verksamhet, produkter och livskvalitet.
11
BinarySearchTree-insert (Comparable x)
public void insert ( Comparable x)
{
root = isert(x, root);
}
public BinaryNode insert( Comparable x, BinaryNode t){
if(t==null)
t= new BinaryNode(x);
else if ( x.compareTo(t.element)<0)
t.left=findPlaceAndLink(x, t.left);
else if (x.compareTo(t.element)>0)
t.right=findPlaceAndLink(x, t.right);
else
throw new DuplicateException(" No dublicates");
return t;
}
För utveckling av verksamhet, produkter och livskvalitet.
Binära Sökträd – metoden find()mycket kort söktid
För utveckling av verksamhet, produkter och livskvalitet.
Binära Sökträd – metoden
findMax()-mycket kort söktid
För utveckling av verksamhet, produkter och livskvalitet.
BinarySearchTree-find( )
public String find ( Comparable x)
{
BinaryNode n= findNode( x, root);
if(n==null)
return null;
else
return n.element;
}
public BinaryNode findNode( Compare x, BinaryNode t)
{
while( t!=null)
{
if(x.compareTo(t.element)<0)
t=t.left;
if(x.compareTo(t.element)>0)
t=t.right;
else
return t ; // hittat!!
}
return null; // inte hittat !!
}
För utveckling av verksamhet, produkter och livskvalitet.
Remove ()
a) Om noden är löv
7
2
1
9
5
3
För utveckling av verksamhet, produkter och livskvalitet.
11
Remove ()
b) Om noden har ett barn
7
2
1
9
5
3
För utveckling av verksamhet, produkter och livskvalitet.
11
Remove ()
c) Om noden har två barn
7
2
3
1
9
11
5
3
4
Ersätt värdet i noden med den minsta
värdet i i det högra delträdet och sedan
ta bort den noden
För utveckling av verksamhet, produkter och livskvalitet.
Farliga specialfall!
För utveckling av verksamhet, produkter och livskvalitet.
Trädet blir en
länkad lista
Lösningen? Balancerade träd
•
Hur ? Försök hålla djupet av trädet så lågt som möjligt.
För utveckling av verksamhet, produkter och livskvalitet.
Hur?
•
Olika tekniker att balancera
•
AVL Träd
•
Red Black Träd
•
AA Träd
För utveckling av verksamhet, produkter och livskvalitet.
Balancerad Search Trees – AVL
Ett träd är balancerad om höjdskillnaden mellan den vänstra delträdet
och den högra delträdet är maximum 1.
12
8
4
HL=2
2
16
10
14
6
HL– HR = 2 – 1 = 1
För utveckling av verksamhet, produkter och livskvalitet.
HR=1
Balanced Search Trees – AVL
Ett träd är balancerad om höjdskillnaden mellan den vänstra delträdet
och den högra delträdet är maximum 1.
12
8
4
HL=1
2
16
10
HR=0
14
6
HL– HR = 1 – 0 = 1
För utveckling av verksamhet, produkter och livskvalitet.
BST: AVL – Balanced?
insert
12
8
4
2
16
10
14
6
För utveckling av verksamhet, produkter och livskvalitet.
1
BST: AVL – Rotation höger
k1
k2
k2
k1
C
B
A
För utveckling av verksamhet, produkter och livskvalitet.
A
B
C
BST: AVL – Rotate right
k2
k1
12
8
16
4
2
10
6
14
1
För utveckling av verksamhet, produkter och livskvalitet.
BST: AVL – Rotation vänster
k1
k2
k2
k1
A
A
B
C
B
C
För utveckling av verksamhet, produkter och livskvalitet.
AA – Träd

En ny nod skapas alltid som löv och har nivå 1.

En horizontal länk är en förbindelase med en nod med samma nivå. .

Två horisontala länkar är inte tilllåtna. Split!
4
5
1
6
2
6
1
5
6
7
För utveckling av verksamhet, produkter och livskvalitet.
5
1
7
AA – Träd

Vänster länk är inte tilllåten

I det fallat gör – screw!
4
5
4
5
För utveckling av verksamhet, produkter och livskvalitet.
AA – Träd : Operation split()
10
15
15
20
10
A
B
A
För utveckling av verksamhet, produkter och livskvalitet.
20
B
AA – Träd : Operation skew()
10
A
15
B
10
c
För utveckling av verksamhet, produkter och livskvalitet.
A
15
B
c
Hash Tabeller?
•
Varför en annan datastruktur?
•
Konstant tid för både insert- och findoperationer
För utveckling av verksamhet, produkter och livskvalitet.
Hash?
Insert
Find
”Daniel”
=18
För utveckling av verksamhet, produkter och livskvalitet.
Hashfunktioner!
•
•
Hash functioner använder associerade “key” ( som kan vara
data i sig ) .
Hash funktionerna är olika för olika sorts data.
• Integers
• Images
• Strings
Etc…
För utveckling av verksamhet, produkter och livskvalitet.
Hashing integers?
•
•
•
•
•
•
Tänk 16bit int => 0 – 65 535
Skapa int[] vec = new int[65536];
Add i => vec[i]++;
Sök value j => Is vec[j] > 0?
Ta bort value k => vec[k]--;
Men för en ... Java int : 32bit
• 4 billion items => impractical!
För utveckling av verksamhet, produkter och livskvalitet.
Exempel av hash funktion
”Daniel”
D a n
i
e
l
68 + 97 + 110 + 105+ 101 + 108 = 589
För utveckling av verksamhet, produkter och livskvalitet.
Men...
•
•
Hur unik är den?
•
hashfunc(”Daniel”) → 589
•
hashfunc(”leinaD”) → 589
Bättre lösning men….!
•
hashfunc(”TestValue”) → 129310392
•
Wrapp värdet till ett visst intervall
•
Vilken? Arraystorleken…
För utveckling av verksamhet, produkter och livskvalitet.
En bättre hash funktion
•
•
•
•
•
Ett bättre sätt att beräkna hash värdet
Om vi har en text sträng av längd n+1 och alla tecken har
index An, An-1,...,A0
gör s = AnXn + An-1Xn-1 +...+ A0X0 =
= ((An)X + An-1)X +...+ A0
Använd hashValue = s % array.length
För utveckling av verksamhet, produkter och livskvalitet.
Och då......
•
For example: ”Danne”
(((’D’)128 + ’a’)128 + ’n’)128 + ’n’)128 + ’e’ =
(((68)128 + 97)128 + 110)128 + 110)128 + 101 =
18 458 851 173
hashValue = 18 458 851 173 % array.length
om length = 7919 (prim nummer) =>
hashValue = 18 458 851 173 % 7919 =2690
För utveckling av verksamhet, produkter och livskvalitet.
Hur löser man kollision?
•
•
Oavsett hur unika keys en hash- funktionen tar fram,
kommer kollisioner alltid att inträffa.
Terminology
• Load factor
LF 
# used positions
# total avaliable positions
För utveckling av verksamhet, produkter och livskvalitet.
Lösningar
•
•
•
•
Linear probing ( undersökning ??)
Quadratic probing
Double hashing
Separate chaining
För utveckling av verksamhet, produkter och livskvalitet.
Linear probing
•
Sök fram till näst lediga platsen.
hashfunc( )
10
18
X=18
X+1,
X+2,
X+3,
X+4,
För utveckling av verksamhet, produkter och livskvalitet.
X+5,
...
Linear probing
•
Fenomen kallat: Primary clusters
För utveckling av verksamhet, produkter och livskvalitet.
Linear probing
•
Bygger upp kluster
•
Påverkar exekveringstiden för insert () och find()!
För utveckling av verksamhet, produkter och livskvalitet.
Quadratic probing
•
•
•
Försök undvika“primary clusters “
Snabbare än linjär probing
Kvadratisk inkrementation av undersöknings-avståndet
X=18
X+12,
X+22,
X+32,
X+42,
För utveckling av verksamhet, produkter och livskvalitet.
X+52,
...
Quadratic probing
32 = 9
1
2
1
4
•
Garantera att hitta fria platser om de finns
För utveckling av verksamhet, produkter och livskvalitet.
Double hashing
•
Använder ytterligare en till hash funktion för att hitta fri plats.
X = hash(obj);
X2 = hash2(obj);
X=18, X2=7
X+1*X2,
X+2*X2,
X+3*X2, X+4*X2, ...
X=18, X2=7
18+1*7,
18+2*7,
17+3*7, 18+4*7, ...
För utveckling av verksamhet, produkter och livskvalitet.
Separate chaining
•
•
•
Varje hash-position har en länkad lista.
Påverkar inte andra värdet, probing görs bara i listan.
Varje element i tabellen är en länkad lista.
För utveckling av verksamhet, produkter och livskvalitet.
Separate chaining
Insert
H
H
H
H
H
H
H
För utveckling av verksamhet, produkter och livskvalitet.
H
H
Jämförelse
•
•
•
•
Linear probing
• Enkel
• Kan resultera i linjär söktid
Quadratic probing
• Kräver Load factor < 0.5 annars rehashing ??
• Kräver primtal för array storleken
Separate chaining
• LF < 1
• Ingen dubblering, länkade listor är dynamiska !
• Kan leda till linjär sökning men i verklighetet ganska
kort
Double hash probing
• Eliminerar kluster
För utveckling av verksamhet, produkter och livskvalitet.
Hash tabeller i java
• I klassen java.util finns klassen HashMap<K,V> som implementerar
interfacet Map<K,V>.
public int hashCode() och
public boolean equals(Object x)
så att man får identisk hashkod för objekt som är lika enligt metoden
equals.
Anm: För flera av Javas egna klasser är detta redan gjort. T ex
klassen String.
För utveckling av verksamhet, produkter och livskvalitet.
Använding av HashMap
•
Antag vi vill vill sätta in Person-objekt i en hashtabell, med nyckel
= personens namn:
class Person {
String name; // namn
long pNbr; // personnummer
public Person(String n, long pnbr) {...}
public boolean equals(Object rhs) {
return name.equals(((Person) rhs).name);
}
// andra metoder i klassen Person
}
För utveckling av verksamhet, produkter och livskvalitet.
Använding av HashMap
HashMap<String,Person> reg = new HashMap<String,Person>();
Person p = new Person("Kalle", 1111111111);
reg.put(p.name, p);
...
Person q = reg.get("Kalle");
if (q != null) {
...
}
Observera att vi här inte själva behöver omdefiniera hashCode
eftersom nycklarna är av typen String, och i denna klass är redan
hashCode omdefinierad ( så att strängar för vilka equals ger true
också får samma hashkod).
För utveckling av verksamhet, produkter och livskvalitet.
Användning av HashSet
•
Om vi vill sätta in Person-objekt i en samling av typen HashSet<Person>
och gör så här:
HashSet<Person> reg = new HashSet<Person>();
Person p = new Person("Kalle", 1111111111);
reg.add(p);
...
if (reg.contains(new Person("Kalle",0))
System.out.println("found");
else
System.out.println("not found");
så blir utskriften ”not found”
För utveckling av verksamhet, produkter och livskvalitet.
Användning av HashSet
• Anledningen är att när Kalle sätts in beräknas hashkoden för
objektet som p refererar till och placeringen i tabellen beror på
denna.
•
När vi sedan söker efter Kalle baseras sökningen på hashkoden
av det objekt som är parameter till contains-metoden och detta
är ett annat objekt (med samma namn).
•
Sökningen utgår från den plats denna senare hashkod anger och
med största sannolikhet är det i en helt annan del av tabellen än
den där Kalle sattes in.
För utveckling av verksamhet, produkter och livskvalitet.
hashCode-metod
•
Vi kan se till att alla Person-objekt som har samma namn också
får samma hashkod genom att omdefiniera metoden hashCode i
klassen Person:
class Person {
String name; // namn
long pNbr; // personnummer
public Person(String n, long pnbr) {...}
public boolean equals(Object rhs) {som förut}
public int hashCode() {
return name.hashCode();
}
// övriga metoder i klassen Person
}
För utveckling av verksamhet, produkter och livskvalitet.