Ordered List e BinarySearchTree
This commit is contained in:
51
com/xgiovio/OrderedListSetTest.java
Normal file
51
com/xgiovio/OrderedListSetTest.java
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package com.xgiovio;
|
||||||
|
|
||||||
|
import position.NodePositionList;
|
||||||
|
import set.OrderedListSet;
|
||||||
|
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created with MONSTER.
|
||||||
|
* User: xgiovio
|
||||||
|
* Date: 18/05/2014
|
||||||
|
* Time: 15:58
|
||||||
|
*/
|
||||||
|
public class OrderedListSetTest {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
NodePositionList<String> t = new NodePositionList<String>();
|
||||||
|
t.addLast("1");
|
||||||
|
t.addLast("2");
|
||||||
|
t.addLast("5");
|
||||||
|
t.addLast("6");
|
||||||
|
t.addLast("8");
|
||||||
|
OrderedListSet<String> a = new OrderedListSet<String>(t);
|
||||||
|
System.out.println(a);
|
||||||
|
|
||||||
|
|
||||||
|
NodePositionList<String> t2 = new NodePositionList<String>();
|
||||||
|
t2.addLast("3");
|
||||||
|
t2.addLast("4");
|
||||||
|
t2.addLast("5");
|
||||||
|
t2.addLast("7");
|
||||||
|
t2.addLast("8");
|
||||||
|
t2.addLast("9");
|
||||||
|
t2.addLast("12");
|
||||||
|
OrderedListSet<String> a2 = new OrderedListSet<String>(t2);
|
||||||
|
System.out.println(a2);
|
||||||
|
|
||||||
|
a.subtract(a2);
|
||||||
|
System.out.println(a);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
180
dictionary/BinarySearchTree.java
Normal file
180
dictionary/BinarySearchTree.java
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
package dictionary;
|
||||||
|
import exceptions.InvalidEntryException;
|
||||||
|
import position.NodePositionList;
|
||||||
|
import position.Position;
|
||||||
|
import position.PositionList;
|
||||||
|
import priorityqueue.Entry;
|
||||||
|
import tree.binarytree.BTPosition;
|
||||||
|
import tree.binarytree.LinkedBinaryTree;
|
||||||
|
import utility.DefaultComparator;
|
||||||
|
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class BinarySearchTree<K,V> extends LinkedBinaryTree<Entry<K,V>> implements Dictionary<K,V> {
|
||||||
|
|
||||||
|
protected Comparator<K> C; // comparator
|
||||||
|
protected Position<Entry<K,V>> actionPos; // insert node or removed node's parent
|
||||||
|
protected int numEntries = 0; // number of entries
|
||||||
|
|
||||||
|
public BinarySearchTree() {
|
||||||
|
C = new DefaultComparator<K>();
|
||||||
|
addRoot(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BinarySearchTree(Comparator<K> c) {
|
||||||
|
C = c;
|
||||||
|
addRoot(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Nested class for location-aware binary search tree entries */
|
||||||
|
protected static class BSTEntry<K,V> implements Entry<K,V> {
|
||||||
|
protected K key;
|
||||||
|
protected V value;
|
||||||
|
protected Position<Entry<K,V>> pos;
|
||||||
|
BSTEntry(K k, V v, Position<Entry<K,V>> p) {
|
||||||
|
key = k; value = v; pos = p;
|
||||||
|
}
|
||||||
|
public K getKey() { return key; }
|
||||||
|
public V getValue() { return value; }
|
||||||
|
public Position<Entry<K,V>> position() { return pos; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Extracts the key of the entry at a given node of the tree. */
|
||||||
|
protected K key(Position<Entry<K,V>> position) {
|
||||||
|
return position.element().getKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Extracts the value of the entry at a given node of the tree. */
|
||||||
|
protected V value(Position<Entry<K,V>> position) {
|
||||||
|
return position.element().getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Extracts the entry at a given node of the tree. */
|
||||||
|
protected Entry<K,V> entry(Position<Entry<K,V>> position) {
|
||||||
|
return position.element();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Replaces an entry with a new entry (and reset the entry's location) */
|
||||||
|
protected void replaceEntry(Position <Entry<K,V>> pos, Entry<K,V> ent) {
|
||||||
|
((BSTEntry<K,V>) ent).pos = pos;
|
||||||
|
replace(pos, ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void checkKey(K key) throws InvalidKeyException {
|
||||||
|
if(key == null)
|
||||||
|
throw new InvalidKeyException("null key");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkEntry(Entry<K,V> ent) throws InvalidEntryException {
|
||||||
|
if(ent == null || !(ent instanceof BSTEntry))
|
||||||
|
throw new InvalidEntryException("invalid entry");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Entry<K,V> insertAtExternal(Position<Entry<K,V>> v, Entry<K,V> e) {
|
||||||
|
expandExternal(v,null,null);
|
||||||
|
replace(v, e);
|
||||||
|
numEntries++;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
/** Auxiliary method for removing an external node and its parent */
|
||||||
|
protected void removeExternal(Position<Entry<K,V>> v) {
|
||||||
|
removeAboveExternal(v);
|
||||||
|
numEntries--;
|
||||||
|
}
|
||||||
|
/** Auxiliary method used by find, insert, and remove. */
|
||||||
|
protected Position<Entry<K,V>> treeSearch(K key, Position<Entry<K,V>> pos) {
|
||||||
|
if (isExternal(pos)) return pos; // key not found; return external node
|
||||||
|
else {
|
||||||
|
K curKey = key(pos);
|
||||||
|
int comp = C.compare(key, curKey);
|
||||||
|
if (comp < 0)
|
||||||
|
return treeSearch(key, left(pos)); // search left subtree
|
||||||
|
else if (comp > 0)
|
||||||
|
return treeSearch(key, right(pos)); // search right subtree
|
||||||
|
return pos; // return internal node where key is found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Adds to L all entries in the subtree rooted at v having keys equal to k
|
||||||
|
protected void addAll(PositionList<Entry<K,V>> L, Position<Entry<K,V>> v, K k) {
|
||||||
|
if (isExternal(v)) return;
|
||||||
|
Position<Entry<K,V>> pos = treeSearch(k, v);
|
||||||
|
if (!isExternal(pos)) { // we found an entry with key equal to k
|
||||||
|
addAll(L, left(pos), k);
|
||||||
|
L.addLast(pos.element()); // add entries in inorder
|
||||||
|
addAll(L, right(pos), k);
|
||||||
|
} // this recursive algorithm is simple, but it's not the fastest
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the number of entries in the tree. */
|
||||||
|
public int size() { return numEntries; }
|
||||||
|
|
||||||
|
/** Returns whether the tree is empty. */
|
||||||
|
public boolean isEmpty() { return size() == 0; }
|
||||||
|
|
||||||
|
/** Returns an entry containing the given key. Returns null if no such entry exists. */
|
||||||
|
public Entry<K,V> find(K key) throws InvalidKeyException {
|
||||||
|
checkKey(key); // may throw an InvalidKeyException
|
||||||
|
Position<Entry<K,V>> curPos = treeSearch(key, root());
|
||||||
|
actionPos = curPos; // node where the search ended
|
||||||
|
if (isInternal(curPos)) return entry(curPos);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns an iterable collection of all the entries containing the given key. */
|
||||||
|
public Iterable<Entry<K,V>> findAll(K key) throws InvalidKeyException {
|
||||||
|
checkKey(key); // may throw an InvalidKeyException
|
||||||
|
PositionList<Entry<K,V>> L = new NodePositionList<Entry<K,V>>();
|
||||||
|
addAll(L, root(), key);
|
||||||
|
return L;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Inserts an entry into the tree and returns the newly created entry. */
|
||||||
|
public Entry<K,V> insert(K k, V x) throws InvalidKeyException {
|
||||||
|
checkKey(k); // may throw an InvalidKeyException
|
||||||
|
Position<Entry<K,V>> insPos = treeSearch(k, root());
|
||||||
|
while (!isExternal(insPos)) // iterative search for insertion position
|
||||||
|
insPos = treeSearch(k, left(insPos));
|
||||||
|
actionPos = insPos; // node where the new entry is being inserted
|
||||||
|
return insertAtExternal(insPos, new BSTEntry<K,V>(k, x, insPos));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Removes and returns a given entry. */
|
||||||
|
public Entry<K,V> remove(Entry<K,V> ent) throws InvalidEntryException {
|
||||||
|
checkEntry(ent); // may throw an InvalidEntryException
|
||||||
|
Position<Entry<K,V>> remPos = ((BSTEntry<K,V>) ent).position();
|
||||||
|
Entry<K,V> toReturn = entry(remPos); // entry to be returned
|
||||||
|
if (isExternal(left(remPos))) remPos = left(remPos); // left easy case
|
||||||
|
else if (isExternal(right(remPos))) remPos = right(remPos); // right easy case
|
||||||
|
else { // entry is at a node with internal children
|
||||||
|
Position<Entry<K,V>> swapPos = remPos; // find node for moving entry
|
||||||
|
remPos = right(swapPos);
|
||||||
|
do
|
||||||
|
remPos = left(remPos);
|
||||||
|
while (isInternal(remPos));
|
||||||
|
replaceEntry(swapPos, (Entry<K,V>) parent(remPos).element());
|
||||||
|
}
|
||||||
|
actionPos = sibling(remPos); // sibling of the leaf to be removed
|
||||||
|
removeExternal(remPos);
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns an iterator containing all entries in the tree. */
|
||||||
|
public Iterable<Entry<K,V>> entries() {
|
||||||
|
PositionList<Entry<K,V>> entries = new NodePositionList<Entry<K,V>>();
|
||||||
|
Iterable<Position<Entry<K,V>>> positer = positions();
|
||||||
|
for (Position<Entry<K,V>> cur: positer)
|
||||||
|
if (isInternal(cur))
|
||||||
|
entries.addLast(cur.element());
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -20,16 +20,26 @@ public class OrderedListSet <E> implements Set<E> {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
OrderedListSet() {
|
public OrderedListSet() {
|
||||||
L = new NodePositionList<E>();
|
L = new NodePositionList<E>();
|
||||||
c = new DefaultComparator();
|
c = new DefaultComparator<E>();
|
||||||
}
|
}
|
||||||
|
|
||||||
OrderedListSet(Comparator<E> in_c) {
|
public OrderedListSet(Comparator<E> in_c) {
|
||||||
L = new NodePositionList<E>();
|
L = new NodePositionList<E>();
|
||||||
c = in_c;
|
c = in_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OrderedListSet(PositionList<E> in_l){
|
||||||
|
L = in_l;
|
||||||
|
c = new DefaultComparator<E>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public OrderedListSet(PositionList<E> in_l,Comparator<E> in_c ){
|
||||||
|
L = in_l;
|
||||||
|
c = in_c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -47,50 +57,59 @@ public class OrderedListSet <E> implements Set<E> {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<E> union(Set<E> B) {return null;
|
public Set<E> union(Set<E> B) {
|
||||||
|
MergeUnion<E> ret = new MergeUnion<E>(L, ((OrderedListSet<E>)B).L , c );
|
||||||
|
L = ret.getResult();
|
||||||
|
return this;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<E> intersect(Set<E> B) {
|
public Set<E> intersect(Set<E> B) {
|
||||||
return null;
|
MergeIntersect<E> ret = new MergeIntersect<E>(L, ((OrderedListSet<E>)B).L , c );
|
||||||
|
L = ret.getResult();
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<E> subtract(Set<E> B) {
|
public Set<E> subtract(Set<E> B) {
|
||||||
return null;
|
MergeSubtract<E> ret = new MergeSubtract<E>(L, ((OrderedListSet<E>)B).L , c );
|
||||||
|
L = ret.getResult();
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return L.toString();
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////// inner class override methods from merge template /////
|
//////////////////////// inner class override methods from merge template /////
|
||||||
|
|
||||||
protected class MergeUnion<E> extends MergeTemplate<E>{
|
protected class MergeUnion<E> extends MergeTemplate<E>{
|
||||||
|
|
||||||
public MergeUnion (PositionList<E> A , PositionList<E> B, DefaultComparator<E> c){
|
public MergeUnion (PositionList<E> A , PositionList<E> B, Comparator<E> c){
|
||||||
super(A,B,c);
|
super(A,B,c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void aIsLess(E a) {
|
protected void aIsLess(E a) {
|
||||||
|
s.addLast(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void bIsLess(E b) {
|
protected void bIsLess(E b) {
|
||||||
|
s.addLast(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void bothAreEqual(E a, E b) {
|
protected void bothAreEqual(E a, E b) {
|
||||||
|
s.addLast(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class MergeIntersect<E> extends MergeTemplate<E>{
|
protected class MergeIntersect<E> extends MergeTemplate<E>{
|
||||||
|
|
||||||
public MergeIntersect (PositionList<E> A , PositionList<E> B, DefaultComparator<E> c){
|
public MergeIntersect (PositionList<E> A , PositionList<E> B, Comparator<E> c){
|
||||||
super(A,B,c);
|
super(A,B,c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,19 +125,19 @@ public class OrderedListSet <E> implements Set<E> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void bothAreEqual(E a, E b) {
|
protected void bothAreEqual(E a, E b) {
|
||||||
|
s.addLast(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class MergeSubtract<E> extends MergeTemplate<E>{
|
protected class MergeSubtract<E> extends MergeTemplate<E>{
|
||||||
|
|
||||||
public MergeSubtract (PositionList<E> A , PositionList<E> B, DefaultComparator<E> c){
|
public MergeSubtract (PositionList<E> A , PositionList<E> B, Comparator<E> c){
|
||||||
super(A,B,c);
|
super(A,B,c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void aIsLess(E a) {
|
protected void aIsLess(E a) {
|
||||||
|
s.addLast(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ import java.util.Iterator;
|
|||||||
*/
|
*/
|
||||||
public abstract class MergeTemplate<E> {
|
public abstract class MergeTemplate<E> {
|
||||||
|
|
||||||
PositionList<E> s = new NodePositionList<E>();
|
protected PositionList<E> s = new NodePositionList<E>();
|
||||||
Comparator<E> c = null;
|
protected Comparator<E> c = null;
|
||||||
|
|
||||||
public MergeTemplate (PositionList<E> A, PositionList <E> B){
|
public MergeTemplate (PositionList<E> A, PositionList <E> B){
|
||||||
this(A,B,new DefaultComparator<E>());
|
this(A,B,new DefaultComparator<E>());
|
||||||
@@ -29,29 +29,49 @@ public abstract class MergeTemplate<E> {
|
|||||||
public MergeTemplate (PositionList<E> A, PositionList <E> B, Comparator<E> in_c){
|
public MergeTemplate (PositionList<E> A, PositionList <E> B, Comparator<E> in_c){
|
||||||
|
|
||||||
c = in_c;
|
c = in_c;
|
||||||
E a,b;
|
E a = null ,b = null;
|
||||||
Iterator<E> Ait, Bit;
|
Iterator<E> Ait, Bit;
|
||||||
Ait = A.iterator();
|
Ait = A.iterator();
|
||||||
Bit = B.iterator();
|
Bit = B.iterator();
|
||||||
|
|
||||||
while (!(Ait.hasNext()) && !(Bit.hasNext())) {
|
|
||||||
|
|
||||||
|
if ( Ait.hasNext() && Bit.hasNext() ){
|
||||||
a = Ait.next();
|
a = Ait.next();
|
||||||
b= Bit.next();
|
b = Bit.next();
|
||||||
|
for (; true; ) {
|
||||||
|
|
||||||
if ( c.compare(a,b) < 0 )
|
if (c.compare(a, b) < 0) {
|
||||||
aIsLess(a);
|
aIsLess(a);
|
||||||
else if (c.compare(a,b) > 0)
|
if (Ait.hasNext())
|
||||||
bIsLess(b);
|
a = Ait.next();
|
||||||
else // se b = a
|
else
|
||||||
bothAreEqual(a, b);
|
break;
|
||||||
|
} else {
|
||||||
|
if (c.compare(a, b) > 0) {
|
||||||
|
bIsLess(b);
|
||||||
|
if (Bit.hasNext())
|
||||||
|
b = Bit.next();
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
} else {// se b = a
|
||||||
|
bothAreEqual(a, b);
|
||||||
|
if (Ait.hasNext() && Bit.hasNext()) {
|
||||||
|
a = Ait.next();
|
||||||
|
b = Bit.next();
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (!(Ait.hasNext())) {
|
while ( Ait.hasNext() ) {
|
||||||
a = Ait.next();
|
a = Ait.next();
|
||||||
aIsLess(a);
|
aIsLess(a);
|
||||||
}
|
}
|
||||||
while (!(Bit.hasNext())) {
|
while ( Bit.hasNext()) {
|
||||||
b = Bit.next();
|
b = Bit.next();
|
||||||
bIsLess(b);
|
bIsLess(b);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user