Løsningsforslag - oppgaver i Avsnitt 5.1.11


Oppgave 2

  for (Iterator<Character> i = tre.iterator(); i.hasNext(); )
    System.out.print(i.next() + " ");

  // Utskrift: H D I B J E A F C G

Oppgave 3

  int antall = 0;
  for (char c : tre) antall++;
  System.out.println(antall);

Oppgave 4

Kjør flg. kode. Hva skjer?

  int[] p = {1,2,3,4,5,6,7,8,9,10};               // nodeposisjoner
  char[] v = "ABCDEFGHIJ".toCharArray();          // nodeverdier

  BinTre<Character> tre = new BinTre<>();         // et tomt binærtre
  for (int i = 0; i < p.length; i++) tre.leggInn(p[i],v[i]);

  Iterator<Character> i = tre.iterator();
  System.out.println(i.next());

  i.remove();

Oppgave 5

  char c = 'F';

  for (Iterator<Character> i = tre.iterator(); i.hasNext(); )
  {
    if (i.next() == c)
    {
      System.out.println("Fant " + c + "!" );
      break;
    }
  }

Oppgave 6

  private class OmvendtInordenIterator implements Iterator<T>
  {
    private final Stakk<Node<T>> s;    // hjelpestakk
    private Node<T> p;                 // hjelpepeker

    private Node<T> sist(Node<T> q)    // en hjelpemetode
    {
      while (q.høyre != null)          // starter i q
      {
        s.leggInn(q);                  // legger q på stakken
        q = q.høyre;                   // går videre mot høyre
      }
      return q;                        // q er lengst ned til høyre
    }

    public OmvendtInordenIterator()    // konstruktør
    {
      s = new TabellStakk<>();
      if (tom()) return;               // treet er tomt
      p = sist(rot);                   // bruker hjelpemetoden
    }

    @Override
    public T next()
    {
      if (!hasNext()) throw new NoSuchElementException();

      T verdi = p.verdi;               // tar vare på verdien i noden p

      if (p.venstre != null)           // p har venstre subtre
        p = sist(p.venstre);
      else if (s.tom()) p = null;      // stakken er tom
      else  p = s.taUt();              // tar fra stakken       

      return verdi;                    // returnerer verdien
    }

    @Override
    public boolean hasNext()
    {
      return p != null;
    }

  }  // OmvendtInordenIterator

  public Iterator<T> omvendtIterator()
  {
    return new OmvendtInordenIterator();
  }

} // class BinTre<T>

Oppgave 7

  private class PreordenIterator implements Iterator<T>
  {
    private final Stakk<Node<T>> s;
    private Node<T> p;

    // konstruktør
    private PreordenIterator()
    {
      s = new TabellStakk<>();
      p = rot;
    }

    @Override
    public boolean hasNext()
    {
      return p != null;
    }

    @Override
    public T next()  // neste er med hensyn på preorden
    {
      if (!hasNext()) throw new NoSuchElementException();

      T verdi = p.verdi;

      if (p.venstre != null)                  // går til venstre
      {
        if (p.høyre != null) s.leggInn(p.høyre);
        p = p.venstre;
      }
      else if (p.høyre != null) p = p.høyre;  // går til høyre
      else if (s.tom()) p = null;             // ingen flere i treet
      else p = s.taUt();                      // tar fra satkken

      return verdi;
    }

  } // PreordenIterator

  public Iterator<T> preIterator()
  {
    return new PreordenIterator();
  }

Oppgave 8

Oppgave 9

  private class NivåordenIterator implements Iterator<T>
  {
    private final Kø<Node<T>> ;
    private Node<T> p;

    // konstruktør
    private NivåordenIterator()
    {
       = new TabellKø<>();
      if (tom()) return;
      p = rot;
    }

    @Override
    public boolean hasNext()
    {
      return p != null;
    }

    @Override
    public T next()  // neste med hensyn på nivåorden
    {
      if (!hasNext()) throw new NoSuchElementException();

      T verdi = p.verdi;

      if (p.venstre != null) .leggInn(p.venstre);
      if (p.høyre != null) .leggInn(p.høyre);
      p = .tom() ? null : .taUt();

      return verdi;
    }

  } // NivåordenIterator

  public Iterator<T> nivåIterator()
  {
    return new NivåordenIterator();
  }

Oppgave 10

  private static class InordenIterator<S> implements Iterator<S>
  {
    private final Stakk<Node<S>> s = new TabellStakk<>();
    private Node<S> p = null;

    private Node<S> først(Node<S> q)   // en hjelpemetode
    {
      while (q.venstre != null)        // starter i q
      {
        s.leggInn(q);                  // legger q på stakken
        q = q.venstre;                 // går videre mot venstre
      }
      return q;                        // q er lengst ned til venstre
    }

    private InordenIterator(Node<S> rot)  // konstruktør
    {
      if (rot == null) return;         // treet er tomt
      p = først(rot);                  // bruker hjelpemetoden
    }

    @Override
    public S next()
    {
      if (!hasNext()) throw new NoSuchElementException("Ingen verdier!");

      S verdi = p.verdi;                        // tar vare på verdien

      if (p.høyre != null) p = først(p.høyre);  // p har høyre subtre
      else if (s.tom()) p = null;               // stakken er tom
      else p = s.taUt();                        // tar fra stakken

      return verdi;                             // returnerer verdien
    }

    @Override
    public boolean hasNext()
    {
      return p != null;
    }

  } // InordenIterator

  @Override
  public Iterator<T> iterator()     // skal ligge i class BinTre
  {
    return new InordenIterator<>(rot);
  }

Oppgave 11

  public Iterator<T> iterator()
  {
    return new Iterator<T> ()  // en anonym klasse
    {
      private final Stakk<Node<T>> stakk = new TabellStakk<>();
      private Node<T> p = tom() ? null : først(rot);

      private Node<T> først(Node<T> q)
      {
        while (q.venstre != null)
        {
          stakk.leggInn(q);
          q = q.venstre;
        }
        return q;
      }

      @Override
      public boolean hasNext()
      {
        return p != null;
      }

      @Override
      public T next()
      {
        if (!hasNext()) throw
          new NoSuchElementException("Tomt eller ingen flere igjen!");

        T verdi = p.verdi;

        if (p.høyre != null) p = først(p.høyre);
        else if (stakk.tom()) p = null;
        else p = stakk.taUt();

        return verdi;
      }
    };
  }

Oppgave 12

import java.util.*;

public class BinTre<T> implements Iterable<T>
{
  private static final class Node<T> // en indre nodeklasse
  {
    private T verdi;            // nodens verdi
    private Node<T> venstre;    // peker til venstre barn/subtre
    private Node<T> høyre;      // peker til høyre barn/subtre

    private Node(T verdi, Node<T> v, Node<T> h) // konstruktør
    {
      this.verdi = verdi;
      venstre = v;
      høyre = h;
    }

    private Node(T verdi)  // konstruktør
    {
      this.verdi = verdi;
    }
  } // class Node<T>

  private Node<T> rot;            // peker til rotnoden
  private int antall;             // antall noder i treet
  private int endringer;    // antall endringer i treet

  private Node<T> finnNode(int k)    // finner noden i posisjon k
  {
    if (k < 1) return null;

    Node<T> p = rot;                         // hjelpepeker
    int n = Integer.highestOneBit(k >> 1);   // n = 100...00

    for (; p != null && n > 0; n >>= 1)
      p = (k & n) == 0 ? p.venstre : p.høyre;

    return p;   // p blir null hvis k ikke er i treet
  }

  public BinTre() // konstruktør
  {
    rot = null;
    antall = 0;
    endringer = 0;
  }

  public BinTre(int[] p, T[] v) // konstruktør
  {
    if (p.length > v.length) throw new
      IllegalArgumentException("Tabell v har for få verdier");

    for (int i = 0; i < p.length; i++) leggInn(p[i],v[i]);
  }

  public int antall()
  {
    return antall;  // returnerer antallet
  }

  public boolean tom()
  {
    return antall == 0;  // tomt tre?
  }

  public final void leggInn(int k, T verdi)
  {
    if (k < 1) throw new
      IllegalArgumentException("Posisjonstallet k(" + k + ") < 1!");

    Node<T> p = rot, q = null;               // hjelpepekere

    int n = Integer.highestOneBit(k >> 1);   // n = 100...00

    while (p != null && n > 0)
    {
      q = p;
      p = (n & k) == 0 ? p.venstre : p.høyre;
      n >>= 1;  // bitforskyver n
    }

    if (n > 0) throw new
      IllegalArgumentException("Posisjonen k(" + k + ") er for stor!");
    else if (p != null) throw new
      IllegalArgumentException("Posisjonen k(" + k + ") finnes fra før!");

    p = new Node<>(verdi);    // ny node

    if (q == null) rot = p;   // tomt tre - ny rot
    else if ((k & 1) == 0)    // sjekker siste siffer i k
      q.venstre = p;
    else
      q.høyre = p;

    antall++;           // en ny verdi i treet
    endringer++;  // ny verdi er en endring
  }

  public boolean finnes(int k)
  {
    return finnNode(k) != null;
  }

  public T hent(int k)
  {
    Node<T> p = finnNode(k);

    if (p == null) throw new
      IllegalArgumentException("Posisjon k(" + k + ") er ukjent!");

    return p.verdi;
  }

  public T oppdater(int k, T nyverdi)
  {
    Node<T> p = finnNode(k);

    if (p == null) throw new
      IllegalArgumentException("Posisjon k(" + k + ") er ukjent!");

    T gammelverdi = p.verdi;  // tar vare på gammel verdi
    p.verdi = nyverdi;        // oppdaterer
    endringer++;        // en endring
    return gammelverdi;       // returnerer gammel verdi
  }

  public T fjern(int k)  // k må representere en bladnode
  {
    if (k < 1) throw new
      IllegalArgumentException("Posisjon k(" + k + ") < 1!");

    Node<T> p = rot, q = null;               // hjelpepekere
    int n = Integer.highestOneBit(k >> 1);   // binært siffer

    while (p != null && n > 0)
    {
      q = p;
      p = (n & k) == 0 ? p.venstre : p.høyre;
      n >>= 1;
    }

    if (p == null) throw new
      IllegalArgumentException("Posisjon k(" + k + ") er utenfor treet!");

    if (p.venstre != null || p.høyre != null) throw new
      IllegalArgumentException("Posisjon k(" + k + ") er ingen bladnode!");

    if (p == rot) rot = null;
    else if (p == q.venstre) q.venstre = null;
    else q.høyre = null;

    antall--;           // en verdi mindre
    endringer++;  // en endring
    return p.verdi;
  }

  private class InordenIterator implements Iterator<T>
  {
    private Stakk<Node<T>> s;
    private Node<T> p;
    private int iteratorendringer;

    private Node<T> først(Node<T> q)   // en hjelpemetode
    {
      while (q.venstre != null)        // starter i q
      {
        s.leggInn(q);                  // legger q på stakken
        q = q.venstre;                 // går videre mot venstre
      }
      return q;                        // q er lengst ned til venstre
    }

    private InordenIterator()          // konstruktør
    {
      s = new TabellStakk<>();         // en hjelpestakk
      p = null;
      if (tom()) return;               // treet er tomt
      p = først(rot);                  // bruker hjelpemetoden
      iteratorendringer = endringer;
    }

    @Override
    public T next()
    {
      if (!hasNext()) throw new NoSuchElementException("Ingen verdier!");

      if (iteratorendringer != endringer) throw
        new ConcurrentModificationException("Treet er endret!");

      T verdi = p.verdi;                        // tar vare på verdien

      if (p.høyre != null) p = først(p.høyre);  // p har høyre subtre
      else if (s.tom()) p = null;               // stakken er tom
      else p = s.taUt();                        // tar fra stakken

      return verdi;                             // returnerer verdien
    }

    @Override
    public boolean hasNext()
    {
      return p != null;
    }
  }

  @Override
  public Iterator<T> iterator()     // skal ligge i class BinTre
  {
    return new InordenIterator();
  }

} // class BinTre<T>