Sie sind auf Seite 1von 1

Home | Rules | Tutorial-1 | Tutorial-2 | Tutorial-3 | Lectures

Tutorial 3
Trees and Graphs

The following algorithm implements a simple binary search tree.

import java.util.*;

public class BinarySearchTree<T> extends AbstractSet<T>


{
private Node<T> root;
private int size;

private static class Node<T>


{
private T element;
private Node<T> left = null;
private Node<T> right = null;
private Node<T> parent;

private Node(T element, Node<T> parent)


{
this.element = element;
this.parent = parent;
}
}

public BinarySearchTree()
{
root = null;
size = 0;
}

public BinarySearchTree(BinarySearchTree<T> other)


{
root = null;
size = 0;
for (T element: other)
add(element);
}

public int size()


{
return size;
}

public Iterator<T> iterator()


{
return new TreeIterator();
}

public boolean add(T element)


{
if (root == null) {
root = new Node<T>(element, null);
size++;
return true;
} else {
Node temp = root;
int comp;
while (true) {
comp = ((Comparable)(element)).compareTo(temp.element);
if (comp == 0)
return false;
if (comp<0) {
if (temp.left != null)
temp = temp.left;
else {
temp.left = new Node<T>(element, temp);
size++;
return true;
}
} else {
if (temp.right != null)
temp = temp.right;
else {
temp.right = new Node<T>(element, temp);
size++;
return true;
}
}
}
}
}

public boolean remove(Object obj)


{
Node<T> e = getNode(obj);
if (e == null)
return false;
deleteNode(e);
return true;
}

private Node<T> getNode(Object obj)


{
int comp;
Node<T> e = root;
while (e != null) {
comp = ((Comparable)(obj)).compareTo(e.element);
if (comp == 0)
return e;
else if (comp < 0)
e = e.left;
else
e = e.right;
}
return null;
}

public T mapAdd(T obj)


{
if (root == null) {
root = new Node<T>(obj, null);
size++;
return root.element;
}
int comp;
Node<T> e = root;
Node<T> p = null;
boolean left = true;
while (e != null) {
p = e;
comp = ((Comparable)(obj)).compareTo(e.element);
if (comp == 0)
return e.element;
else if (comp < 0) {
left = true;
e = e.left;
} else {
e = e.right;
left = false;
}
}
e = new Node<T>(obj, p);
if (left)
p.left = e;
else
p.right = e;
size++;
return e.element;
}

public boolean contains(Object obj)


{
return getNode(obj) != null;
}

private Node<T> deleteNode(Node<T> p)


{
size--;
if (p.left != null && p.right != null) {
Node<T> s = successor(p);
p.element = s.element;
p = s;
}

Node<T> replacement;
if (p.left != null)
replacement = p.left;
else
replacement = p.right;

if (replacement != null) {
replacement.parent = p.parent;
if (p.parent == null)
root = replacement;
else if (p == p.parent.left)
p.parent.left = replacement;
else
p.parent.right = replacement;
} else if (p.parent == null) {
root = null;
} else {
if (p == p.parent.left)
p.parent.left = null;
else
p.parent.right = null;
}
return p;
}

private Node<T> successor(Node<T> e)


{
if (e == null) {
return null;
} else if (e.right != null) {
Node<T> p = e.right;
while (p.left != null)
p = p.left;
return p;
} else {
Node<T> p = e.parent;
Node<T> child = e;
while (p != null && child == p.right) {
child = p;
p = p.parent;
}
return p;
}
}

private class TreeIterator implements Iterator<T>


{
private Node<T> lastReturned = null;
private Node<T> next;

private TreeIterator()
{
next = root;
if (next != null)
while (next.left != null)
next = next.left;
}

public boolean hasNext()


{
return next != null;
}

public T next()
{
if (next == null)
throw new NoSuchElementException();
lastReturned = next;
next = successor(next);
return lastReturned.element;
}

public void remove()


{
if (lastReturned == null)
throw new IllegalStateException();
if (lastReturned.left != null && lastReturned.right != null)
next = lastReturned;
deleteNode(lastReturned);
lastReturned = null;
}
}

BinarySearchTree.java

1. Write a test program to test add, remove, contains and the iterator
2. Write a method (using recursion) to count the average depth of a tree (you are allowed to modify the class). To compute the average depth, first compute total depth of all the nodes and then divide by the number of nodes.
3. Write a program to compute the average depth versus the number of inputs for randomly generated numbers. Plot this as a graph.

4-5 are Supplemental Questions

4. Modify the Binary Search Tree to implement a Map interface


5. Write a program to display a tree Hint

Graph Algorithms

6. Write a Java Graph class which stores a set of vertices and their 2-D positions. It should also store a set of edges together with weights on the edges. Hint

7. Write a method randomGraph(n,p) which generates a graph with n vertices placed at random in the unit square and where the probability of an edge is p. The weight of the edges are the distances between the
nodes.

To visualise the graph use the follow program (this is just for visualisation, to use it create an instance of GraphDisplay)

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

class GraphDisplay extends JComponent


{
public static void main(String[] args)
{
GraphDisplay gd = new GraphDisplay();
gd.showInWindow(400,400,"A Random Graph");

// Add some randomly placed nodes


int n = 20;
for(int i=0; i<n; i++)
gd.addNode(i,Math.random(),Math.random());

// Add a few random edges in slow motion


try{
for(int j=0; j<2*n; j++)
{
int a = (int)(Math.random()*n);
int b = (int)(Math.random()*n);
gd.addEdge(a,b,Color.red);
Thread.sleep(500);
gd.addEdge(a,b,Color.black);
}
}catch(InterruptedException e) {
}
}

public GraphDisplay()
{
minX = minY = Double.POSITIVE_INFINITY;
maxX = maxY = Double.NEGATIVE_INFINITY;
}

public synchronized void addNode(Object identifier, double x, double y,


Color col)
{
maxX = Math.max(maxX,x);
maxY = Math.max(maxY,y);
minX = Math.min(minX,x);
minY = Math.min(minY,y);
nodes.put(identifier,new Node(x,y,col));
repaint();
}

public synchronized void addNode(Object identifier, double x, double y)


{
maxX = Math.max(maxX,x);
maxY = Math.max(maxY,y);
minX = Math.min(minX,x);
minY = Math.min(minY,y);
nodes.put(identifier,new Node(x,y,NODE_COLOR));
repaint();
}

public synchronized void addEdge(Object start, Object end, Color c)


{
removeEdge(start,end);
edges.add(new Edge(start,end,c));
repaint();
}

public synchronized boolean removeEdge(Object start, Object end)


{
Iterator<Edge> it = edges.iterator();
while(it.hasNext())
{
Edge tmp = it.next();
if(tmp.joins(start,end))
{
it.remove();
repaint();
return true;
}
}
return false;
}

public void addEdge(Object start, Object end)


{
addEdge(start,end,Color.black);
}

public JFrame showInWindow(int width, int height, String title)


{
JFrame f = new JFrame();
f.add(this);
f.setSize(width,height);
f.setTitle(title);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
f.setVisible(true);
return f;
}

public void paint(Graphics g)


{
if(nodes.isEmpty())
return;

double xscl = (getSize().width -2*MARGIN) / (maxX-minX);


double yscl = (getSize().height-2*MARGIN) / (maxY-minY);

g.translate(+MARGIN,+MARGIN);

synchronized(this){
for(Edge e: edges)
e.paint(g,xscl,yscl,minX,minY);
for(Node n: nodes.values())
n.paint(g,xscl,yscl,minX,minY);
}

g.translate(-MARGIN,-MARGIN);
}

protected double minX,maxX,minY,maxY;


protected HashMap<Object,Node> nodes = new HashMap<Object,Node>();
protected Vector<Edge> edges = new Vector<Edge>();

protected int MARGIN = 20;


protected int NODE_RADIUS = 5;
protected Color NODE_COLOR = Color.blue.brighter();

private class Node


{
public Node(double x, double y, Color col)
{
this.x = x;
this.y = y;
this.col = col;
}

public void paint(Graphics g, double xscl, double yscl, double tx, double ty)
{
g.setColor(col);
g.fillOval(
(int)((x-tx)*xscl - NODE_RADIUS),
(int)((y-ty)*yscl - NODE_RADIUS),
2*NODE_RADIUS,
2*NODE_RADIUS
);
}

protected double x,y;


protected Color col;

private class Edge


{
public Edge(Object start, Object end, Color col)
{
this.start = start;
this.end = end;
this.col = col;
}

public boolean joins(Object a, Object b)


{
return (start.equals(a) && end.equals(b))
|| (start.equals(b) && end.equals(a));
}

public void paint(Graphics g, double xscl, double yscl, double tx, double ty)
{
Node a = nodes.get(start);
Node b = nodes.get(end);
g.setColor(col);
g.drawLine(
(int)(xscl*(a.x-tx)),
(int)(yscl*(a.y-ty)),
(int)(xscl*(b.x-tx)),
(int)(yscl*(b.y-ty))
);
}

protected Object start,end;


protected Color col;
}
}

GraphDisplay1.java

8. Write a method that implements Prim's algorithm to compute the minimum spanning tree.

Prim's algorithm is illsutrated in here. Your program should use your Graph class and the Java's collection class priority queue. You should visualise the answer using GraphDisplay.

9. Write a method that implements Kruskal's algorithm to compute the minimum spanning tree.

You will need to use the DisjointSets class

public class DisjointSets


{
public DisjointSets(int numElements)
{
s = new int[numElements];
for(int i=0; i<s.length; i++)
s[i] = -1;
}

public void union(int root1, int root2)


{
if (s[root2]<s[root1]) {
s[root1] = root2;
} else {
if (s[root1]==s[root2])
s[root1]--;
s[root2] = root1;
}
}

public int find(int x)


{
if (s[x]<0)
return x;
else
return s[x] = find(s[x]);
}

private int[] s;
}

DisjointSets.java
To use the DisjointSet class you simple write

/* Create a disjoint sets object*/

DisjointSets dj = new DisjointSets(n);

/* Find to shortest edge (a,b) */

int finda = dj.find(a);


int findb = dj.find(b);

if (finda!=findb) {
// vertices a and b belong to different trees
dj.union(finda, findb); // NOT dj.union(a,b)
/* add (a,b) to spanning tree */
}

usingds.java

Supplemental Question: Branch and Bound

10. Add a method to the graph-colouring program in tutorial 1 so that it performs a branch and bound search (see lesson 17). This should involve modifying the exhaustive search. Compare the time complexity with exhaustive
enumeration.

previous

Das könnte Ihnen auch gefallen