Le support aux utilisateurs et les demandes de création de comptes externes doivent être faites depuis les issues du projet GitLab HEFR (https://gitlab.forge.hefr.ch/forge-hefr/gitlab-hefr)

Commit 76637448 authored by Frédéric Bapst's avatar Frédéric Bapst
Browse files

add s10

parent 2f1a45ed
package s10;
public class BST<E extends Comparable<E>> {
protected BTree<E> tree;
protected int crtSize;
public BST() {
tree = new BTree<>();
crtSize = 0;
}
public BST(E[] tab) { // PRE sorted, no duplicate
tree = optimalBST(tab, 0, tab.length-1);
crtSize = tab.length;
}
public void add(E e) {
BTreeItr<E> ti = locate(e);
if (!ti.isBottom()) return;
ti.insert(e);
crtSize++;
}
public void remove(E e) {
BTreeItr<E> ti = locate(e);
if(ti.isBottom()) return;
crtSize--;
// Alternative 1
while(ti.hasRight()) {
ti.rotateLeft();
ti = ti.left();
}
BTree<E> l = ti.left().cut();
ti.cut();
ti.paste(l);
// Alternative 2
// remplacer avec le plus grand dans le ss-arbre gauche...
// locate(e);
// if (t.isLeafArc()) return;
// crtSize--;
// if (!t.hasRight()) {t.paste(t.left ().cut()); return;}
// if (!t.hasLeft()) {t.paste(t.right().cut()); return;}
// t.update(t.right().leftMost().up().consult());
// t.goToRight().goToLeftMost().goToUp();
// t.paste(t.right().cut());
}
public boolean contains(E e) {
BTreeItr<E> ti = locate(e);
return ! ti.isBottom();
}
public int size() {
return crtSize;
}
public boolean isEmpty() {
return size() == 0;
}
public E minElt() {
return (tree.root().leftMost().up().consult());
}
public E maxElt() {
return (tree.root().rightMost().up().consult());
}
@Override public String toString() {
return ""+tree;
}
public String toReadableString() {
String s = tree.toReadableString();
s += "size=="+crtSize+"\n";
return s;
}
// --------------------------------------------------
// --- Non-public methods
// --------------------------------------------------
/** returns where e is, or where it should be inserted as a leaf */
protected BTreeItr<E> locate(E e) {
BTreeItr<E> ti = tree.root();
while(!ti.isBottom()) {
E c = ti.consult();
if (e.compareTo(c)==0) break;
if (e.compareTo(c)< 0) ti = ti.left();
else ti = ti.right();
}
return ti;
}
private BTree<E> optimalBST(E[] sorted, int left, int right) {
BTree<E> r = new BTree<>();
BTreeItr<E> ri = r.root();
if (left>right) return r;
int mid = (left + right) /2;
ri.insert(sorted[mid]);
ri.left( ).paste(optimalBST(sorted, left, mid-1));
ri.right().paste(optimalBST(sorted, mid+1, right));
return r;
}
}
package s10;
import java.util.ArrayList;
import java.util.List;
public class BTree<E> {
//======================================================================
static class BTNode <E> {
E elt;
BTNode<E> left, right, parent;
public BTNode(E e, BTNode<E> l, BTNode<E> r, BTNode<E> p) {
elt = e; left = l; right = r; parent = p;
}
@Override public String toString() {
String ls=""+(( left==null)?"-":left.elt);
String rs=""+(( right==null)?"-":right.elt);
String ps=""+((parent==null)?"-":parent.elt);
return ""+elt+"_"+ls+"_"+rs+"_"+ps;
}
}
//======================================================================
BTNode<E> root = null;
public boolean isEmpty() {
return root == null;
}
public BTreeItr<E> root() {
return new BTreeItr<>(this);
}
@Override public String toString() {
return toStr(root);
}
public String toReadableString() {
List<StringBuilder> b=subtreeBlock(root);
StringBuilder res=new StringBuilder("\n");
for(StringBuilder s:b) res.append(s).append('\n');
return res.toString();
}
//------------------------------------------------------------
//------ Non-public methods
//------------------------------------------------------------
// format : "()" si le sous-arbre est vide
// sinon "(" sous_arbre_gauche "," élément "," sous_arbre_droit ")"
private String toStr(BTNode<E> n) {
if (n==null) return "()";
return "(" + toStr(n.left) +","+n.elt+","+ toStr(n.right) + ")";
}
/* ------------ Example: --------------------
                        9             
             2´´´´´´´´´´ ```````4     
          12´ ``8            6´´ ```7 
  3´´´´´´´ `   ´ ``10     14´ `   1´ `
5´ ``0            ´ `11               
    ´ `13                             
------------------------------------------ */
private static final char SPACE = '\u00A0'; // the rarer non-breaking space
private static final char LMARK = '´';
private static final char RMARK = '`';
private static final String FIRST_SEP = ""+LMARK+SPACE+RMARK;
private static final String OTHER_SEP = ""+SPACE+SPACE+SPACE;
private static List<StringBuilder> subtreeBlock(BTNode<?> n) {
List<StringBuilder> ls, rs, res=new ArrayList<>();
if(n==null) { // empty subtree
res.add(new StringBuilder(""));
return res;
}
String eltStr=String.valueOf(n.elt);
//if(eltStr.startsWith(""+SPACE) || eltStr.endsWith(""+SPACE))
// System.out.println("possible display problem...");
ls=subtreeBlock(n.left);
rs=subtreeBlock(n.right);
int lw=ls.get(0).length();
int rw=rs.get(0).length();
if(lw+rw==0) { // no child
res.add(new StringBuilder(eltStr));
return res;
}
replaceExtremeSpaces(ls.get(0), SPACE, LMARK); // " elt´´´´´"
replaceExtremeSpaces(rs.get(0), RMARK, SPACE); // "````elt "
String sep = FIRST_SEP;
for(int i=0; i<ls.size() || i<rs.size(); i++) {
StringBuilder l=(i<ls.size()) ? ls.get(i) : blockOf(lw, SPACE);
StringBuilder r=(i<rs.size()) ? rs.get(i) : blockOf(rw, SPACE);
res.add(l.append(sep).append(r));
sep=OTHER_SEP; // only the first line is joined with ´ `
}
StringBuilder first=blockOf(lw+1, SPACE).append(eltStr);
int pad=(lw+rw+sep.length()) - first.length();
if(pad>=0) {
first.append(blockOf(pad, SPACE));
} else { // special case where "root line" is longer because of its elt
StringBuilder suffix=blockOf(-pad, SPACE);
for(StringBuilder z:res)
z.append(suffix);
}
res.add(0, first);
//assert first.length()==res.get(1).length() :
// (first.length()+" "+res.get(1).length());
return res;
}
// " ... " --> "ccc...ddd"
private static void replaceExtremeSpaces(StringBuilder sb, char c, char d) {
int n=sb.length();
for(int i=0; i<n && sb.charAt(i)==SPACE; i++) sb.setCharAt(i, c);
for(int i=n-1; i>=0 && sb.charAt(i)==SPACE; i--) sb.setCharAt(i, d);
}
// (3,'a') --> "aaa"
private static StringBuilder blockOf(int w, char c) {
StringBuilder r=new StringBuilder("");
while(w-- > 0) r.append(c);
return r;
}
}
package s10;
import s10.BTree.BTNode;
public class BTreeItr<E> {
private BTree<E> whole;
// ------------------------------------------------------------
private BTNode<E> up = null;
private BTNode<E> down = null;
private boolean isLeftArc = false; // not relevant at the root
// ------------------------------------------------------------
/** Position on root. */
public BTreeItr(BTree<E> t) {
whole=t;down = whole.root;
}
// ------------------------------------------------------------
// ------ Accessors
// ------------------------------------------------------------
/** Terminal position: no node above. */
public boolean isRoot() {
return up==null;
}
/** Position on a node with a left child. */
public boolean hasLeft() {
return down!=null && down.left !=null;
}
/** Position on a node with a right child. */
public boolean hasRight() {
return down!=null && down.right!=null;
}
/** Terminal position: no node below. */
public boolean isBottom() {
return down==null;
}
/** Position on a node with no child. */
public boolean isLeafNode() {
return !(isBottom()||hasLeft()||hasRight());
}
/** Position on a left child. Not relevant if isRoot(). */
public boolean isLeftArc() {
return isLeftArc;
}
/** PRE: !isBottom(). Returns the element stored at that position. */
public E consult() {
assert (!isBottom());
assert (isConsistent());
return down.elt;
}
// ------------------------------------------------------------
// ------ Movements
// ------------------------------------------------------------
/** The tree containing that position */
public BTree<E> whole() {
return whole;
}
/** PRE: !isRoot(). Does not move this itr but creates a new one.*/
public BTreeItr<E> up() {
assert (!isRoot());
BTreeItr<E> r = new BTreeItr<>(whole);
r.down=up; r.up=up.parent; r.isLeftArc = (r.up!=null && r.up.left==r.down);
return r;
}
/** PRE: !isBottom(). Does not move this itr but creates a new one. */
public BTreeItr<E> left() {
assert (!isBottom());
BTreeItr<E> r = new BTreeItr<>(whole);
r.up=down; r.down=down.left; r.isLeftArc = true;
return r;
}
/** PRE: !isBottom(). Does not move this itr but creates a new one. */
public BTreeItr<E> right() {
assert (!isBottom());
BTreeItr<E> r = new BTreeItr<>(whole);
r.up=down; r.down=down.right; r.isLeftArc = false;
return r;
}
/** Goes down to the left as far as possible, from here. Always returns
* a bottom arc. Does not move this itr but creates a new one. */
public BTreeItr<E> leftMost() {
BTreeItr<E> r = new BTreeItr<>(whole);
r.up=up; r.down=down; r.isLeftArc = isLeftArc;
while (!r.isBottom()) {
r.up=r.down; r.down=r.down.left; r.isLeftArc = true;
}
return r;
}
/** Goes down to the right as far as possible, from here. Always returns
* a bottom arc. Does not move this itr but creates a new one. */
public BTreeItr<E> rightMost() {
BTreeItr<E> r = new BTreeItr<>(whole);
r.up=up; r.down=down; r.isLeftArc = isLeftArc;
while (!r.isBottom()) {
r.up=r.down; r.down=r.down.right; r.isLeftArc = false;
}
return r;
}
/** Returns a new itr on the same position. */
public BTreeItr<E> alias() {
BTreeItr<E> t = new BTreeItr<>(whole);
t.whole = whole; t.up=up; t.down=down; t.isLeftArc=isLeftArc;
return t;
}
/** Each position belongs to exactly one tree. */
public boolean isInside(BTree<E> t) {
return whole==t;
}
// ------------------------------------------------------------
// ------ Modifiers
// ------------------------------------------------------------
/** PRE: !isBottom(). Replaces the element stored at that position. */
public void update(E elt) {
assert (!isBottom()); assert (isConsistent());
down.elt = elt;
}
/** Replaces the subtree with a single node containing that element. */
public void insert(E elt) {
cut();
BTNode<E> n = new BTNode<>(elt, null, null, up);
if (isRoot())
whole.root=n;
else {
if (isLeftArc) up.left = n;
else up.right= n;
}
down = n;
}
/** Replaces the subtree with that whole tree.
* PRE: !this.isInside(t). POST: t is now empty.*/
public void paste(BTree<E> t) {
if (isInside(t)) throw new IllegalArgumentException();
cut();
if (t.isEmpty()) return;
BTNode<E> n = t.root;
n.parent=up;
if (isRoot())
whole.root=n;
else {
if (isLeftArc) up.left = n;
else up.right= n;
}
down = n;
t.root = null;
}
/** Removes the subtree and returns it as a new tree. */
public BTree<E> cut() {
assert (isConsistent());
BTree<E> t = new BTree<>();
if (isBottom()) return t;
t.root = down; t.root.parent = null;
if (isRoot())
whole.root=null;
else {
if (isLeftArc) up.left = null;
else up.right= null;
}
down = null;
return t;
}
//------------------------------------------------------------
//------ "rotation" methods
//------------------------------------------------------------
/** Moves the neighboring nodes according to a left rotation.
* PRE: hasRight() */
public void rotateLeft() {
assert (hasRight());
BTreeItr<E> x = cut().root();
BTree<E> b = x.right().left().cut();
BTreeItr<E> y = x.right().cut().root();
x.right().paste(b);
y.left().paste(x.whole());
paste(y.whole());
}
/** Moves the neighboring nodes according to a right rotation.
* PRE: hasLeft() */
public void rotateRight() {
assert (hasLeft());
BTreeItr<E> y = cut().root();
BTree<E> b = y.left().right().cut();
BTreeItr<E> x = y.left().cut().root();
y.left().paste(b);
x.right().paste(y.whole());
paste(x.whole());
}
@Override public String toString() {
return whole.toString();
}
/** A nice representation of the whole tree */
public String toReadableString() {
return whole.toReadableString();
}
//------------------------------------------------------------
//------ Non-public methods
//------------------------------------------------------------
// isConsistent() : tracks tree inconsistency (due to recent
// PRE-conditions violations for cut/paste/insert) :
// - local bidirectional chaining
// - recursively, upwards, till the root arc
// This slows a lot, but may help detect bugs
// ------------------------------------------------------------
private boolean isConsistent() {
BTNode<E> u=up, d=down;
if (u!=null && d!=((isLeftArc)?(u.left):(u.right))) return false;
while (u!=null) {
if (d!=null && d.parent!=u) return false;
if (d!=u.left && d!=u.right) return false;
d=u; u=u.parent;
}
return (d==whole.root);
}
//------------------------------------------------------------
}
package s10;
import java.util.Random;
//--------------------------------------------------
public class Treap<E extends Comparable<E>> {
//============================================================
static class TreapElt<E extends Comparable<E>> implements Comparable<TreapElt<E>> {
static Random rnd=new Random();
// -----------------------
private final E elt;
private int pty;
// -----------------------
public TreapElt(E e) {
elt=e;
pty=rnd.nextInt();
}
public int pty() {
return pty;
}
public E elt() {
return elt;
}
public int compareTo(TreapElt<E> o) {
return elt.compareTo(o.elt);
}
@Override public boolean equals(Object o) {
if(o==null) return false;
if (this.getClass() != o.getClass()) return false;
if (elt==null) return false;
return elt.equals(((TreapElt<?>)o).elt);
}
@Override public String toString() {
return ""+elt+"#"+pty;
}
@Override public int hashCode() {
return elt.hashCode();
}
}
//============================================================
private final BST<TreapElt<E>> bst;
// --------------------------
public Treap() {
bst=null;
// TODO - A COMPLETER
}
public void add(E e) {
// TODO - A COMPLETER
}
public void remove(E e) {
// TODO - A COMPLETER
}
public boolean contains(E e) {
return false; // TODO - A COMPLETER
}
public int size() {
return 0; // TODO - A COMPLETER
}
public E minElt() {
return null; // TODO - A COMPLETER
}
public E maxElt() {
return null; // TODO - A COMPLETER
}
public String toString() {
return bst.toString();
}
// --------------------------------------------------
// --- Non-public methods
// --------------------------------------------------
private void siftDownAndCut(BTreeItr<TreapElt<E>> ti) {
// TODO - A COMPLETER
}
private void percolateUp(BTreeItr<TreapElt<E>> ti) {
while((!ti.isRoot()) && isLess(ti, ti.up())) {
if (ti.isLeftArc()) {ti=ti.up(); ti.rotateRight();}
else {ti=ti.up(); ti.rotateLeft(); }
}
}
private boolean isLess(BTreeItr<TreapElt<E>> a, BTreeItr<TreapElt<E>> b) {
TreapElt<E> ca= a.consult();
TreapElt<E> cb= b.consult();
return ca.pty()<cb.pty();
}
}
package s10;
import java.util.BitSet;
import java.util.Random;
import org.junit.Test;
import static org.junit.Assert.*;
public class TreapTestJU {
// ------------------------------------------------------------
@Test
public void testTreap() {
int n=2000;
testSet(n);
}
// ------------------------------------------------------------
static void rndAddRm(Random r, Treap<Integer> s, BitSet bs, int i) {
if (r.nextBoolean()) {
s.add(i); bs.set(i);
//System.out.println("add "+i+": "+s+" // "+bs);
//if (! areSetEqual(s, bs)) {
//System.out.println("oh ! add "+i);
//}
} else {
s.remove(i); bs.clear(i);
//System.out.println("rm "+i+": "+s+" // "+bs);
//if (! areSetEqual(s, bs)) {
//System.out.println("oh ! rm "+i);
//}
}
}
// ------------------------------------------------------------
static boolean areSetEqual(Treap<Integer> s, BitSet bs) {
int l=0;
for (int i=0; i<bs.length(); i++) {
if(bs.get(i) != s.contains(Integer.valueOf(i))) {
System.out.println("SetOf : "+s);
System.out.println("BitSet: "+bs);
System.out.println("Size: "+s.size());