├── latex ├── figs │ ├── .gitignore │ ├── makeepss │ └── Makefile ├── figs-python │ ├── .gitignore │ ├── makeepss │ ├── Makefile │ └── snarf-fig.py ├── images │ ├── cc-by.pdf │ ├── tree3.pdf │ ├── cc-by-gs.pdf │ ├── Makefile │ ├── bigoh-1.gp │ └── bigoh-2.gp ├── .gitignore ├── ods-book.css ├── ods-colors.sty ├── README ├── ack-ptbr.tex ├── cpp-preface.tex ├── rebuilding.tex ├── latex2html-init └── why-ptbr.tex ├── Transparências ├── Testes │ ├── animated.bbl │ ├── animated.tex │ └── animated.blg ├── .gitignore ├── imagens │ ├── arvore.png │ ├── img18.png │ ├── img21.png │ ├── logodesc.png │ ├── ArvoreBinaria1.jpg │ ├── Nary_to_binary.png │ ├── arvorebinaria.png │ ├── arvorebinaria1.png │ ├── arvorebinaria2.png │ ├── arvoredelivros.png │ └── breadth-first.png ├── estruturasDeDados.tex └── disciplina.sty ├── c ├── .gitignore ├── include │ ├── iterator.h │ ├── sllist.h │ └── binarysearchtree.h └── Makefile ├── python ├── .gitignore └── ods │ ├── simple.py │ ├── tests │ ├── test_chainedhashtable.py │ ├── test_linearhashtable.py │ ├── test_adjacencylists.py │ ├── test_adjacencymatrix.py │ ├── test_xfasttrie.py │ ├── test_yfasttrie.py │ ├── test_btree.py │ ├── test_treap.py │ ├── test_binaryheap.py │ ├── test_binarytrie.py │ ├── test_meldableheap.py │ ├── test_redblacktree.py │ ├── test_scapegoattree.py │ ├── test_skiplistsset.py │ ├── test_binarysearchtree.py │ ├── test_dllist.py │ ├── test_sllist.py │ ├── test_arraydeque.py │ ├── test_arraystack.py │ ├── test_fastarraystack.py │ ├── test_dualrraydeque.py │ ├── test_skiplistlist.py │ ├── test_dualarraydeque.py │ ├── test_rootisharraystack.py │ ├── test_selist.py │ ├── test_arrayqueue.py │ ├── heaptest.py │ ├── sorttest.py │ ├── test_algorithms.py │ ├── graphtest.py │ ├── settest.py │ ├── ssettest.py │ └── listtest.py │ ├── point3d.py │ ├── utils.py │ ├── geomvector.py │ ├── controllist.py │ ├── arrayqueue.py │ ├── controlsset.py │ ├── adjacencymatrix.py │ ├── adjacencylists.py │ ├── fastarraystack.py │ ├── __init__.py │ ├── dllist.py │ ├── meldableheap.py │ ├── arraystack.py │ ├── chainedhashtable.py │ ├── treap.py │ ├── dualarraydeque.py │ ├── arraydeque.py │ ├── binaryheap.py │ ├── rootisharraystack.py │ ├── sllist.py │ ├── binarytree.py │ ├── skiplistsset.py │ ├── base.py │ └── yfasttrie.py ├── .gitmodules ├── java ├── ods │ ├── Integerizer.java │ ├── USet.java │ ├── DefaultComparator.java │ ├── Graph.java │ ├── DualRootishArrayDeque.java │ ├── Factory.java │ ├── ScapegoatTree2.java │ ├── SkiplistRope.java │ ├── FastArrayStack.java │ ├── USetSet.java │ ├── MultiplicativeHashMap.java │ ├── USetMap.java │ ├── Treap.java │ ├── BlockStore.java │ ├── AdjacencyMatrix.java │ ├── MultiplicativeHashSet.java │ ├── AdjacencyLists.java │ ├── SString.java │ ├── SSet.java │ ├── ArrayDeque.java │ ├── RootishArrayStack.java │ ├── SVGTreap.java │ ├── ArrayQueue.java │ ├── RangeSSet.java │ ├── SortedSSet.java │ ├── ArrayStack.java │ ├── FastSqrt.java │ ├── DualArrayDeque.java │ └── SLList.java ├── junk │ ├── Simple.java │ ├── Comp.java │ ├── Point3D.java │ └── GeomVector.java └── Makefile ├── cpp ├── utils.cpp ├── SkiplistSSet.cpp ├── BTree.cpp ├── array.cpp ├── SEList.cpp ├── Treap.cpp ├── BinaryHeap.cpp ├── FastSqrt.cpp ├── BinaryTree.cpp ├── BinaryTrie.cpp ├── BlockStore.cpp ├── MeldableHeap.cpp ├── RedBlackTree.cpp ├── XFastTrie.cpp ├── YFastTrie.cpp ├── ScapegoatTree.cpp ├── ArrayDeque.cpp ├── ArrayQueue.cpp ├── FastArrayStack.cpp ├── ChainedHashTable.cpp ├── DLList.cpp ├── Simple.h ├── AdjacencyLists.cpp ├── SLList.cpp ├── Point3D.h ├── RootishArrayStack.cpp ├── AdjacencyMatrix.cpp ├── DualArrayDeque.cpp ├── GeomVector.h ├── ArrayStack.cpp ├── AdjacencyMatrix.h ├── utils.h ├── BinarySearchTree.cpp ├── BlockStore.h ├── FastArrayStack.h ├── ArrayQueue.h ├── AdjacencyLists.h ├── SLList.h ├── FastSqrt.h ├── ArrayStack.h ├── array.h ├── YFastTrie.h ├── DLList.h ├── ChainedHashTable.h ├── ArrayDeque.h ├── DualArrayDeque.h ├── RootishArrayStack.h ├── MeldableHeap.h └── BinaryHeap.h ├── Makefile ├── README.md ├── COPYING └── README /latex/figs/.gitignore: -------------------------------------------------------------------------------- 1 | *.pdf 2 | -------------------------------------------------------------------------------- /Transparências/Testes/animated.bbl: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /c/.gitignore: -------------------------------------------------------------------------------- 1 | *.so 2 | *.a 3 | *.o 4 | main.c 5 | a.out 6 | -------------------------------------------------------------------------------- /python/.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | .pydevproject 3 | *.pyc 4 | -------------------------------------------------------------------------------- /latex/figs-python/.gitignore: -------------------------------------------------------------------------------- 1 | *.xml 2 | *.pdf 3 | *.eps 4 | doc_data.txt 5 | -------------------------------------------------------------------------------- /python/ods/simple.py: -------------------------------------------------------------------------------- 1 | def fragmento(): 2 | i=0 3 | while i { 4 | public int intValue(T x); 5 | } 6 | -------------------------------------------------------------------------------- /latex/images/cc-by.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaraujouerj/Estruturas-de-Dados-Abertos/HEAD/latex/images/cc-by.pdf -------------------------------------------------------------------------------- /latex/images/tree3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaraujouerj/Estruturas-de-Dados-Abertos/HEAD/latex/images/tree3.pdf -------------------------------------------------------------------------------- /latex/images/cc-by-gs.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaraujouerj/Estruturas-de-Dados-Abertos/HEAD/latex/images/cc-by-gs.pdf -------------------------------------------------------------------------------- /Transparências/.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.aux 3 | *.nav 4 | *.out 5 | *.snm 6 | *.synctex.gz 7 | *.toc 8 | *.vrb 9 | *.pdf 10 | -------------------------------------------------------------------------------- /cpp/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | namespace ods { 4 | 5 | int hashCode(int x) { 6 | return x; 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /Transparências/imagens/arvore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaraujouerj/Estruturas-de-Dados-Abertos/HEAD/Transparências/imagens/arvore.png -------------------------------------------------------------------------------- /Transparências/imagens/img18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaraujouerj/Estruturas-de-Dados-Abertos/HEAD/Transparências/imagens/img18.png -------------------------------------------------------------------------------- /Transparências/imagens/img21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaraujouerj/Estruturas-de-Dados-Abertos/HEAD/Transparências/imagens/img21.png -------------------------------------------------------------------------------- /Transparências/imagens/logodesc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaraujouerj/Estruturas-de-Dados-Abertos/HEAD/Transparências/imagens/logodesc.png -------------------------------------------------------------------------------- /Transparências/imagens/ArvoreBinaria1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaraujouerj/Estruturas-de-Dados-Abertos/HEAD/Transparências/imagens/ArvoreBinaria1.jpg -------------------------------------------------------------------------------- /Transparências/imagens/Nary_to_binary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaraujouerj/Estruturas-de-Dados-Abertos/HEAD/Transparências/imagens/Nary_to_binary.png -------------------------------------------------------------------------------- /Transparências/imagens/arvorebinaria.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaraujouerj/Estruturas-de-Dados-Abertos/HEAD/Transparências/imagens/arvorebinaria.png -------------------------------------------------------------------------------- /Transparências/imagens/arvorebinaria1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaraujouerj/Estruturas-de-Dados-Abertos/HEAD/Transparências/imagens/arvorebinaria1.png -------------------------------------------------------------------------------- /Transparências/imagens/arvorebinaria2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaraujouerj/Estruturas-de-Dados-Abertos/HEAD/Transparências/imagens/arvorebinaria2.png -------------------------------------------------------------------------------- /Transparências/imagens/arvoredelivros.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaraujouerj/Estruturas-de-Dados-Abertos/HEAD/Transparências/imagens/arvoredelivros.png -------------------------------------------------------------------------------- /Transparências/imagens/breadth-first.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaraujouerj/Estruturas-de-Dados-Abertos/HEAD/Transparências/imagens/breadth-first.png -------------------------------------------------------------------------------- /python/ods/tests/test_chainedhashtable.py: -------------------------------------------------------------------------------- 1 | from settest import exercise_set 2 | import ods 3 | 4 | def test_cht(): 5 | exercise_set(ods.ChainedHashTable()) 6 | -------------------------------------------------------------------------------- /python/ods/tests/test_linearhashtable.py: -------------------------------------------------------------------------------- 1 | import ods 2 | from settest import exercise_set 3 | 4 | def test_cht(): 5 | exercise_set(ods.LinearHashTable()) 6 | -------------------------------------------------------------------------------- /cpp/SkiplistSSet.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SkiplistSSet.cpp 3 | * 4 | * Created on: 2011-11-28 5 | * Author: morin 6 | */ 7 | 8 | #include "SkiplistSSet.h" 9 | 10 | -------------------------------------------------------------------------------- /python/ods/tests/test_adjacencylists.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | import ods 4 | from graphtest import exercise_graph 5 | 6 | 7 | def test_al(): 8 | exercise_graph(ods.AdjacencyLists) -------------------------------------------------------------------------------- /python/ods/tests/test_adjacencymatrix.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | import ods 4 | from graphtest import exercise_graph 5 | 6 | 7 | def test_am(): 8 | exercise_graph(ods.AdjacencyMatrix) -------------------------------------------------------------------------------- /python/ods/tests/test_xfasttrie.py: -------------------------------------------------------------------------------- 1 | from nose.tools import * 2 | import ods 3 | from ssettest import exercise_sset 4 | 5 | def test_bst(): 6 | exercise_sset(ods.XFastTrie()) 7 | -------------------------------------------------------------------------------- /python/ods/tests/test_yfasttrie.py: -------------------------------------------------------------------------------- 1 | from nose.tools import * 2 | import ods 3 | from ssettest import exercise_sset 4 | 5 | def test_bst(): 6 | exercise_sset(ods.YFastTrie()) 7 | -------------------------------------------------------------------------------- /python/ods/tests/test_btree.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | from nose.tools import * 4 | import ods 5 | from ssettest import exercise_sset 6 | 7 | def test_bst(): 8 | exercise_sset(ods.BTree(11)) 9 | -------------------------------------------------------------------------------- /python/ods/tests/test_treap.py: -------------------------------------------------------------------------------- 1 | 2 | from nose.tools import * 3 | 4 | import ods 5 | from ssettest import exercise_sset 6 | 7 | def test_treap(): 8 | exercise_sset(ods.Treap()) 9 | -------------------------------------------------------------------------------- /python/ods/tests/test_binaryheap.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | import ods 4 | from heaptest import exercise_heap 5 | 6 | def test_bh(): 7 | exercise_heap(ods.BinaryHeap()) 8 | 9 | 10 | -------------------------------------------------------------------------------- /python/ods/tests/test_binarytrie.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | from nose.tools import * 4 | import ods 5 | from ssettest import exercise_sset 6 | 7 | def test_bst(): 8 | exercise_sset(ods.BinaryTrie()) 9 | -------------------------------------------------------------------------------- /python/ods/tests/test_meldableheap.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | import ods 4 | from heaptest import exercise_heap 5 | 6 | def test_mh(): 7 | exercise_heap(ods.MeldableHeap()) 8 | 9 | 10 | -------------------------------------------------------------------------------- /python/ods/tests/test_redblacktree.py: -------------------------------------------------------------------------------- 1 | from nose.tools import * 2 | 3 | import ods 4 | from ssettest import exercise_sset 5 | 6 | def test_rbt(): 7 | exercise_sset(ods.RedBlackTree()) 8 | 9 | -------------------------------------------------------------------------------- /python/ods/tests/test_scapegoattree.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | from nose.tools import * 4 | import ods 5 | from ssettest import exercise_sset 6 | 7 | def test_bst(): 8 | exercise_sset(ods.ScapegoatTree()) 9 | -------------------------------------------------------------------------------- /python/ods/tests/test_skiplistsset.py: -------------------------------------------------------------------------------- 1 | 2 | from nose.tools import * 3 | 4 | import ods 5 | from ssettest import exercise_sset 6 | 7 | def test_treap(): 8 | exercise_sset(ods.SkiplistSSet()) 9 | -------------------------------------------------------------------------------- /cpp/BTree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * BTree.cpp 3 | * 4 | * Created on: 2013-07-03 5 | * Author: morin 6 | */ 7 | 8 | #include "BTree.h" 9 | 10 | namespace ods { 11 | 12 | } /* namespace ods */ 13 | -------------------------------------------------------------------------------- /cpp/array.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * array.cpp 3 | * 4 | * Created on: 2011-11-24 5 | * Author: morin 6 | */ 7 | 8 | #include "array.h" 9 | 10 | namespace ods { 11 | 12 | } /* namespace ods */ 13 | -------------------------------------------------------------------------------- /python/ods/tests/test_binarysearchtree.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | from nose.tools import * 4 | import ods 5 | from ssettest import exercise_sset 6 | 7 | def test_bst(): 8 | exercise_sset(ods.BinarySearchTree()) 9 | -------------------------------------------------------------------------------- /cpp/SEList.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SEList.cpp 3 | * 4 | * Created on: 2011-11-25 5 | * Author: morin 6 | */ 7 | 8 | #include "SEList.h" 9 | 10 | namespace ods { 11 | 12 | } /* namespace ods */ 13 | -------------------------------------------------------------------------------- /cpp/Treap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Treap.cpp 3 | * 4 | * Created on: 2011-11-28 5 | * Author: morin 6 | */ 7 | 8 | #include "Treap.h" 9 | 10 | namespace ods { 11 | 12 | 13 | } /* namespace ods */ 14 | -------------------------------------------------------------------------------- /java/junk/Simple.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | public class Simple { 4 | static int[] a; 5 | static int n; 6 | public static void snippet() { 7 | for (int i = 0; i < n; i++) 8 | a[i] = i; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /cpp/BinaryHeap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * BinaryHeap.cpp 3 | * 4 | * Created on: 2011-11-30 5 | * Author: morin 6 | */ 7 | 8 | #include "BinaryHeap.h" 9 | 10 | namespace ods { 11 | 12 | } /* namespace ods */ 13 | -------------------------------------------------------------------------------- /cpp/FastSqrt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * FastSqrt.cpp 3 | * 4 | * Created on: 2011-11-25 5 | * Author: morin 6 | */ 7 | 8 | #include "FastSqrt.h" 9 | 10 | namespace ods { 11 | 12 | 13 | } /* namespace ods */ 14 | -------------------------------------------------------------------------------- /python/ods/tests/test_dllist.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | from nose.tools import * 4 | 5 | import ods 6 | from listtest import exercise_list 7 | 8 | def test_as(): 9 | exercise_list(ods.DLList()) 10 | 11 | -------------------------------------------------------------------------------- /python/ods/tests/test_sllist.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | from nose.tools import * 4 | 5 | import ods 6 | from listtest import exercise_list 7 | 8 | def test_as(): 9 | exercise_list(ods.SLList()) 10 | 11 | -------------------------------------------------------------------------------- /cpp/BinaryTree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * BinaryTree.cpp 3 | * 4 | * Created on: 2011-11-28 5 | * Author: morin 6 | */ 7 | 8 | #include "BinaryTree.h" 9 | 10 | namespace ods { 11 | 12 | 13 | } /* namespace ods */ 14 | -------------------------------------------------------------------------------- /cpp/BinaryTrie.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * BinaryTrie.cpp 3 | * 4 | * Created on: 2012-01-26 5 | * Author: morin 6 | */ 7 | 8 | #include "BinaryTrie.h" 9 | 10 | namespace ods { 11 | 12 | 13 | } /* namespace ods */ 14 | -------------------------------------------------------------------------------- /cpp/BlockStore.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * BlockStore.cpp 3 | * 4 | * Created on: 2013-07-03 5 | * Author: morin 6 | */ 7 | 8 | #include "BlockStore.h" 9 | 10 | namespace ods { 11 | 12 | 13 | } /* namespace ods */ 14 | -------------------------------------------------------------------------------- /cpp/MeldableHeap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MeldableHeap.cpp 3 | * 4 | * Created on: 2011-11-30 5 | * Author: morin 6 | */ 7 | 8 | #include "MeldableHeap.h" 9 | 10 | namespace ods { 11 | 12 | } /* namespace ods */ 13 | -------------------------------------------------------------------------------- /cpp/RedBlackTree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * RedBlackTree.cpp 3 | * 4 | * Created on: 2011-11-30 5 | * Author: morin 6 | */ 7 | 8 | #include "RedBlackTree.h" 9 | 10 | namespace ods { 11 | 12 | } /* namespace ods */ 13 | -------------------------------------------------------------------------------- /cpp/XFastTrie.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * XFastTrie.cpp 3 | * 4 | * Created on: 2012-01-26 5 | * Author: morin 6 | */ 7 | 8 | #include "XFastTrie.h" 9 | 10 | namespace ods { 11 | 12 | 13 | } /* namespace ods */ 14 | -------------------------------------------------------------------------------- /cpp/YFastTrie.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * YFastTrie.cpp 3 | * 4 | * Created on: 2012-01-27 5 | * Author: morin 6 | */ 7 | 8 | #include "YFastTrie.h" 9 | 10 | namespace ods { 11 | 12 | 13 | } /* namespace ods */ 14 | -------------------------------------------------------------------------------- /python/ods/tests/test_arraydeque.py: -------------------------------------------------------------------------------- 1 | import random 2 | from nose.tools import * 3 | 4 | import ods 5 | from listtest import exercise_list 6 | 7 | def test_as(): 8 | exercise_list(ods.ArrayDeque()) 9 | 10 | -------------------------------------------------------------------------------- /python/ods/tests/test_arraystack.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | from nose.tools import * 4 | import ods 5 | from listtest import exercise_list 6 | 7 | def test_as(): 8 | exercise_list(ods.ArrayStack()) 9 | 10 | -------------------------------------------------------------------------------- /python/ods/tests/test_fastarraystack.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | from nose.tools import * 4 | import ods 5 | from listtest import exercise_list 6 | 7 | def test_as(): 8 | exercise_list(ods.FastArrayStack()) 9 | 10 | -------------------------------------------------------------------------------- /cpp/ScapegoatTree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ScapegoatTree.cpp 3 | * 4 | * Created on: 2011-11-30 5 | * Author: morin 6 | */ 7 | 8 | #include "ScapegoatTree.h" 9 | 10 | namespace ods { 11 | 12 | 13 | } /* namespace ods */ 14 | -------------------------------------------------------------------------------- /python/ods/tests/test_dualrraydeque.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | from nose.tools import * 4 | 5 | import ods 6 | from listtest import exercise_list 7 | 8 | def test_as(): 9 | exercise_list(ods.DualArrayDeque()) 10 | 11 | -------------------------------------------------------------------------------- /python/ods/tests/test_skiplistlist.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | from nose.tools import * 4 | 5 | import ods 6 | from listtest import exercise_list 7 | 8 | def test_as(): 9 | exercise_list(ods.SkiplistList()) 10 | 11 | -------------------------------------------------------------------------------- /java/ods/USet.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | public interface USet extends Iterable { 4 | public int size(); 5 | public boolean add(T x); 6 | public T remove(T x); 7 | public T find(T x); 8 | public void clear(); 9 | } 10 | -------------------------------------------------------------------------------- /python/ods/tests/test_dualarraydeque.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | from nose.tools import * 4 | 5 | import ods 6 | from listtest import exercise_list 7 | 8 | def test_dad(): 9 | exercise_list(ods.DualArrayDeque()) 10 | 11 | -------------------------------------------------------------------------------- /python/ods/tests/test_rootisharraystack.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | from nose.tools import * 4 | 5 | import ods 6 | from listtest import exercise_list 7 | 8 | def test_as(): 9 | exercise_list(ods.RootishArrayStack()) 10 | 11 | -------------------------------------------------------------------------------- /cpp/ArrayDeque.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ArrayDeque.cpp 3 | * 4 | * Created on: 2011-11-23 5 | * Author: morin 6 | */ 7 | #include "utils.h" 8 | #include "ArrayDeque.h" 9 | 10 | namespace ods { 11 | 12 | 13 | 14 | } /* namespace ods */ 15 | -------------------------------------------------------------------------------- /cpp/ArrayQueue.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ArrayQueue.cpp 3 | * 4 | * Created on: 2011-11-23 5 | * Author: morin 6 | */ 7 | 8 | #include "utils.h" 9 | #include "ArrayQueue.h" 10 | 11 | namespace ods { 12 | 13 | 14 | } /* namespace ods */ 15 | -------------------------------------------------------------------------------- /latex/figs/makeepss: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for f in *.pdf ; do 4 | echo "$f => ${f%.pdf}.eps" 5 | pdftops -eps "$f" 6 | done 7 | for f in *-1.eps ; do 8 | r="${f%-1.eps}".eps 9 | echo cp "$f" "$r" 10 | cp "$f" "$r" 11 | done 12 | 13 | -------------------------------------------------------------------------------- /latex/figs-python/makeepss: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for f in *.pdf ; do 4 | echo "$f => ${f%.pdf}.eps" 5 | pdftops -eps "$f" 6 | done 7 | for f in *-1.eps ; do 8 | r="${f%-1.eps}".eps 9 | echo cp "$f" "$r" 10 | cp "$f" "$r" 11 | done 12 | 13 | -------------------------------------------------------------------------------- /cpp/FastArrayStack.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * FastArrayStack.cpp 3 | * 4 | * Created on: 2011-11-23 5 | * Author: morin 6 | */ 7 | #include 8 | #include "FastArrayStack.h" 9 | #include "utils.h" 10 | 11 | namespace ods { 12 | 13 | 14 | 15 | } /* namespace ods */ 16 | -------------------------------------------------------------------------------- /cpp/ChainedHashTable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ChainedHashTable.cpp 3 | * 4 | * Created on: 2011-11-30 5 | * Author: morin 6 | */ 7 | 8 | #include "ChainedHashTable.h" 9 | 10 | namespace ods { 11 | 12 | 13 | template class ChainedHashTable; 14 | 15 | } /* namespace ods */ 16 | -------------------------------------------------------------------------------- /cpp/DLList.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * DLList.cpp 3 | * 4 | * Created on: 2011-11-24 5 | * Author: morin 6 | */ 7 | 8 | #include "DLList.h" 9 | 10 | namespace ods { 11 | 12 | 13 | template DLList::DLList(); 14 | template DLList::~DLList(); 15 | 16 | } /* namespace ods */ 17 | -------------------------------------------------------------------------------- /python/ods/tests/test_selist.py: -------------------------------------------------------------------------------- 1 | import random 2 | from nose.tools import * 3 | 4 | import ods 5 | from listtest import exercise_list 6 | 7 | def test_sel(): 8 | exercise_list(ods.SEList(5)) 9 | exercise_list(ods.SEList(10)) 10 | exercise_list(ods.SEList(42)) 11 | 12 | -------------------------------------------------------------------------------- /python/ods/tests/test_arrayqueue.py: -------------------------------------------------------------------------------- 1 | import ods 2 | 3 | def test_aq(): 4 | m = 10000 5 | n = 500 6 | q = ods.ArrayQueue() 7 | for i in range(m): 8 | q.add(i) 9 | if q.size() > n: 10 | x = q.remove() 11 | assert x == i - n 12 | 13 | -------------------------------------------------------------------------------- /java/ods/DefaultComparator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package ods; 5 | 6 | import java.util.Comparator; 7 | 8 | class DefaultComparator implements Comparator { 9 | @SuppressWarnings("unchecked") 10 | public int compare(T a, T b) { 11 | return ((Comparable)a).compareTo(b); 12 | } 13 | } -------------------------------------------------------------------------------- /latex/.gitignore: -------------------------------------------------------------------------------- 1 | *-java.tex 2 | *-python.tex 3 | *-cpp.tex 4 | *-html.tex 5 | ods-java* 6 | ods-cpp* 7 | ods-python* 8 | images/bigoh-1.tex 9 | images/bigoh-2.tex 10 | *.aux 11 | *.log 12 | *.synctex.gz 13 | /.gitignore 14 | *.bbl 15 | *.blg 16 | *.fdb_latexmk 17 | *.fls 18 | *.idx 19 | *.ilg 20 | *.ind 21 | *.out 22 | *.pdf 23 | -------------------------------------------------------------------------------- /java/Makefile: -------------------------------------------------------------------------------- 1 | 2 | sources=$(wildcard ods/*.java) 3 | 4 | classes=$(sources:.java=.class) 5 | 6 | all: 7 | javac ods/*.java 8 | jar cvf ods.jar ods/*.class 9 | 10 | ods.jar: $(classes) 11 | jar cvf ods.jar ods/*.class 12 | 13 | %.class : %.java 14 | javac -Xlint $< 15 | 16 | clean : 17 | rm -f ods.jar ods/*.class 18 | 19 | -------------------------------------------------------------------------------- /cpp/Simple.h: -------------------------------------------------------------------------------- 1 | /** Fake file used for providing a code snippet */ 2 | 3 | namespace ods { 4 | 5 | template 6 | class Simple { 7 | int *a; 8 | int n; 9 | void snippet(); 10 | } 11 | 12 | template 13 | void Simple::snippet() { 14 | for (int i = 0; i < n; i++) 15 | a[i] = i; 16 | } 17 | 18 | } /* namespace ods */ 19 | -------------------------------------------------------------------------------- /latex/figs/Makefile: -------------------------------------------------------------------------------- 1 | sources=$(wildcard *.ipe) 2 | 3 | pdfs=$(sources:.ipe=.pdf) 4 | burstpdfs=$(sources:.ipe=-1.pdf) 5 | 6 | all: $(pdfs) $(burstpdfs) 7 | 8 | epss: $(pdfs) $(burstpdfs) 9 | ./makeepss 10 | 11 | %-1.pdf : %.pdf 12 | pdftk $< burst output $(<:.pdf=-%d.pdf) 13 | 14 | %.pdf : %.ipe 15 | ipetoipe -pdf $< 16 | 17 | clean : 18 | rm -f ./*.pdf ./*.eps 19 | 20 | -------------------------------------------------------------------------------- /python/ods/point3d.py: -------------------------------------------------------------------------------- 1 | """This code doesn't even compile---it's just used as an example""" 2 | """ 3 | class Point3D(object): 4 | def hash_code(self): 5 | z = [0x2058cc50, 0xcb19137e, 0x2cb6b6fd] 6 | zz = 0xbea0107e5067d19d 7 | h = [x0.hash_code(), x1.hash_code(), x2.hash_code()] 8 | return \ensuremath{(((z[0]*h[0] + z[1]*h[1] + z[2]*h[2])*zz)%(1<<2*w)) >> w} 9 | """ -------------------------------------------------------------------------------- /cpp/AdjacencyLists.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * AdjacencyLists.cpp 3 | * 4 | * Created on: 2012-01-13 5 | * Author: morin 6 | */ 7 | 8 | #include "AdjacencyLists.h" 9 | 10 | namespace ods { 11 | 12 | AdjacencyLists::AdjacencyLists(int n0) { 13 | n = n0; 14 | adj = new List[n]; 15 | } 16 | 17 | AdjacencyLists::~AdjacencyLists() { 18 | delete[] adj; 19 | } 20 | 21 | } /* namespace ods */ 22 | -------------------------------------------------------------------------------- /latex/images/Makefile: -------------------------------------------------------------------------------- 1 | svgs=$(wildcard *.svg) 2 | pdfs=$(svgs:.svg=.pdf) 3 | epss=$(svgs:.svg=.eps) 4 | 5 | 6 | all: $(pdfs) $(epss) bigoh-1.tex bigoh-2.tex 7 | 8 | bigoh-1.tex : bigoh-1.gp 9 | gnuplot $< 10 | 11 | bigoh-2.tex : bigoh-2.gp 12 | gnuplot $< 13 | 14 | %.pdf : %.svg 15 | inkscape --export-pdf=$@ $< 16 | 17 | %.eps : %.svg 18 | inkscape --export-eps=$@ $< 19 | 20 | clean: 21 | rm -f $(pdfs) 22 | 23 | -------------------------------------------------------------------------------- /python/ods/tests/heaptest.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def exercise_heap(h=None): 5 | if h is None: return 6 | a0 = [] 7 | h 8 | n = 1000 9 | for _ in range(n): 10 | x = random.randrange(5*n) 11 | a0.append(x) 12 | h.add(x) 13 | assert(len(h) == len(a0)) 14 | a1 = [h.remove() for _ in range(n)] 15 | assert(sorted(a0) == a1) 16 | assert(len(h) == 0) 17 | 18 | 19 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | (cd java ; make) 4 | (cd latex ; make) 5 | 6 | clean: 7 | (cd java ; make clean) 8 | (cd latex ; make clean) 9 | 10 | tarballs: 11 | tar czvf ods-java.tgz java/ods/ 12 | tar czvf ods-cpp.tgz cpp/ 13 | tar czvf ods-python.tgz python/ods 14 | 15 | install: all tarballs 16 | (cd latex ; make install) 17 | scp ods-java.tgz ods-cpp.tgz ods-python.tgz morin@cg.scs.carleton.ca:public_html/ods/ 18 | 19 | 20 | -------------------------------------------------------------------------------- /python/ods/tests/sorttest.py: -------------------------------------------------------------------------------- 1 | 2 | import random 3 | 4 | def exercise_sort(sort, gen=random.random): 5 | """Run some tests on the sorting function, sort""" 6 | for n in [0, 1, 100, 1000, 10000]: 7 | a = [gen() for _ in range(n)] 8 | b = a[:] 9 | # in-place sorts return None, other sorts return sorted array 10 | c = sort(b) 11 | if c is None: c = b 12 | assert(sorted(a) == list(c)) 13 | 14 | -------------------------------------------------------------------------------- /cpp/SLList.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SLList.cpp 3 | * 4 | * Created on: 2011-11-25 5 | * Author: morin 6 | */ 7 | 8 | #include "SLList.h" 9 | 10 | namespace ods { 11 | 12 | template SLList::SLList(); 13 | template SLList::~SLList(); 14 | template int SLList::push(int x); 15 | template bool SLList::add(int x); 16 | template int SLList::remove(); 17 | template int SLList::pop(); 18 | template int SLList::size(); 19 | 20 | } /* namespace ods */ 21 | -------------------------------------------------------------------------------- /python/ods/tests/test_algorithms.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | from sorttest import exercise_sort 4 | from ods import merge_sort, quick_sort, counting_sort, radix_sort, heap_sort 5 | 6 | def test_sorts(): 7 | exercise_sort(merge_sort) 8 | exercise_sort(quick_sort) 9 | exercise_sort(heap_sort) 10 | k = 100 11 | exercise_sort(lambda a: counting_sort(a, k), lambda : random.randrange(k)) 12 | r = 1000000 13 | exercise_sort(lambda a: radix_sort(a), lambda : random.randrange(r)) 14 | -------------------------------------------------------------------------------- /latex/images/bigoh-1.gp: -------------------------------------------------------------------------------- 1 | set term tikz color size 5in,3in 2 | set output 'bigoh-1.tex' 3 | set xlabel '{\color{var}\texttt{n}}' 4 | set ylabel '$f({\color{var}\mathtt{n}})$' 5 | set key right bottom 6 | set xrange [1:100] 7 | set style line 1 linecolor rgb '#0060ad' linetype 1 linewidth 2 8 | set style line 2 linecolor rgb '#dd181f' linetype 2 linewidth 2 9 | plot 15*x title '$15{\mathtt{n}}$' with lines linestyle 1, \ 10 | 2*x*(log(x)/log(2)) title '$2{\mathtt{n}}\log{\mathtt{n}}$' with lines linestyle 2 11 | 12 | -------------------------------------------------------------------------------- /latex/images/bigoh-2.gp: -------------------------------------------------------------------------------- 1 | set term tikz color size 5in,3in 2 | set output 'bigoh-2.tex' 3 | set xlabel '{\color{var}\texttt{n}}' 4 | set ylabel '$f({\color{var}\mathtt{n}})$' 5 | set key right bottom 6 | set style line 1 linecolor rgb '#0060ad' linetype 1 linewidth 2 7 | set style line 2 linecolor rgb '#dd181f' linetype 2 linewidth 2 8 | set xrange [1:10000] 9 | plot 15*x title '$15{\mathtt{n}}$' with lines linestyle 1, \ 10 | 2*x*(log(x)/log(2)) title '$2{\mathtt{n}}\log{\mathtt{n}}$' with lines linestyle 2 11 | 12 | -------------------------------------------------------------------------------- /latex/figs-python/Makefile: -------------------------------------------------------------------------------- 1 | sources=$(wildcard ../figs/*.ipe) 2 | kek=$(notdir $(sources)) 3 | kak=$(kek:.ipe=.xml) 4 | pdfs=$(kak:.xml=.pdf) 5 | burstpdfs=$(kak:.xml=-1.pdf) 6 | 7 | all : $(kak) $(pdfs) $(burstpdfs) 8 | 9 | epss : $(pdfs) $(burstpdfs) 10 | ./makeepss 11 | 12 | %.xml : ../figs/%.ipe Makefile snarf-fig.py 13 | ./snarf-fig.py $< > $@ 14 | 15 | %-1.pdf : %.pdf 16 | pdftk $< burst output $(<:.pdf=-%d.pdf) 17 | 18 | %.pdf : %.xml 19 | ipetoipe -pdf $< 20 | 21 | clean : 22 | rm -f *.xml ./*.pdf ./*.eps 23 | 24 | -------------------------------------------------------------------------------- /cpp/Point3D.h: -------------------------------------------------------------------------------- 1 | 2 | #include "utils.h" 3 | 4 | namespace ods { 5 | 6 | class Point3D { 7 | protected: 8 | int x0, x1, x2; 9 | 10 | public: 11 | unsigned hashCode() { 12 | // random number from random.org 13 | long long z[] = {0x2058cc50L, 0xcb19137eL, 0x2cb6b6fdL}; 14 | long zz = 0xbea0107e5067d19dL; 15 | 16 | long h0 = ods::hashCode(x0); 17 | long h1 = ods::hashCode(x1); 18 | long h2 = ods::hashCode(x2); 19 | return (int)(((z[0]*h0 + z[1]*h1 + z[2]*h2)*zz) >> 32); 20 | } 21 | }; 22 | 23 | } // namespace ods 24 | 25 | -------------------------------------------------------------------------------- /cpp/RootishArrayStack.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * RootishArrayStack.cpp 3 | * 4 | * Created on: 2011-11-23 5 | * Author: morin 6 | */ 7 | 8 | #include "RootishArrayStack.h" 9 | 10 | namespace ods { 11 | 12 | template RootishArrayStack::RootishArrayStack(); 13 | template RootishArrayStack::~RootishArrayStack(); 14 | template void RootishArrayStack::add(int,int); 15 | template int RootishArrayStack::remove(int); 16 | template void RootishArrayStack::grow(); 17 | template void RootishArrayStack::shrink(); 18 | 19 | } /* namespace ods */ 20 | -------------------------------------------------------------------------------- /java/ods/Graph.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.List; 4 | 5 | 6 | /** 7 | * This interface represents a directed graph whose vertices are 8 | * indexed by 0,...,nVertices()-1 9 | * @author morin 10 | * 11 | */ 12 | public interface Graph { 13 | public int nVertices(); 14 | public void addEdge(int i, int j); 15 | public void removeEdge(int i, int j); 16 | public boolean hasEdge(int i, int j); 17 | public List outEdges(int i); 18 | public List inEdges(int i); 19 | public int outDegree(int i); 20 | public int inDegree(int i); 21 | } 22 | -------------------------------------------------------------------------------- /latex/ods-book.css: -------------------------------------------------------------------------------- 1 | body { 2 | max-width: 45em; 3 | margin: 0 auto; 4 | margin-top: 2em; 5 | text-align: justify; 6 | line-height: 1.5em; 7 | } 8 | 9 | h1 { 10 | font-size: 160%; 11 | font-weight: normal; 12 | font-family: "Charcoal", "Kalimati", "Verdana", sans-serif; 13 | } 14 | 15 | h2 { 16 | font-size: 100%; 17 | font-weight: normal; 18 | font-family: "Charcoal", "Kalimati", "Verdana", sans-serif; 19 | } 20 | 21 | pre { 22 | padding: 1em; 23 | border: 1px solid black; 24 | line-height: 1.2em; 25 | } 26 | 27 | a { 28 | text-decoration: none; 29 | } 30 | -------------------------------------------------------------------------------- /java/junk/Comp.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | public class Comp { 4 | static long binom(long a, long b) { 5 | long z = 1; 6 | while (a > b) 7 | z *= a--; 8 | while (b > 0) 9 | z /= b--; 10 | return z; 11 | } 12 | 13 | 14 | 15 | static long s(long h) { 16 | return (1l << (h+1l))-1l; 17 | } 18 | 19 | static long f(long h) { 20 | if (h == 0) return 1; 21 | long z = f(h-1); 22 | return z*z*binom(2 * s(h-1), s(h-1)); 23 | } 24 | 25 | public static void main(String[] args) { 26 | System.out.println(f(3)); 27 | System.out.println(binom(6,3)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /latex/figs-python/snarf-fig.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import sys 3 | import re 4 | 5 | 6 | if __name__ == "__main__": 7 | lines = open(sys.argv[1]).readlines() 8 | for line in lines: 9 | line = re.sub(r'{\\color{var}', r'\mathit{', line) 10 | line = re.sub(r'\\mathtt', r'\mathrm', line) 11 | line = re.sub(r'\\texttt', r'\\textrm', line) 12 | line = re.sub(r'(\\mathrm{[a-z_]+)([A-Z]+)', 13 | lambda m: m.group(1) + '\_' + m.group(2).lower(), line) 14 | line = re.sub(r'(\\mathit{\w+)(\d})', r'\1_\2', line) 15 | print line, 16 | -------------------------------------------------------------------------------- /cpp/AdjacencyMatrix.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * AdjacencyMatrix.cpp 3 | * 4 | * Created on: 2012-01-13 5 | * Author: morin 6 | */ 7 | 8 | #include "AdjacencyMatrix.h" 9 | 10 | namespace ods { 11 | 12 | AdjacencyMatrix::AdjacencyMatrix(int n0) { 13 | n = n0; 14 | a = new bool*[n]; 15 | for (int i = 0; i < n; i++) 16 | a[i] = new bool[n]; 17 | for (int i = 0; i < n; i++) 18 | for (int j = 0; j < n; j++) 19 | a[i][j] = false; 20 | } 21 | 22 | AdjacencyMatrix::~AdjacencyMatrix() { 23 | for (int i = 0; i < n; i++) 24 | delete[] a[i]; 25 | delete[] a; 26 | } 27 | 28 | } /* namespace ods */ 29 | -------------------------------------------------------------------------------- /java/ods/DualRootishArrayDeque.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * This is d DualArrayDeque, but with the internal Lists are implemented as 7 | * RootishArrayStacks. This class provides an implementation of a Deque 8 | * with a space overhead of only O(sqrt(n)). 9 | * @author morin 10 | * 11 | * @param 12 | */ 13 | public class DualRootishArrayDeque extends DualArrayDeque { 14 | public DualRootishArrayDeque(Class t) { 15 | super(t); 16 | } 17 | 18 | protected List newStack() { 19 | return new RootishArrayStack(f.type()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /python/ods/utils.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | 3 | w = 32 4 | 5 | def new_array(n, dtype=numpy.object): 6 | return numpy.empty(n, dtype) 7 | 8 | def _new_array(n): 9 | return [None]*n 10 | 11 | def new_zero_array(n): 12 | return numpy.zeros(n) 13 | 14 | def new_boolean_matrix(n, m): 15 | return numpy.zeros([n, m], numpy.bool_) 16 | 17 | def new_boolean_array(n): 18 | return numpy.zeros(n, numpy.bool_) 19 | 20 | def new_int_array(n, init=0): 21 | a = numpy.empty(n, numpy.int32) 22 | a.fill(init) 23 | return a 24 | 25 | def binfmt(n): 26 | return "{0:012b}".format(n) 27 | -------------------------------------------------------------------------------- /cpp/DualArrayDeque.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * DualArrayDeque.cpp 3 | * 4 | * Created on: 2011-11-23 5 | * Author: morin 6 | */ 7 | 8 | #include "DualArrayDeque.h" 9 | #include "utils.h" 10 | 11 | namespace ods { 12 | 13 | 14 | template DualArrayDeque::DualArrayDeque(); 15 | template DualArrayDeque::~DualArrayDeque(); 16 | template int DualArrayDeque::get(int); 17 | template int DualArrayDeque::set(int,int); 18 | template void DualArrayDeque::add(int,int); 19 | template int DualArrayDeque::remove(int); 20 | template int DualArrayDeque::size(); 21 | 22 | 23 | 24 | } /* namespace ods */ 25 | -------------------------------------------------------------------------------- /python/ods/geomvector.py: -------------------------------------------------------------------------------- 1 | """Demonstration code used to illustrate hashing a variable length object""" 2 | class GeomVector(object): 3 | def hash_code(self): 4 | p = (1<<32)-5 # this is a prime number 5 | z = 0x64b6055a # 32 bits from random.org 6 | z2 = 0x5067d19d # random odd 32 bit number 7 | s = 0 8 | zi = 1 9 | for i in range(len(x)): 10 | # reduce to 31 bits 11 | xi = ((x[i].hash_code() * z2)%(1<<32)) >> 1 12 | s = (s + zi * xi) % p 13 | zi = (zi * z) % p 14 | s = (s + zi * (p-1)) % p 15 | return s%(1<<32) 16 | -------------------------------------------------------------------------------- /python/ods/controllist.py: -------------------------------------------------------------------------------- 1 | """A class that wraps a python list in the ods List interface""" 2 | from .base import BaseList 3 | 4 | class ControlList(BaseList): 5 | def __init__(self, iterable=[]): 6 | self.a = [] 7 | self.add_all(iterable) 8 | 9 | def get(self, i): 10 | return self.a[i] 11 | 12 | def set(self, i, x): #@ReservedAssignment 13 | y = self.a[i] 14 | self.a[i] = x 15 | return y 16 | 17 | def add(self, i, x): 18 | self.a.insert(i, x) 19 | 20 | def remove(self, i): 21 | self.a.pop(i) 22 | 23 | def size(self): 24 | return len(self.a) 25 | -------------------------------------------------------------------------------- /cpp/GeomVector.h: -------------------------------------------------------------------------------- 1 | 2 | #include "utils.h" 3 | #include "array.h" 4 | 5 | namespace ods { 6 | 7 | class GeomVector { 8 | protected: 9 | array x; 10 | 11 | public: 12 | unsigned hashCode() { 13 | long p = (1L<<32)-5; // prime: 2^32 - 5 14 | long z = 0x64b6055aL; // 32 bits from random.org 15 | int z2 = 0x5067d19d; // random odd 32 bit number 16 | long s = 0; 17 | long zi = 1; 18 | for (int i = 0; i < x.length; i++) { 19 | // reduce to 31 bits 20 | long long xi = (ods::hashCode(x[i]) * z2) >> 1; 21 | s = (s + zi * xi) % p; 22 | zi = (zi * z) % p; 23 | } 24 | s = (s + zi * (p-1)) % p; 25 | return (int)s; 26 | } 27 | }; 28 | 29 | } // namespace ods 30 | -------------------------------------------------------------------------------- /Transparências/Testes/animated.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{animate} 3 | \usepackage{tikz} 4 | \usetikzlibrary{lindenmayersystems} 5 | \pgfdeclarelindenmayersystem{A}{% 6 | \symbol{F}{\pgflsystemstep=0.6\pgflsystemstep\pgflsystemdrawforward} 7 | \rule{A->F[+A][-A]} 8 | } 9 | 10 | \begin{document} 11 | \begin{animateinline}[controls,autoplay,loop]{2} 12 | \multiframe{8}{n=1+1}{ 13 | \begin{tikzpicture}[scale=10,rotate=90] 14 | \draw (-.1,-.2) rectangle (.4,0.2); 15 | \draw [blue,opacity=0.5,line width=0.1cm,line cap=round] 16 | l-system [l-system={A,axiom=A,order=\n,angle=45,step=0.25cm}]; 17 | \end{tikzpicture} 18 | } 19 | \end{animateinline} 20 | \end{document} 21 | s -------------------------------------------------------------------------------- /cpp/ArrayStack.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ArrayStack.cpp 3 | * 4 | * Created on: 2011-11-23 5 | * Author: morin 6 | */ 7 | 8 | #include "ArrayStack.h" 9 | #include "utils.h" 10 | 11 | 12 | namespace ods { 13 | 14 | 15 | template ArrayStack::ArrayStack(); 16 | template ArrayStack::~ArrayStack(); 17 | template void ArrayStack::add(int,int); 18 | template int ArrayStack::remove(int); 19 | 20 | template ArrayStack::ArrayStack(); 21 | template ArrayStack::~ArrayStack(); 22 | template void ArrayStack::add(int,int*); 23 | template int* ArrayStack::remove(int); 24 | 25 | 26 | //void pfft() { 27 | // ArrayStack asi; 28 | // asi.size(); 29 | //} 30 | 31 | } /* namespace ods */ 32 | 33 | 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Estruturas-de-Dados-Abertas 2 | Projeto de tradução do livro Open Data Structures 3 | 4 | Versões em português: 5 | 6 | Java: http://www.araujo.eng.uerj.br/opendata/ods-ptbr-java.pdf 7 | 8 | C++: http://www.araujo.eng.uerj.br/opendata/ods-ptbr-cpp.pdf 9 | 10 | Pseudo-código: http://www.araujo.eng.uerj.br/opendata/ods-ptbr-python.pdf 11 | 12 | Este é um trabalho colaborativo. 13 | Gostaria de agradecer aos meus alunos do curso de Estruturas de Informação, da Faculdade de Engenharia, curso de Engenharia de Sistemas e Computação, Universidade do Estado do Rio de Janeiro que gentilmente me auxiliaram na tradução deste livro. 14 | Foram eles: Diana Almeida Barros, Leonardo Lobão, Ester Gomes Pais, Fábio Cavallari, Lucas Ferreira Stefe, Matheus Caldeira Matias e Pedro Yuri dos Reis de Moraes Lopes. 15 | -------------------------------------------------------------------------------- /latex/ods-colors.sty: -------------------------------------------------------------------------------- 1 | % Colors for syntax highlighting 2 | \usepackage{xcolor} 3 | \definecolor{RoyalPurple}{HTML}{613F99} 4 | \definecolor{keyword}{named}{RoyalPurple} 5 | \definecolor{var}{rgb}{0,0,0.5} % Navy 6 | \definecolor{ForestGreen}{HTML}{009B55} 7 | \definecolor{comment}{named}{ForestGreen} 8 | \definecolor{linkblue}{rgb}{.098,.098,.439} %Midnight blue 9 | \definecolor{fm}{named}{ForestGreen} 10 | \definecolor{Yellow}{HTML}{FFF200} 11 | \definecolor{shadecolor}{named}{Yellow} 12 | 13 | % Enable this code for a black and white version 14 | %\usepackage[usenames,dvipsnames]{xcolor} 15 | %\definecolor{keyword}{named}{Black} 16 | %\definecolor{var}{named}{Black} % Navy 17 | %\definecolor{comment}{gray}{0.5} 18 | %\definecolor{linkblue}{named}{Black} 19 | %\definecolor{fm}{named}{Black} 20 | % 21 | 22 | 23 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | The following two directories contain code from Sun Microsystems and 2 | the Apache Foundation: 3 | 4 | java/test/acc/ 5 | java/test/jdk/ 6 | 7 | 8 | Consult the file headers of the files in these directories for information 9 | about their copyright status. 10 | 11 | ---- 12 | The following directories contain code created for the Open Data 13 | Structures project. 14 | 15 | latex/ 16 | java/ods/ 17 | 18 | This code is released under a Creative Commons Attribution license. 19 | The full text of the license is available here. 20 | 21 | http://creativecommons.org/licenses/by/2.5/ca/ 22 | 23 | Users of this code should attribute the work to the Open Data Structures 24 | project by displaying a notice stating their product contains code 25 | and/or text from the Open Data Structures Project and/or linking to 26 | opendatastructures.org. 27 | 28 | -------------------------------------------------------------------------------- /latex/README: -------------------------------------------------------------------------------- 1 | Use GNU make to create the files ods-java.pdf and ods-cpp.pdf ods-python.pdf 2 | 3 | During the make process, all of the tex files in this directory are 4 | preprocessed with scripts. These scripts allow for the insertion of 5 | source code into the tex files and do two things: 6 | 7 | 1. They expand \(code|java|cpp)import{} commands into Verbatim 8 | environments that contain highlighted versions of the relevant 9 | source code. 10 | 11 | 2. They treat anything sandwiched between # and # as inline source 12 | code that is also highlighted and typeset with a fixed-width font. 13 | This is suitable for use inside of math environments so that source 14 | code variables and functions can be used inside of equations. 15 | 16 | Any .tex file whose filename looks like blah-cpp.tex, blah-java.tex, 17 | or blah-python.tex was generated by these perl scripts. Don't edit 18 | them by hand. 19 | -------------------------------------------------------------------------------- /java/junk/Point3D.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | public class Point3D { 4 | protected Double x0, x1, x2; 5 | 6 | public boolean equals(Object o) { 7 | return (o instanceof Point3D) && ((Point3D)o).x0.equals(x0) 8 | && ((Point3D)o).x1.equals(x1) && ((Point3D)o).x2.equals(x2); 9 | } 10 | 11 | public int hashCode() { 12 | // random numbers from rand.org 13 | long[] z = {0x2058cc50L, 0xcb19137eL, 0x2cb6b6fdL}; 14 | long zz = 0xbea0107e5067d19dL; 15 | 16 | // convert (unsigned) hashcodes to long 17 | long h0 = x0.hashCode() & ((1L<<32)-1); 18 | long h1 = x1.hashCode() & ((1L<<32)-1); 19 | long h2 = x2.hashCode() & ((1L<<32)-1); 20 | 21 | return (int)(((z[0]*h0 + z[1]*h1 + z[2]*h2)*zz) 22 | >>> 32); 23 | } 24 | 25 | public static void main(String[] args) { 26 | Integer two = -3; 27 | long ltwo = two & (1L<<32)-1; 28 | System.out.println(two.hashCode() + " " + ltwo); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Transparências/estruturasDeDados.tex: -------------------------------------------------------------------------------- 1 | %\usetheme{CambridgeUS} % tema 2 | % \usecolortheme{orchid} % cores 3 | \usetheme{metropolis} 4 | \metroset{numbering=fraction, sectionpage=none, subsectionpage=progressbar} 5 | \usecolortheme{seahorse} 6 | \usecolortheme{rose} 7 | \usefonttheme[onlysmall]{structurebold} 8 | \usefonttheme[onlymath]{serif} % fonte modo matematico 9 | 10 | \usepackage{framed} 11 | \usepackage{disciplina} 12 | \usepackage{tikz} 13 | \usetikzlibrary{calc,shapes.multipart,chains,arrows} 14 | \usepgflibrary{shapes.multipart} 15 | \newcommand{\eq}{=} 16 | 17 | \author[João Araujo Ribeiro]{João Araujo Ribeiro \\ \texttt{jaraujo@uerj.br}} 18 | \institute[UERJ]{Universidade do Estado do Rio de Janeiro} % opcional 19 | \date[EstrInf]{Departamento de Engenharia de Sistemas e Computação} 20 | \pgfdeclareimage[height=0.7cm]{imagens//logo.png}{imagens//logodesc.png} 21 | \logo{\pgfuseimage{imagens//logo.png}} -------------------------------------------------------------------------------- /latex/ack-ptbr.tex: -------------------------------------------------------------------------------- 1 | \chapter*{Agradecimentos} 2 | \addcontentsline{toc}{chapter}{Agradecimentos} 3 | 4 | Sou grato a Nima~Hoda, que passou um verão corrigindo incansavelmente muitos 5 | dos capítulos deste livro; aos alunos da disciplina COMP2402/2002 no outono 2011, que 6 | aguentaram o primeiro rascunho deste livro e alertaram sobre muitos erros tipográficos, 7 | gramaticais e factuais; e a Morgan~Tunzelmann da Athabasca University Press, por ter 8 | pacientemente editado vários rascunhos quase finais. 9 | 10 | \section{Agradecimentos da Edição Brasileira} 11 | 12 | Gostaria de agradecer aos meus alunos do curso de Estruturas de Informação, da 13 | Universidade do Estado do Rio de Janeiro que gentilmente me auxiliaram na tradução 14 | deste livro. Foram eles: Diana Almeida Barros, Leonardo Lobão, Ester Gomes Pais, 15 | Fábio Cavallari, Lucas Ferreira Stefe, Matheus Caldeira Matias e Pedro Yuri 16 | dos Reis de Moraes Lopes. 17 | 18 | Ass. João Araujo Ribeiro -------------------------------------------------------------------------------- /cpp/AdjacencyMatrix.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AdjacencyMatrix.h 3 | * 4 | * Created on: 2012-01-13 5 | * Author: morin 6 | */ 7 | 8 | #ifndef ADJACENCYMATRIX_H_ 9 | #define ADJACENCYMATRIX_H_ 10 | 11 | namespace ods { 12 | 13 | class AdjacencyMatrix { 14 | protected: 15 | int n; 16 | bool **a; 17 | public: 18 | AdjacencyMatrix(int n); 19 | virtual ~AdjacencyMatrix(); 20 | void addEdge(int i, int j) { 21 | a[i][j] = true; 22 | } 23 | 24 | void removeEdge(int i, int j) { 25 | a[i][j] = false; 26 | } 27 | 28 | bool hasEdge(int i, int j) { 29 | return a[i][j]; 30 | } 31 | 32 | template 33 | void outEdges(int i, List &edges) { 34 | for (int j = 0; j < n; j++) 35 | if (a[i][j]) edges.add(j); 36 | } 37 | 38 | template 39 | void inEdges(int i, List &edges) { 40 | for (int j = 0; j < n; j++) 41 | if (a[j][i]) edges.add(j); 42 | } 43 | 44 | int nVertices() { 45 | return n; 46 | } 47 | }; 48 | 49 | } /* namespace ods */ 50 | #endif /* ADJACENCYMATRIX_H_ */ 51 | -------------------------------------------------------------------------------- /java/junk/GeomVector.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | public class GeomVector { 4 | 5 | Double[] x; 6 | 7 | public boolean equals(Object o) { 8 | if (!(o instanceof GeomVector)) return false; 9 | GeomVector gvo = (GeomVector)o; 10 | if (gvo.x.length != x.length) return false; 11 | for (int i = 0; i < x.length; i++) 12 | if (gvo.x[i] != x[i]) return false; 13 | return true; 14 | } 15 | 16 | 17 | public int hashCode() { 18 | long p = (1L<<32)-5; // prime: 2^32 - 5 19 | long z = 0x64b6055aL; // 32 bits from random.org 20 | int z2 = 0x5067d19d; // random odd 32 bit number 21 | long s = 0; 22 | long zi = 1; 23 | for (int i = 0; i < x.length; i++) { 24 | // reduce to 31 bits 25 | long xi = (x[i].hashCode() * z2) >>> 1; 26 | s = (s + zi * xi) % p; 27 | zi = (zi * z) % p; 28 | } 29 | s = (s + zi * (p-1)) % p; 30 | return (int)s; 31 | } 32 | 33 | public static void main(String[] args) { 34 | System.out.printf("%d\n", 4294967311L * 0x64b6055aL + ((1L<<32)-1)); 35 | System.out.printf("%d\n", (1L<<63)-1); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /python/ods/tests/graphtest.py: -------------------------------------------------------------------------------- 1 | 2 | import random 3 | import ods 4 | 5 | def exercise_graph(Clz=ods.AdjacencyMatrix): 6 | n = 50 7 | g = Clz(n) 8 | s = set() 9 | 10 | # add a bunch of random edges 11 | for i in range(5*n): 12 | i, j = random.randrange(n), random.randrange(n) 13 | if (i,j) not in s: 14 | s.add((i,j)) 15 | g.add_edge(i,j) 16 | 17 | for i in range(n): 18 | for j in range(n): 19 | assert(g.has_edge(i,j) == ((i,j) in s)) 20 | 21 | # remove some of these edges 22 | rem = random.sample(s, n) 23 | for e in rem: 24 | s.remove(e) 25 | g.remove_edge(e[0], e[1]) 26 | 27 | for i in range(n): 28 | for j in range(n): 29 | assert(g.has_edge(i,j) == ((i,j) in s)) 30 | 31 | # check that in and out degrees are correctly computed 32 | for i in range(n): 33 | od = len([e for e in s if e[0] == i]) 34 | id = len([e for e in s if e[1] == i]) 35 | assert(g.out_degree(i) == od) 36 | assert(g.in_degree(i) == id) 37 | 38 | -------------------------------------------------------------------------------- /latex/cpp-preface.tex: -------------------------------------------------------------------------------- 1 | \cpponly{ 2 | \chapter*{Preface to the C++ Edition} 3 | \addcontentsline{toc}{chapter}{Preface to the C++ Edition} 4 | 5 | This book is intended to teach the design and analysis of basic data 6 | structures and their implementation in an object-oriented language. 7 | In this edition, the language happens to be C++. 8 | 9 | This book is not intended to act as an introduction to the C++ programming 10 | language. Readers of this book need only be familiar with the basic 11 | syntax of C++ and similar languages. Those wishing to work with the 12 | accompanying source code should have some experience programming in C++. 13 | 14 | This book is also not intended as an introduction to the C++ Standard 15 | Template Library or the generic programming paradigm that the STL 16 | embodies. This book describes implementations of several different data 17 | structures, many of which are used in implementations of the STL. The 18 | contents of this book may help an STL programmer understand how some of 19 | the STL data structures are implemented and why these implementations 20 | are efficient. 21 | } 22 | -------------------------------------------------------------------------------- /python/ods/tests/settest.py: -------------------------------------------------------------------------------- 1 | 2 | import random 3 | 4 | def set_cmp(s1, s2): 5 | """Compare s1 and s2 several different ways""" 6 | assert(len(s1) == len(s2)) 7 | assert(sorted(s1) == sorted(s2)) 8 | for x in s1: 9 | assert(x in s2) 10 | for x in s2: 11 | assert(x in s1) 12 | 13 | def exercise_set(s): 14 | s1 = s 15 | s2 = set() 16 | 17 | n = 100 18 | for j in range(5): 19 | if j == 2: 20 | s1.clear() 21 | s2.clear() 22 | for _ in range(n): 23 | x = random.randrange(2*n) 24 | s1.add(x) 25 | s2.add(x) 26 | set_cmp(s1, s2) 27 | 28 | for i in range(2*n): 29 | assert((i in s1) == (i in s2)) 30 | 31 | for i in range(n): 32 | x = random.randrange(2*n) 33 | if x in s2: 34 | s1.remove(x) 35 | s2.remove(x) 36 | set_cmp(s1, s2) 37 | 38 | for i in range(2*n): 39 | assert((i in s1) == (i in s2)) 40 | 41 | 42 | -------------------------------------------------------------------------------- /cpp/utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * utils.h 3 | * 4 | * Created on: 2011-11-23 5 | * Author: morin 6 | */ 7 | 8 | #ifndef UTILS_H_ 9 | #define UTILS_H_ 10 | 11 | namespace ods { 12 | 13 | template inline 14 | T min(T a, T b) { 15 | return ((a)<(b) ? (a) : (b)); 16 | } 17 | 18 | template inline 19 | T max(T a, T b) { 20 | return ((a)>(b) ? (a) : (b)); 21 | } 22 | 23 | template inline 24 | int compare(T &x, T &y) { 25 | if (x < y) return -1; 26 | if (y < x) return 1; 27 | return 0; 28 | } 29 | 30 | template inline 31 | bool equals(T &x, T &y) { 32 | return x == y; 33 | } 34 | 35 | inline 36 | unsigned intValue(int x) { 37 | return (unsigned)x; 38 | } 39 | 40 | /** 41 | * This is terrible - don't use it 42 | */ 43 | int hashCode(int x); 44 | 45 | template class XFastTrieNode1; 46 | 47 | 48 | template 49 | unsigned hashCode(const XFastTrieNode1 *u) { 50 | return u->prefix; 51 | } 52 | 53 | 54 | class dodo { 55 | public: 56 | bool operator < (dodo &d) { 57 | return this < &d; 58 | } 59 | }; 60 | 61 | } /* namespace ods */ 62 | 63 | 64 | #endif /* UTILS_H_ */ 65 | -------------------------------------------------------------------------------- /cpp/BinarySearchTree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * BinarySearchTree.cpp 3 | * 4 | * Created on: 2011-11-28 5 | * Author: morin 6 | */ 7 | 8 | #include "BinarySearchTree.h" 9 | #include "utils.h" 10 | namespace ods { 11 | 12 | /** 13 | * Todo: Do this for other classes and/or move this up into BinarySearchTree 14 | */ 15 | template<> 16 | BinarySearchTree1::BinarySearchTree1() : BinarySearchTree, int>(INT_MIN) { 17 | } 18 | 19 | template<> 20 | BinarySearchTree1::BinarySearchTree1() : BinarySearchTree, long>(LONG_MIN) { 21 | } 22 | 23 | template<> 24 | BinarySearchTree1::BinarySearchTree1() : BinarySearchTree, long long>(LLONG_MIN) { 25 | } 26 | 27 | template<> 28 | BinarySearchTree1::BinarySearchTree1() : BinarySearchTree, double>(NAN) { 29 | } 30 | 31 | template<> 32 | BinarySearchTree1::BinarySearchTree1() : BinarySearchTree, float>(NAN) { 33 | } 34 | 35 | template class BinarySearchTree1; 36 | template class BinarySearchTree1; 37 | // template class BinarySearchTree1; 38 | 39 | } /* namespace ods */ 40 | -------------------------------------------------------------------------------- /java/ods/Factory.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.lang.reflect.Array; 4 | 5 | /** 6 | * An ugly little class for allocating objects and arrays of generic 7 | * type T. This is needed to work around limitations of Java generics. 8 | */ 9 | public class Factory { 10 | Class t; 11 | 12 | /** 13 | * Return the type associated with this factory 14 | * @return 15 | */ 16 | public Class type() { 17 | return t; 18 | } 19 | 20 | /** 21 | * Constructor - creates a factory for creating objects and 22 | * arrays of type t(=T) 23 | * @param t0 24 | */ 25 | public Factory(Class t0) { 26 | t = t0; 27 | } 28 | 29 | /** 30 | * Allocate a new array of objects of type T. 31 | * @param n the size of the array to allocate 32 | * @return the array allocated 33 | */ 34 | @SuppressWarnings({"unchecked"}) 35 | protected T[] newArray(int n) { 36 | return (T[])Array.newInstance(t, n); 37 | } 38 | 39 | /** 40 | * 41 | * @return 42 | */ 43 | public T newInstance() { 44 | T x; 45 | try { 46 | x = t.newInstance(); 47 | } catch (Exception e) { 48 | x = null; 49 | } 50 | return x; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /python/ods/arrayqueue.py: -------------------------------------------------------------------------------- 1 | """An array-based implementation of a queue that uses modular arithmetic.""" 2 | from .utils import new_array 3 | 4 | from .base import BaseList 5 | 6 | class ArrayQueue(BaseList): 7 | def __init__(self, iterable=[]): 8 | self._initialize() 9 | self.add_all(iterable) 10 | 11 | def _initialize(self): 12 | self.a = new_array(1) 13 | self.j = 0 14 | self.n = 0 15 | 16 | def _resize(self): 17 | b = new_array(max(1, 2*self.n)) 18 | for k in range(self.n): 19 | b[k] = self.a[(self.j+k) % len(self.a)] 20 | self.a = b 21 | self.j = 0 22 | 23 | def add(self, x): 24 | if self.n + 1 > len(self.a): self._resize() 25 | self.a[(self.j+self.n) % len(self.a)] = x 26 | self.n += 1 27 | return True 28 | 29 | def remove(self): 30 | if self.n == 0: raise IndexError() 31 | x = self.a[self.j] 32 | self.j = (self.j + 1) % len(self.a) 33 | self.n -= 1 34 | if len(self.a) >= 3*self.n: self._resize() 35 | return x 36 | 37 | def get(self, i): 38 | return self.a[(self.j + i) % len(self.a)] 39 | -------------------------------------------------------------------------------- /java/ods/ScapegoatTree2.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | public class ScapegoatTree2 extends ScapegoatTree { 4 | 5 | protected void rebuild(Node u) { 6 | int n = size(u); 7 | Node p = u.parent; 8 | // FIXME: check if p is root 9 | if (p == nil) { 10 | r = rebuildTree(n,u); 11 | } else if (p.left == u) { 12 | u = rebuildTree(n, u); 13 | p.left = u; 14 | } else { 15 | u = rebuildTree(n, u); 16 | p.right = u; 17 | } 18 | u.parent = p; 19 | } 20 | 21 | protected Node flatten(Node x, Node y) { 22 | if (x == nil) return y; 23 | x.right = flatten(x.right, y); 24 | return flatten(x.left, x); 25 | } 26 | 27 | protected Node buildTree(int n, Node x) { 28 | if (n == 0) { 29 | x.left = nil; 30 | return x; 31 | } 32 | int k = n/2; 33 | Node r = buildTree(k, x); 34 | Node s = buildTree(n-k-1, r.right); 35 | r.right = s.left; 36 | if (s.left != nil) s.left.parent = r; 37 | s.left = r; 38 | r.parent = s; 39 | return s; 40 | } 41 | 42 | protected Node rebuildTree(int n, Node scapegoat) { 43 | Node w = newNode(); 44 | Node z = flatten(scapegoat, w); 45 | buildTree(n, z); 46 | return w.left; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /java/ods/SkiplistRope.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.Random; 4 | 5 | public class SkiplistRope { 6 | class Node { 7 | SString s; 8 | Node[] next; 9 | int[] length; 10 | public Node(SString s, int h) { 11 | this.s = s; 12 | next = (Node[])new Node[h+1]; 13 | length = new int[h+1]; 14 | } 15 | } 16 | 17 | /** 18 | * This node sits on the left side of the skiplist 19 | */ 20 | protected Node sentinel; 21 | 22 | /** 23 | * The maximum height of any element 24 | */ 25 | int height; 26 | 27 | /** 28 | * The number of SStrings stored in the skiplist 29 | */ 30 | int n; 31 | 32 | /** 33 | * A source of random numbers 34 | */ 35 | Random r; 36 | 37 | public SkiplistRope() { 38 | n = 0; 39 | sentinel = new Node(null, 33); 40 | height = 0; 41 | r = new Random(0); 42 | } 43 | 44 | public char charAt(int i) { 45 | Node u = sentinel; 46 | int r = height - 1; 47 | int j = -1; // the index of the first character of u's string 48 | while (r >= 0) { 49 | while (u.next[r] != null && j + u.length[r] < i) { 50 | j += u.length[r]; 51 | u = u.next[r]; 52 | } 53 | r--; 54 | } 55 | return u.s.charAt(i-j); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /java/ods/FastArrayStack.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | /** 4 | * This subclass of ArrayStack overrides some of its functions to make 5 | * them faster. In particular, it uses System.arraycopy() rather than for 6 | * loops copy elements between arrays and to shift them within arrays. 7 | * @author morin 8 | * 9 | * @param 10 | */ 11 | public class FastArrayStack extends ArrayStack { 12 | public FastArrayStack(Class t0) { 13 | super(t0); 14 | } 15 | 16 | protected void resize() { 17 | T[] b = f.newArray(Math.max(2*n,1)); 18 | System.arraycopy(a, 0, b, 0, n); 19 | a = b; 20 | } 21 | 22 | protected void resize(int nn) { 23 | T[] b = f.newArray(nn); 24 | System.arraycopy(a, 0, b, 0, n); 25 | a = b; 26 | } 27 | 28 | public void add(int i, T x) { 29 | if (i < 0 || i > n) throw new IndexOutOfBoundsException(); 30 | if (n + 1 > a.length) resize(); 31 | System.arraycopy(a, i, a, i+1, n-i); 32 | a[i] = x; 33 | n++; 34 | } 35 | 36 | public T remove(int i) { 37 | if (i < 0 || i > n - 1) throw new IndexOutOfBoundsException(); 38 | T x = a[i]; 39 | System.arraycopy(a, i+1, a, i, n-i-1); 40 | n--; 41 | if (a.length >= 3*n) resize(); 42 | return x; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /cpp/BlockStore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * BlockStore.h 3 | * 4 | * Created on: 2013-07-03 5 | * Author: morin 6 | */ 7 | 8 | #ifndef BLOCKSTORE_H_ 9 | #define BLOCKSTORE_H_ 10 | 11 | #include "ArrayStack.h" 12 | 13 | namespace ods { 14 | 15 | /** 16 | * This class fakes an external memory block storage system. It's just a list 17 | * of blocks. 18 | */ 19 | template 20 | class BlockStore { 21 | protected: 22 | ArrayStack blocks; // list of blocks 23 | ArrayStack free; // unused block indices 24 | public: 25 | BlockStore() : blocks(), free() { } 26 | virtual void clear() { 27 | blocks.clear(); 28 | free.clear(); 29 | } 30 | virtual ~BlockStore() { 31 | clear(); 32 | } 33 | virtual int placeBlock(T block) { 34 | int i; 35 | if (free.size() > 0) { 36 | i = free.remove(free.size()); 37 | } else { 38 | i = blocks.size(); 39 | blocks.add(i, block); 40 | } 41 | return i; 42 | } 43 | virtual void freeBlock(int i) { 44 | blocks.set(i, NULL); 45 | free.add(i); 46 | } 47 | virtual T readBlock(int i) { 48 | return blocks.get(i); 49 | } 50 | void writeBlock(int i, T block) { 51 | blocks.set(i, block); 52 | } 53 | }; 54 | 55 | } /* namespace ods */ 56 | #endif /* BLOCKSTORE_H_ */ 57 | -------------------------------------------------------------------------------- /Transparências/Testes/animated.blg: -------------------------------------------------------------------------------- 1 | This is BibTeX, Version 0.99d (TeX Live 2015/Debian) 2 | Capacity: max_strings=35307, hash_size=35307, hash_prime=30011 3 | The top-level auxiliary file: animated.aux 4 | I found no \citation commands---while reading file animated.aux 5 | I found no \bibdata command---while reading file animated.aux 6 | I found no \bibstyle command---while reading file animated.aux 7 | You've used 0 entries, 8 | 0 wiz_defined-function locations, 9 | 83 strings with 490 characters, 10 | and the built_in function-call counts, 0 in all, are: 11 | = -- 0 12 | > -- 0 13 | < -- 0 14 | + -- 0 15 | - -- 0 16 | * -- 0 17 | := -- 0 18 | add.period$ -- 0 19 | call.type$ -- 0 20 | change.case$ -- 0 21 | chr.to.int$ -- 0 22 | cite$ -- 0 23 | duplicate$ -- 0 24 | empty$ -- 0 25 | format.name$ -- 0 26 | if$ -- 0 27 | int.to.chr$ -- 0 28 | int.to.str$ -- 0 29 | missing$ -- 0 30 | newline$ -- 0 31 | num.names$ -- 0 32 | pop$ -- 0 33 | preamble$ -- 0 34 | purify$ -- 0 35 | quote$ -- 0 36 | skip$ -- 0 37 | stack$ -- 0 38 | substring$ -- 0 39 | swap$ -- 0 40 | text.length$ -- 0 41 | text.prefix$ -- 0 42 | top$ -- 0 43 | type$ -- 0 44 | warning$ -- 0 45 | while$ -- 0 46 | width$ -- 0 47 | write$ -- 0 48 | (There were 3 error messages) 49 | -------------------------------------------------------------------------------- /python/ods/controlsset.py: -------------------------------------------------------------------------------- 1 | """A class that implements a stupid SSet (for testing purposes)""" 2 | 3 | import bisect 4 | 5 | from .base import BaseSet 6 | 7 | class ControlSSet(BaseSet): 8 | def __init__(self, iterable=[]): 9 | self.a = [] 10 | self.add_all(iterable) 11 | 12 | def add_all(self, iterable): 13 | for x in iterable: 14 | self.add(x) 15 | 16 | def add(self, x): 17 | i = bisect.bisect_left(self.a, x) 18 | if i == len(self.a) or self.a[i] != x: 19 | bisect.insort_right(self.a, x) 20 | return True 21 | return False 22 | 23 | def remove(self, x): 24 | i = bisect.bisect_left(self.a, x) 25 | if i != len(self.a) and self.a[i] == x: 26 | del self.a[i] 27 | return True 28 | return False 29 | 30 | def find(self, x): 31 | i = bisect.bisect_left(self.a, x) 32 | if i != len(self.a): 33 | return self.a[i] 34 | return None 35 | 36 | def size(self): 37 | return len(self.a) 38 | 39 | def clear(self): 40 | self.a = list() 41 | 42 | def __iter__(self): 43 | return self.a.__iter__() 44 | 45 | 46 | -------------------------------------------------------------------------------- /java/ods/USetSet.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.AbstractSet; 4 | import java.util.ArrayList; 5 | import java.util.Collection; 6 | import java.util.HashSet; 7 | import java.util.Iterator; 8 | import java.util.Set; 9 | 10 | public class USetSet extends AbstractSet { 11 | USet s; 12 | 13 | public USetSet(USet s) { 14 | this.s = s; 15 | } 16 | 17 | @SuppressWarnings("unchecked") 18 | public boolean contains(Object x) { 19 | return s.find((T)x) != null; 20 | } 21 | 22 | public boolean add(T x) { 23 | return s.add(x); 24 | } 25 | 26 | @SuppressWarnings("unchecked") 27 | public boolean remove(Object x) { 28 | return s.remove((T)x) != null; 29 | } 30 | 31 | public Iterator iterator() { 32 | return s.iterator(); 33 | } 34 | 35 | public int size() { 36 | return s.size(); 37 | } 38 | 39 | public void clear() { 40 | s.clear(); 41 | } 42 | 43 | public static void main(String[] args) { 44 | int n = 1000000; 45 | Collection> cs = new ArrayList>(); 46 | cs.add(new HashSet()); 47 | cs.add(new USetSet(new LinearHashTable(-1))); 48 | cs.add(new USetSet(new ChainedHashTable())); 49 | Testum.setSpeedTests(cs, n); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /java/ods/MultiplicativeHashMap.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.AbstractMap; 4 | import java.util.Set; 5 | 6 | class Pair { 7 | public Object key; 8 | public V value; 9 | public Pair(Object ikey, V ivalue) { 10 | key = ikey; 11 | value = ivalue; 12 | } 13 | @SuppressWarnings("unchecked") 14 | public boolean equals(Object o) { 15 | return ((o instanceof Pair) && key.equals(((Pair)o).key)); 16 | } 17 | public int hashCode() { 18 | return key.hashCode(); 19 | } 20 | } 21 | 22 | public class MultiplicativeHashMap extends AbstractMap { 23 | /** 24 | * The underlying hash table 25 | */ 26 | HashTable> tab; 27 | 28 | public V put(K key, V value) { 29 | Pair p = new Pair(key, value); 30 | Pair r = tab.removeOne(p); 31 | tab.add(p); 32 | return (r == null) ? null : r.value; 33 | } 34 | 35 | public V get(Object key) { 36 | Pair p = new Pair(key, null); 37 | Pair r = tab.find(p); 38 | return (r == null) ? null : r.value; 39 | } 40 | 41 | public V remove(Object key) { 42 | Pair p = new Pair(key, null); 43 | Pair r = tab.removeOne(p); 44 | return (r == null) ? null : r.value; 45 | } 46 | 47 | public Set> entrySet() { 48 | return null; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /python/ods/adjacencymatrix.py: -------------------------------------------------------------------------------- 1 | """An implementation of the adjacency matrix representation of a graph""" 2 | from .utils import new_boolean_matrix 3 | 4 | class AdjacencyMatrix(object): 5 | def __init__(self, n): 6 | self.n = n 7 | self._initialize() 8 | 9 | def _initialize(self): 10 | self.a = new_boolean_matrix(self.n, self.n) 11 | 12 | def add_edge(self, i, j): 13 | self.a[i][j] = True 14 | 15 | def remove_edge(self, i, j): 16 | self.a[i][j] = False 17 | 18 | def has_edge(self, i, j): 19 | return self.a[i][j] 20 | 21 | def out_edges(self, i): 22 | out = list() 23 | for j in range(self.n): 24 | if self.a[i][j]: out.append(j) 25 | return out 26 | 27 | def in_edges(self, i): 28 | out = list() 29 | for j in range(self.n): 30 | if self.a[j][i]: out.append(j) 31 | return out 32 | 33 | def in_degree(self, i): 34 | deg = 0 35 | for j in range(self.n): 36 | if self.a[j][i]: 37 | deg += 1 38 | return deg 39 | 40 | def out_degree(self, i): 41 | deg = 0 42 | for j in range(self.n): 43 | if self.a[i][j]: 44 | deg += 1 45 | return deg 46 | 47 | -------------------------------------------------------------------------------- /cpp/FastArrayStack.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FastArrayStack.h 3 | * 4 | * Created on: 2011-11-23 5 | * Author: morin 6 | */ 7 | 8 | #ifndef FASTARRAYSTACK_H_ 9 | #define FASTARRAYSTACK_H_ 10 | 11 | #include "ArrayStack.h" 12 | 13 | namespace ods { 14 | 15 | template 16 | class FastArrayStack : public ArrayStack { 17 | protected: 18 | using ArrayStack::a; 19 | using ArrayStack::n; 20 | virtual void resize(); 21 | public: 22 | virtual ~FastArrayStack(); 23 | FastArrayStack(); 24 | virtual void add(int i, T x); 25 | virtual T remove(int i); 26 | }; 27 | 28 | template 29 | FastArrayStack::FastArrayStack() : ArrayStack() { 30 | } 31 | 32 | template 33 | FastArrayStack::~FastArrayStack() { 34 | } 35 | 36 | template 37 | void FastArrayStack::resize() { 38 | array b(max(1, 2*n)); 39 | std::copy(a+0, a+n, b+0); 40 | a = b; 41 | } 42 | 43 | template 44 | void FastArrayStack::add(int i, T x) { 45 | if (n + 1 > a.length) resize(); 46 | std::copy_backward(a+i, a+n, a+n+1); 47 | a[i] = x; 48 | n++; 49 | } 50 | 51 | template 52 | T FastArrayStack::remove(int i) 53 | { 54 | T x = a[i]; 55 | std::copy(a+i+1, a+n, a+i); 56 | n--; 57 | if (a.length >= 3 * n) resize(); 58 | return x; 59 | } 60 | 61 | 62 | } /* namespace ods */ 63 | #endif /* FASTARRAYSTACK_H_ */ 64 | -------------------------------------------------------------------------------- /cpp/ArrayQueue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ArrayQueue.h 3 | * 4 | * Created on: 2011-11-23 5 | * Author: morin 6 | */ 7 | 8 | #ifndef ARRAYQUEUE_H_ 9 | #define ARRAYQUEUE_H_ 10 | #include "array.h" 11 | #include "utils.h" 12 | 13 | namespace ods { 14 | 15 | template 16 | class ArrayQueue { 17 | protected: 18 | array a; 19 | int j; 20 | int n; 21 | void resize(); 22 | public: 23 | ArrayQueue(); 24 | virtual ~ArrayQueue(); 25 | virtual bool add(T x); 26 | virtual T remove(); 27 | int size(); 28 | }; 29 | 30 | template 31 | ArrayQueue::ArrayQueue() : a(1) { 32 | n = 0; 33 | j = 0; 34 | } 35 | 36 | template 37 | ArrayQueue::~ArrayQueue() { 38 | } 39 | 40 | template 41 | void ArrayQueue::resize() { 42 | array b(max(1, 2*n)); 43 | for (int k = 0; k < n; k++) 44 | b[k] = a[(j+k)%a.length]; 45 | a = b; 46 | j = 0; 47 | } 48 | 49 | template 50 | bool ArrayQueue::add(T x) { 51 | if (n + 1 > a.length) resize(); 52 | a[(j+n) % a.length] = x; 53 | n++; 54 | return true; 55 | } 56 | 57 | template 58 | T ArrayQueue::remove() { 59 | T x = a[j]; 60 | j = (j + 1) % a.length; 61 | n--; 62 | if (a.length >= 3*n) resize(); 63 | return x; 64 | } 65 | 66 | template 67 | int ArrayQueue::size() { 68 | return n; 69 | } 70 | 71 | } /* namespace ods */ 72 | #endif /* ARRAYQUEUE_H_ */ 73 | -------------------------------------------------------------------------------- /python/ods/tests/ssettest.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | from ods import ControlSSet 4 | 5 | 6 | def exercise_sset(t1): 7 | random.seed(0) 8 | 9 | t2 = ControlSSet() 10 | n = 200 11 | for k in range(5): 12 | for i in range(n): 13 | x = random.randrange(0,5*n) 14 | t1.add(x) 15 | t2.add(x) 16 | assert(str(t1) == str(t2)) 17 | assert(len(t1) == len(t2)) 18 | 19 | assert(t2 == t1) 20 | assert(len(t1) == len(t2)) 21 | assert(str(t1) == str(t2)) 22 | 23 | for i in range(n): 24 | x = random.randrange(0,5*n) 25 | y = t1.find(x) 26 | y2 = t2.find(x) 27 | assert(y == y2) 28 | 29 | assert(len(t1) == len(t2)) 30 | assert(str(t1) == str(t2)) 31 | 32 | for i in range(n): 33 | x = random.randrange(0,5*n) 34 | b1 = t1.remove(x) 35 | b2 = t2.remove(x) 36 | assert(b1 == b2) 37 | 38 | assert(len(t1) == len(t2)) 39 | assert(str(t1) == str(t2)) 40 | 41 | for i in range(n): 42 | x = random.randrange(0,5*n) 43 | y = t1.find(x) 44 | y2 = t2.find(x) 45 | assert(y == y2) 46 | 47 | assert(len(t1) == len(t2)) 48 | assert(str(t1) == str(t2)) 49 | -------------------------------------------------------------------------------- /c/include/iterator.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * File : iterator.h 3 | * Author(s) : Tekin Ozbek 4 | ******************************************************************************/ 5 | 6 | #ifndef ODS_ITERATOR_H_ 7 | #define ODS_ITERATOR_H_ 8 | 9 | typedef struct iterator_t { 10 | 11 | /* FUNCTION 12 | * next 13 | * 14 | * DESCRIPTION 15 | * Advances to the next element if possible, or returns 0 if there are 16 | * no more elements left. In case of reverse iteration, this function 17 | * will advance to the previous element. 18 | * 19 | * RETURN VALUE 20 | * Returns 1 if there is a next element, 0 otherwise. 21 | */ 22 | int (*next)(struct iterator_t*); 23 | 24 | /* FUNCTION 25 | * elem 26 | * 27 | * RETURN VALUE 28 | * Returns pointer to the element at current position. This is a 29 | * pointer to the data within the data structure, not a copy. 30 | */ 31 | void* (*elem)(struct iterator_t*); 32 | 33 | /* FUNCTION 34 | * elem 35 | * 36 | * DESCRIPTION 37 | * Cleans up the memory used by the iterator. 38 | */ 39 | void (*dispose)(struct iterator_t*); 40 | 41 | void* istruct; 42 | 43 | } iterator_t; 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /Transparências/disciplina.sty: -------------------------------------------------------------------------------- 1 | \ProvidesPackage{disciplina} 2 | \mode 3 | \usepackage[utf8]{inputenc} % codificacao de caracteres 4 | \usepackage[brazil]{babel} % idioma 5 | \usepackage{default} 6 | \usepackage{tikz} 7 | \usepackage{verbatim} 8 | \usepackage[T1]{fontenc} 9 | %\usepackage{listings} 10 | \usepackage{listingsutf8} 11 | \lstset{ 12 | inputencoding=utf8/latin1, 13 | language=python, 14 | upquote=true, 15 | columns=flexible, 16 | basicstyle=\ttfamily, 17 | keywordstyle=\bfseries\color{green!40!black}, 18 | identifierstyle=\color{blue}, 19 | extendedchars=true, 20 | stringstyle=\color{orange}, 21 | numbers=left, 22 | numberstyle=\tiny\color{lightgray}, 23 | firstnumber=auto, 24 | showspaces=false, 25 | tabsize=2, 26 | showstringspaces=false, 27 | literate= {'}{{\'{ }}}1 28 | } 29 | 30 | \usepackage{color} 31 | \usepackage{caption} 32 | \usetikzlibrary{arrows,shapes} 33 | \usepackage{wrapfig} 34 | 35 | % Desativando os botoes de navegacao 36 | \beamertemplatenavigationsymbolsempty 37 | \setbeamercolor{title}{fg=red!80!black} 38 | % Tela cheia 39 | \hypersetup{pdfpagemode=FullScreen} 40 | % Layout da pagina 41 | \hypersetup{pdfpagelayout=SinglePage} 42 | \newcommand\totiny{\tiny\selectfont} 43 | \newcommand\tosmall{\small\selectfont} 44 | \newcommand\toscriptsize{\scriptsize\selectfont} 45 | \newcommand{\textttb}[1]{\textcolor{blue}{\texttt{#1}}} -------------------------------------------------------------------------------- /cpp/AdjacencyLists.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AdjacencyLists.h 3 | * 4 | * Created on: 2012-01-13 5 | * Author: morin 6 | */ 7 | 8 | #ifndef ADJACENCYLISTS_H_ 9 | #define ADJACENCYLISTS_H_ 10 | 11 | #include "ArrayStack.h" 12 | 13 | namespace ods { 14 | 15 | class AdjacencyLists { 16 | protected: 17 | class List : public ArrayStack { 18 | public: 19 | List() : ArrayStack() {}; 20 | virtual ~List() {}; 21 | bool contains(int j) { 22 | for (int i = 0; i < n; i++) 23 | if (a[i] == j) return true; 24 | return false; 25 | } 26 | }; 27 | int n; 28 | List *adj; 29 | public: 30 | AdjacencyLists(int n0); 31 | virtual ~AdjacencyLists(); 32 | void addEdge(int i, int j) { 33 | adj[i].add(j); 34 | } 35 | 36 | bool hasEdge(int i, int j) { 37 | return adj[i].contains(j); 38 | } 39 | 40 | template 41 | void inEdges(int i, LisT &edges) { 42 | for (int j = 0; j < n; j++) 43 | if (adj[j].contains(i)) edges.add(j); 44 | } 45 | 46 | int nVertices() { 47 | return n; 48 | } 49 | 50 | template 51 | void outEdges(int i, LisT &edges) { 52 | for (int k = 0; k < adj[i].size(); k++) 53 | edges.add(adj[i].get(k)); 54 | } 55 | 56 | void removeEdge(int i, int j) { 57 | for (int k = 0; k < adj[i].size(); k++) { 58 | if (adj[i].get(k) == j) { 59 | adj[i].remove(k); 60 | return; 61 | } 62 | } 63 | } 64 | 65 | }; 66 | 67 | } /* namespace ods */ 68 | #endif /* ADJACENCYLISTS_H_ */ 69 | -------------------------------------------------------------------------------- /python/ods/tests/listtest.py: -------------------------------------------------------------------------------- 1 | """For testing the functionality of list implementations""" 2 | import random 3 | 4 | from nose.tools import * 5 | from ods import ControlList 6 | 7 | def list_cmp(l1, l2): 8 | assert(l1 == l2) 9 | assert(list(l1) == list(l2)) 10 | assert(len(l1) == len(l2)) 11 | for i in range(len(l1)): 12 | assert(l1.get(i) == l2.get(i)) 13 | 14 | def exercise_list(ell=None): 15 | l1 = [ell, ControlList()][ell is None] 16 | l2 = ControlList() 17 | random.seed(5) 18 | n = 100 19 | for i in range(5): 20 | if i == 2: 21 | l1.clear() 22 | l2.clear() 23 | for _ in range(n): 24 | x = random.random(); 25 | i = random.randrange(0, len(l1)+1) 26 | l1.add(i, x) 27 | l2.add(i, x) 28 | list_cmp(l1, l2) 29 | for _ in range(5*n): 30 | op = random.randrange(0,3) 31 | if (op == 0): 32 | i = random.randrange(0, len(l1)+1) 33 | x = random.random(); 34 | l1.add(i, x) 35 | l2.add(i, x) 36 | elif op == 1: 37 | i = random.randrange(0, len(l1)) 38 | x = random.random(); 39 | l1.set(i,x) 40 | l2.set(i,x) 41 | else: 42 | i = random.randrange(0, len(l1)) 43 | l1.remove(i) 44 | l2.remove(i) 45 | list_cmp(l1, l2) 46 | 47 | -------------------------------------------------------------------------------- /python/ods/adjacencylists.py: -------------------------------------------------------------------------------- 1 | """An implementation of the adjacency list representation of a graph""" 2 | from .arraystack import ArrayStack 3 | from .utils import new_array 4 | 5 | length = len 6 | 7 | class AdjacencyLists(object): 8 | def __init__(self, n): 9 | self.n = n 10 | self._initialize() 11 | 12 | def _initialize(self): 13 | self.adj = new_array(self.n) 14 | for i in range(self.n): 15 | self.adj[i] = ArrayStack() 16 | 17 | def add_edge(self, i, j): 18 | self.adj[i].append(j) 19 | 20 | def remove_edge(self, i, j): 21 | for k in range(length(self.adj[i])): 22 | if self.adj[i].get(k) == j: 23 | self.adj[i].remove(k) 24 | return 25 | 26 | def has_edge(self, i, j): 27 | for k in self.adj[i]: 28 | if k == j: 29 | return True 30 | return False 31 | 32 | def out_edges(self, i): 33 | return self.adj[i] 34 | 35 | def out_degree(self, i): 36 | return len(self.adj[i]) 37 | 38 | def in_edges(self, i): 39 | out = ArrayStack() 40 | for j in range(self.n): 41 | if self.has_edge(j, i): out.append(j) 42 | return out 43 | 44 | def in_degree(self, i): 45 | deg = 0 46 | for j in range(self.n): 47 | if self.has_edge(j, i): deg += 1 48 | return deg 49 | 50 | -------------------------------------------------------------------------------- /latex/rebuilding.tex: -------------------------------------------------------------------------------- 1 | \chapter{Partial Rebuilding} 2 | 3 | 4 | In other chapters, we have seen structures that obtain their efficiency 5 | through the use of \emph{global rebuilding}: Occasionally, the entire 6 | structure is rebuilt in a ``balanced'' manner. The best example of 7 | this are the array-based list implementations of \chapref{X}. In these 8 | implementations, a new backing array is allocated (of appropriate size) 9 | and all the elements in the old backing array arec copied into the new 10 | backing array. 11 | 12 | In this chapter, we consider structures that maintain their efficiency 13 | through the use of \emph{partial rebuilding}. In applications of this 14 | technique, only parts of the data structure are rebuilt. 15 | 16 | \chapter{ScapegoatTree: A binary tree with partial rebuilding} 17 | 18 | A #ScapegoatTree# is a binary search tree that, in addition to storing 19 | a reference #root# to the root node, store the number #n# of nodes in 20 | the tree and another number #q# that is an overestimate of the number 21 | of nodes in the tree. At all times, two invariants are maintained. 22 | The first invariant ensures that #q# is a reasonable estimate of #n#: 23 | \[ #n# \le #q# \le 2#n# \enspace . \] 24 | The second invariant ensures that the height of the tree is small 25 | \[ 26 | \mbox{height} \le \log_{3/2} q 27 | \] 28 | 29 | 30 | 31 | \chaplabel{scapegoat} 32 | \chapter{Jumplist: Randomized Partial Rebuilding} 33 | \chapter{KDTree: Multidimensional search trees} 34 | 35 | 36 | \chaplabel{jumplists} 37 | 38 | 39 | -------------------------------------------------------------------------------- /python/ods/fastarraystack.py: -------------------------------------------------------------------------------- 1 | ''' 2 | An array-based list implementation with O(1+n-i) amortized update time. 3 | 4 | Stores the list in an array, a, so that the i'th list item is stored 5 | at a[(j+i)%len(a)]. 6 | 7 | Uses a doubling strategy for resizing a when it becomes full or too empty. 8 | ''' 9 | from .utils import new_array 10 | 11 | from .base import BaseList 12 | 13 | class FastArrayStack(BaseList): 14 | def __init__(self, iterable=[]): 15 | self._initialize() 16 | self.add_all(iterable) 17 | 18 | def _initialize(self): 19 | self.a = new_array(1) 20 | self.n = 0 21 | 22 | def get(self, i): 23 | if i < 0 or i >= self.n: raise IndexError() 24 | return self.a[i] 25 | 26 | def set(self, i, x): 27 | if i < 0 or i >= self.n: raise IndexError() 28 | y = self.a[i] 29 | self.a[i] = x 30 | return y 31 | 32 | def add(self, i, x): 33 | if i < 0 or i > self.n: raise IndexError() 34 | if self.n == len(self.a): self._resize() 35 | self.a[i+1:self.n+1] = self.a[i:self.n] 36 | self.a[i] = x 37 | self.n += 1 38 | 39 | def remove(self, i): 40 | if i < 0 or i >= self.n: raise IndexError() 41 | x = self.a[i] 42 | self.a[i:self.n-1] = self.a[i+1:self.n] 43 | self.n -= 1 44 | if len(self.a) >= 3*self.n: self._resize() 45 | return x 46 | 47 | def _resize(self): 48 | b = new_array(max(1, 2*self.n)) 49 | b[0:self.n] = self.a[0:self.n] 50 | self.a = b 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /java/ods/USetMap.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.AbstractMap; 4 | import java.util.Map; 5 | import java.util.Set; 6 | 7 | public class USetMap extends AbstractMap { 8 | /** 9 | * FIXME: Doesn't have the same equals() and hashCode() 10 | * that the API demands 11 | * @author morin 12 | */ 13 | protected class Entry implements Map.Entry { 14 | K k; 15 | V v; 16 | public Entry(K k, V v) { 17 | this.k = k; 18 | this.v = v; 19 | } 20 | public boolean equals(Entry x) { 21 | return x.k.equals(k); 22 | } 23 | public int hashCode() { 24 | return k.hashCode(); 25 | } 26 | @Override 27 | public K getKey() { 28 | return k; 29 | } 30 | @Override 31 | public V getValue() { 32 | return v; 33 | } 34 | @Override 35 | public V setValue(V value) { 36 | return v = value; 37 | } 38 | } 39 | 40 | protected USet> s; 41 | 42 | public USetMap(USet> s) { 43 | this.s = s; 44 | } 45 | 46 | public V put(K k, V v) { 47 | Entry p = new Entry(k, v); 48 | Map.Entry q = s.remove(p); 49 | s.add(p); 50 | return q == null ? null : q.getValue(); 51 | } 52 | 53 | @SuppressWarnings("unchecked") 54 | public V remove(Object k) { 55 | Map.Entry p = s.remove(new Entry((K)k, null)); 56 | return p == null ? null : p.getValue(); 57 | } 58 | 59 | @SuppressWarnings("unchecked") 60 | public boolean containsKey(Object k) { 61 | return s.find(new Entry((K)k, null)) != null; 62 | } 63 | 64 | public int size() { 65 | return s.size(); 66 | } 67 | 68 | public Set> entrySet() { 69 | return new USetSet>(s); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /python/ods/__init__.py: -------------------------------------------------------------------------------- 1 | # Array-based lists 2 | from .arraydeque import ArrayDeque 3 | from .arrayqueue import ArrayQueue 4 | from .arraystack import ArrayStack 5 | from .fastarraystack import FastArrayStack 6 | from .dualarraydeque import DualArrayDeque 7 | from .rootisharraystack import RootishArrayStack 8 | 9 | # Linked lists 10 | from .sllist import SLList 11 | from .dllist import DLList 12 | from .selist import SEList 13 | from .skiplistlist import SkiplistList 14 | 15 | # Hash tables 16 | from .chainedhashtable import ChainedHashTable 17 | from .linearhashtable import LinearHashTable 18 | 19 | # Binary tree 20 | from .binarytree import BinaryTree 21 | 22 | # Comparison-based SSets 23 | from .skiplistsset import SkiplistSSet 24 | from .binarysearchtree import BinarySearchTree 25 | from .redblacktree import RedBlackTree 26 | from .scapegoattree import ScapegoatTree 27 | from .treap import Treap 28 | 29 | # Priority queues 30 | from .binaryheap import BinaryHeap 31 | from .meldableheap import MeldableHeap 32 | 33 | # Dumb as a bag of hammers data structures used for testing 34 | from .controllist import ControlList 35 | from .controlsset import ControlSSet 36 | 37 | # Sorting algorithms 38 | from .algorithms import ( 39 | merge_sort, 40 | quick_sort, 41 | heap_sort, 42 | counting_sort, 43 | radix_sort, 44 | ) 45 | 46 | # Graphs 47 | from .adjacencymatrix import AdjacencyMatrix 48 | from .adjacencylists import AdjacencyLists 49 | 50 | # Integer data structures 51 | from .binarytrie import BinaryTrie 52 | from .xfasttrie import XFastTrie 53 | from .yfasttrie import YFastTrie 54 | 55 | # External memory data structures 56 | from .btree import BTree, BlockStore # fixme, don't need blockstore 57 | 58 | -------------------------------------------------------------------------------- /c/Makefile: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # # 3 | # OPEN DATA STRUCTURES in C (libodsc) # 4 | # # 5 | ################################################################################ 6 | 7 | # 8 | # Name of the library 9 | # 10 | LIB = libodsc 11 | 12 | # 13 | # C compiler 14 | # 15 | # Replace this with c89, cc, clang, or whatever. ODSC conforms to ANSI C (C89) 16 | # specifications. Make sure to check COMPILE and SHARED_LIB variables to match 17 | # the arguments of your compiler. 18 | # 19 | CC = gcc 20 | 21 | # 22 | # Arguments to force ANSI specs. I only use this to make sure the code complies 23 | # with ANSI C specs. 24 | # 25 | ifeq ($(ansi),true) 26 | ANSI_ARGS = -ansi -pedantic -Wall -Werror 27 | endif 28 | 29 | # 30 | # Compile arguments 31 | # 32 | # Runs for each file in src/. $@ is the output (.o), $< is the input (.c) 33 | # 34 | COMPILE = $(CC) $(ANSI_ARGS) -fpic -I include/ -c -o $@ $< 35 | 36 | # 37 | # Shared library arguments 38 | # 39 | SHARED_LIB = $(CC) -shared -o $(LIB).so $^ -lm 40 | 41 | # 42 | # Shared library install directory 43 | # 44 | INSDIR = /usr/lib 45 | 46 | OBJ = arraystack.o arrayqueue.o arraydeque.o dualarraydeque.o \ 47 | rootisharraystack.o sllist.o dllist.o selist.o skiplistsset.o skiplist.o \ 48 | chainedhashtable.o binarysearchtree.o 49 | 50 | lib: $(OBJ) 51 | $(SHARED_LIB) 52 | 53 | install: lib 54 | mv $(LIB).so $(INSDIR)/$(LIB).so && rm -f *.o 55 | 56 | %.o: src/%.c 57 | $(COMPILE) 58 | 59 | clean: 60 | rm -f *.o *.so *.a a.out 61 | -------------------------------------------------------------------------------- /java/ods/Treap.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.Comparator; 4 | import java.util.Random; 5 | 6 | 7 | public class Treap extends 8 | BinarySearchTree, T> implements SSet { 9 | /** 10 | * A random number source 11 | */ 12 | Random rand; 13 | 14 | protected static class Node extends BinarySearchTree.BSTNode,T> { 15 | int p; 16 | } 17 | 18 | public Treap(Comparator c) { 19 | super(new Node(), c); 20 | rand = new Random(); 21 | } 22 | 23 | public Treap() { 24 | this(new DefaultComparator()); 25 | } 26 | 27 | public boolean add(T x) { 28 | Node u = newNode(); 29 | u.x = x; 30 | u.p = rand.nextInt(); 31 | if (super.add(u)) { 32 | bubbleUp(u); 33 | return true; 34 | } 35 | return false; 36 | } 37 | 38 | protected void bubbleUp(Node u) { 39 | while (u.parent != nil && u.parent.p > u.p) { 40 | if (u.parent.right == u) { 41 | rotateLeft(u.parent); 42 | } else { 43 | rotateRight(u.parent); 44 | } 45 | } 46 | if (u.parent == nil) { 47 | r = u; 48 | } 49 | } 50 | 51 | public boolean remove(T x) { 52 | Node u = findLast(x); 53 | if (u != nil && c.compare(u.x, x) == 0) { 54 | trickleDown(u); 55 | splice(u); 56 | return true; 57 | } 58 | return false; 59 | } 60 | 61 | /** 62 | * Do rotations to make u a leaf 63 | */ 64 | protected void trickleDown(Node u) { 65 | while (u.left != nil || u.right != nil) { 66 | if (u.left == nil) { 67 | rotateLeft(u); 68 | } else if (u.right == nil) { 69 | rotateRight(u); 70 | } else if (u.left.p < u.right.p) { 71 | rotateRight(u); 72 | } else { 73 | rotateLeft(u); 74 | } 75 | if (r == u) { 76 | r = u.parent; 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | latex/ contains the latex sources 2 | java/ods contains the java sources 3 | cpp contains the C++ sources (still under development) 4 | 5 | To make the books (ods-java.pdf and ods-cpp.pdf and ods-python.pdf): 6 | mkdir ~/texmf/tex/latex/ods/ 7 | cp ods-colors.sty ~/texmf/tex/latex/ods/ 8 | cd latex ; make 9 | This will require a decent installation of pdflatex, perl, ipe, inkscape, 10 | gnuplot, and pdftk. 11 | 12 | If you have problems with tikz figures, consult the solution here: 13 | http://goo.gl/hCvlyp 14 | 15 | If ipetoipe generates errors about ods-colors.sty, then try this: 16 | 17 | mkdir -p ~textmf/tex/latex/ods/ 18 | ln -s $PWD/latex/ods-colors.sty ~textmf/tex/latex/ods/ 19 | texhash 20 | 21 | 22 | To make the Java archive ods.jar: 23 | cd java ; make 24 | 25 | To make both: 26 | make 27 | 28 | What's in here: 29 | java/test - Test code from Sun/Oracle and Apache 30 | java/junk - Small sample code snippets used in the text 31 | java/ods - The Java data structures sources 32 | cpp - The C++ data structures sources and sample code 33 | python - The Python code used to generate the pseudocode version 34 | python/tests - Unit tests for the Python code 35 | latex - The book's latex source code and scripts 36 | latex/figs - The book's ipe figures 37 | latex/images - Images used in the book 38 | 39 | 40 | How it works: 41 | The Makefile and Perl script in ./latex do the following: 42 | 1. Convert ipe figures in ./latex/figs into pdf 43 | 2. Convert svg figures in ./latex/images into pdf 44 | 3. Scan the latex sources and generate -java.tex and -cpp.tex files 45 | that include source code from ./java and ./cpp directories 46 | 4. Run pdflatex and bibtex to generate the file ods-java.pdf and 47 | ods-cpp.pdf 48 | 49 | -------------------------------------------------------------------------------- /cpp/SLList.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SLList.h 3 | * 4 | * Created on: 2011-11-25 5 | * Author: morin 6 | * FIXME: This code is completely untested (but was ported from tested Java code) 7 | */ 8 | 9 | #ifndef SLLIST_H_ 10 | #define SLLIST_H_ 11 | #include 12 | 13 | namespace ods { 14 | 15 | template 16 | class SLList { 17 | T null; 18 | protected: 19 | class Node { 20 | public: 21 | T x; 22 | Node *next; 23 | Node(T x0) { 24 | x = x0; 25 | next = NULL; 26 | } 27 | }; 28 | Node *head; 29 | Node *tail; 30 | int n; 31 | 32 | public: 33 | 34 | SLList() { 35 | null = (T)NULL; 36 | n = 0; 37 | head = tail = NULL; 38 | } 39 | 40 | virtual ~SLList() { 41 | Node *u = head; 42 | while (u != NULL) { 43 | Node *w = u; 44 | u = u->next; 45 | delete w; 46 | } 47 | } 48 | 49 | int size() { 50 | return n; 51 | } 52 | 53 | T peek() { 54 | return head->x; 55 | } 56 | 57 | bool add(T x) { 58 | Node *u = new Node(x); 59 | if (n == 0) { 60 | head = u; 61 | } else { 62 | tail->next = u; 63 | } 64 | tail = u; 65 | n++; 66 | return true; 67 | } 68 | 69 | T push(T x) { 70 | Node *u = new Node(x); 71 | u->next = head; 72 | head = u; 73 | if (n == 0) 74 | tail = u; 75 | n++; 76 | return x; 77 | } 78 | 79 | T remove() { 80 | if (n == 0) return null; 81 | T x = head->x; 82 | Node *u = head; 83 | head = head->next; 84 | delete u; 85 | if (--n == 0) tail = NULL; 86 | return x; 87 | } 88 | 89 | T pop() { 90 | if (n == 0) return null; 91 | T x = head->x; 92 | Node *u = head; 93 | head = head->next; 94 | delete u; 95 | if (--n == 0) tail = NULL; 96 | return x; 97 | } 98 | 99 | 100 | }; 101 | 102 | } /* namespace ods */ 103 | #endif /* SLLIST_H_ */ 104 | -------------------------------------------------------------------------------- /java/ods/BlockStore.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * This class fakes an external memory block storage system. It's actually implemented as 8 | * a list of blocks. 9 | * @author morin 10 | * 11 | * @param 12 | */ 13 | class BlockStore { 14 | 15 | /** 16 | * A list of blocks 17 | */ 18 | List blocks; 19 | 20 | /** 21 | * A list if available block indices (indices into the blocks list) 22 | */ 23 | List free; 24 | 25 | /** 26 | * Initialise a BlockStore with block size b 27 | * @param b the block size 28 | * @param clz needed so that we can allocate arrays of type T 29 | */ 30 | public BlockStore() { 31 | blocks = new ArrayList(); 32 | free = new ArrayList(); 33 | } 34 | 35 | public void clear() { 36 | blocks.clear(); 37 | free.clear(); 38 | } 39 | 40 | /** 41 | * Allocate a new block and return its index 42 | * @return the index of the newly allocated block 43 | */ 44 | public int placeBlock(T block) { 45 | int i; 46 | if (!free.isEmpty()) { 47 | i = free.remove(free.size()); 48 | blocks.set(i, block); 49 | } else { 50 | i = blocks.size(); 51 | blocks.add(i, block); 52 | } 53 | return i; 54 | } 55 | 56 | /** 57 | * Free a block, adding its index to the free list 58 | * @param i the block index to free 59 | */ 60 | public void freeBlock(int i) { 61 | blocks.set(i, null); 62 | free.add(i); 63 | } 64 | 65 | /** 66 | * Read a block 67 | * @param i the index of the block to read 68 | * @return the block 69 | */ 70 | public T readBlock(int i) { 71 | return blocks.get(i); 72 | } 73 | 74 | /** 75 | * Write a block 76 | * @param i the index of the block 77 | * @param block the block 78 | */ 79 | public void writeBlock(int i, T block) { 80 | blocks.set(i, block); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /java/ods/AdjacencyMatrix.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * This class represents a directed graph with no parallel edges 8 | * 9 | * @author morin 10 | * 11 | */ 12 | public class AdjacencyMatrix implements Graph { 13 | protected int n; 14 | protected boolean[][] a; 15 | 16 | /** 17 | * Create a new adjacency matrix with n vertices 18 | * @param n 19 | */ 20 | public AdjacencyMatrix(int n0) { 21 | n = n0; 22 | a = new boolean[n][n]; 23 | } 24 | 25 | public void addEdge(int i, int j) { 26 | a[i][j] = true; 27 | } 28 | 29 | public void removeEdge(int i, int j) { 30 | a[i][j] = false; 31 | } 32 | 33 | public boolean hasEdge(int i, int j) { 34 | return a[i][j]; 35 | } 36 | 37 | public List outEdges(int i) { 38 | List edges = new ArrayList(); 39 | for (int j = 0; j < n; j++) 40 | if (a[i][j]) edges.add(j); 41 | return edges; 42 | } 43 | 44 | public List inEdges(int i) { 45 | List edges = new ArrayList(); 46 | for (int j = 0; j < n; j++) 47 | if (a[j][i]) edges.add(j); 48 | return edges; 49 | } 50 | 51 | public int inDegree(int i) { 52 | int deg = 0; 53 | for (int j = 0; i < n; i++) 54 | if (a[j][i]) deg++; 55 | return deg; 56 | } 57 | 58 | public int outDegree(int i) { 59 | int deg = 0; 60 | for (int j = 0; i < n; i++) 61 | if (a[i][j]) deg++; 62 | return deg; 63 | } 64 | 65 | public int nVertices() { 66 | return n; 67 | } 68 | 69 | public static void main(String[] args) { 70 | for (int n = 10; n < 500; n *= 2) { 71 | Graph am = new AdjacencyMatrix(n); 72 | Graph al = new AdjacencyLists(n); 73 | System.out.print("Running tests on graphs of size " + n + "..."); 74 | System.out.flush(); 75 | Testum.graphTests(am, al); 76 | System.out.println("done"); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /java/ods/MultiplicativeHashSet.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.AbstractSet; 4 | import java.util.Iterator; 5 | import java.util.Set; 6 | 7 | public class MultiplicativeHashSet extends AbstractSet { 8 | /** 9 | * The underlying hash table 10 | */ 11 | HashTable tab; 12 | 13 | public MultiplicativeHashSet() { 14 | tab = new HashTable(); 15 | } 16 | 17 | protected MultiplicativeHashSet(HashTable tab) { 18 | this.tab = tab; 19 | } 20 | 21 | /** 22 | * Return true iff this hash table contains an object y such 23 | * that x.equals(y) 24 | */ 25 | public boolean contains(Object x) { 26 | return tab.find(x) != null; 27 | } 28 | 29 | public boolean add(T x) { 30 | if (contains(x)) { 31 | return false; 32 | } else { 33 | return tab.add(x); 34 | } 35 | } 36 | 37 | public boolean remove(Object x) { 38 | return tab.remove(x); 39 | } 40 | 41 | public Iterator iterator() { 42 | return tab.iterator(); 43 | } 44 | 45 | public int size() { 46 | return tab.size(); 47 | } 48 | 49 | public static void main(String[] args) { 50 | int n = 100002; 51 | Set t = new MultiplicativeHashSet(); 52 | for (int i = 0; i < n; i++) { 53 | t.add(i*2); 54 | } 55 | for (int i = 0; i < 2*n; i++) { 56 | if (i % 2 == 0) { 57 | assert(t.contains(i)); 58 | } else { 59 | assert(!t.contains(i)); 60 | } 61 | } 62 | for (int i = 0; i < n/2; i++) { 63 | t.remove(i*4); 64 | } 65 | for (int i = 0; i < 2*n; i++) { 66 | if (i % 4 == 2) { 67 | assert(t.contains(i)); 68 | } else { 69 | assert(!t.contains(i)); 70 | } 71 | } 72 | boolean[] checked = new boolean[2*n]; 73 | for (Integer x : t) { 74 | assert(checked[x] == false); 75 | checked[x] = true; 76 | } 77 | for (int i = 0; i < 2*n; i++) { 78 | if (i % 4 == 2) { 79 | assert(checked[i] == true); 80 | } else { 81 | assert(checked[i] == false); 82 | } 83 | } 84 | 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /java/ods/AdjacencyLists.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | public class AdjacencyLists implements Graph { 7 | int n; 8 | 9 | List[] adj; 10 | 11 | @SuppressWarnings("unchecked") 12 | public AdjacencyLists(int n0) { 13 | n = n0; 14 | adj = (List[])new List[n]; 15 | for (int i = 0; i < n; i++) 16 | adj[i] = new ArrayStack(Integer.class); 17 | } 18 | 19 | public void addEdge(int i, int j) { 20 | adj[i].add(j); 21 | } 22 | 23 | public boolean hasEdge(int i, int j) { 24 | return adj[i].contains(j); 25 | } 26 | 27 | public int inDegree(int i) { 28 | int deg = 0; 29 | for (int j = 0; j < n; j++) 30 | if (adj[j].contains(i)) deg++; 31 | return deg; 32 | } 33 | 34 | public List inEdges(int i) { 35 | List edges = new ArrayStack(Integer.class); 36 | for (int j = 0; j < n; j++) 37 | if (adj[j].contains(i)) edges.add(j); 38 | return edges; 39 | } 40 | 41 | public int nVertices() { 42 | return n; 43 | } 44 | 45 | public int outDegree(int i) { 46 | return adj[i].size(); 47 | } 48 | 49 | public List outEdges(int i) { 50 | return adj[i]; 51 | } 52 | 53 | public void removeEdge(int i, int j) { 54 | Iterator it = adj[i].iterator(); 55 | while (it.hasNext()) { 56 | if (it.next() == j) { 57 | it.remove(); 58 | return; 59 | } 60 | } 61 | } 62 | 63 | public static Graph mesh(int n) { 64 | Graph g = new AdjacencyLists(n*n); 65 | for (int k = 0; k < n*n; k++) { 66 | if (k % n > 0) 67 | g.addEdge(k, k-1); 68 | if (k >= n) 69 | g.addEdge(k, k-n); 70 | if (k % n != n-1) 71 | g.addEdge(k, k+1); 72 | if (k < n*(n-1)) 73 | g.addEdge(k, k+n); 74 | } 75 | return g; 76 | } 77 | 78 | public static void main(String[] args) { 79 | Graph g = mesh(4); 80 | Algorithms.bfsZ(g,0); 81 | Algorithms.dfsZ(g,0); 82 | Algorithms.dfs2Z(g,0); 83 | 84 | AdjacencyMatrix.main(args); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /cpp/FastSqrt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FastSqrt.h 3 | * 4 | * Created on: 2011-11-25 5 | * Author: morin 6 | */ 7 | 8 | #ifndef FASTSQRT_H_ 9 | #define FASTSQRT_H_ 10 | 11 | namespace ods { 12 | 13 | static int *sqrtab; 14 | static int *logtab; 15 | 16 | class FastSqrt { 17 | protected: 18 | static const int halfint = 1<<16; 19 | static const int r = 29; 20 | 21 | /** 22 | * Initialize the logarithm and square root tables 23 | */ 24 | static void inittabs(int dummy) { 25 | sqrtab = new int[halfint]; 26 | logtab = new int[halfint]; 27 | for (int d = 0; d < 16; d++) 28 | for (int k = 0; k < 1<= halfint) 54 | return 16 + logtab[x>>16]; 55 | return logtab[x]; 56 | } 57 | 58 | static int sqrt(int x) { 59 | int rp = log(x); 60 | int upgrade = ((r-rp)/2) * 2; 61 | int xp = x << upgrade; // xp has r or r-1 bits 62 | int s = sqrtab[xp>>(r/2)] >> (upgrade/2); 63 | while ((s+1)*(s+1) <= x) s++; // executes at most twice 64 | return s; 65 | } 66 | 67 | /* Fake code used only in the book 68 | int sqrt(int x, int r) { 69 | int s = sqrtab[x>>r/2]; 70 | while ((s+1)*(s+1) <= x) s++; // executes at most twice 71 | return s; 72 | } 73 | */ 74 | 75 | }; 76 | 77 | } /* namespace ods */ 78 | #endif /* FASTSQRT_H_ */ 79 | -------------------------------------------------------------------------------- /cpp/ArrayStack.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ArrayStack.h 3 | * 4 | * Created on: 2011-11-23 5 | * Author: morin 6 | */ 7 | 8 | #ifndef ARRAYSTACK_H_ 9 | #define ARRAYSTACK_H_ 10 | #include "array.h" 11 | #include "utils.h" 12 | 13 | namespace ods { 14 | 15 | template 16 | class DualArrayDeque; 17 | 18 | template 19 | class ArrayStack { 20 | protected: 21 | friend class DualArrayDeque; 22 | array a; 23 | int n; 24 | virtual void resize(); 25 | public: 26 | ArrayStack(); 27 | virtual ~ArrayStack(); 28 | int size(); 29 | T get(int i); 30 | T set(int i, T x); 31 | virtual void add(int i, T x); 32 | virtual void add(T x) { add(size(), x); } 33 | virtual T remove(int i); 34 | virtual void clear(); 35 | }; 36 | 37 | template inline 38 | int ArrayStack::size() { 39 | return n; 40 | } 41 | 42 | template inline 43 | T ArrayStack::get(int i) { 44 | return a[i]; 45 | } 46 | 47 | template inline 48 | T ArrayStack::set(int i, T x) { 49 | T y = a[i]; 50 | a[i] = x; 51 | return y; 52 | } 53 | 54 | template 55 | void ArrayStack::clear() { 56 | n = 0; 57 | array b(1); 58 | a = b; 59 | } 60 | 61 | template 62 | ArrayStack::ArrayStack() : a(1) { 63 | n = 0; 64 | } 65 | 66 | template 67 | ArrayStack::~ArrayStack() { 68 | } 69 | 70 | template 71 | void ArrayStack::resize() { 72 | array b(max(2 * n, 1)); 73 | for (int i = 0; i < n; i++) 74 | b[i] = a[i]; 75 | a = b; 76 | } 77 | 78 | template 79 | void ArrayStack::add(int i, T x) { 80 | if (n + 1 > a.length) resize(); 81 | for (int j = n; j > i; j--) 82 | a[j] = a[j - 1]; 83 | a[i] = x; 84 | n++; 85 | } 86 | 87 | template 88 | T ArrayStack::remove(int i) { 89 | T x = a[i]; 90 | for (int j = i; j < n - 1; j++) 91 | a[j] = a[j + 1]; 92 | n--; 93 | if (a.length >= 3 * n) resize(); 94 | return x; 95 | } 96 | 97 | } /* namespace ods */ 98 | 99 | #endif /* ARRAYSTACK_H_ */ 100 | -------------------------------------------------------------------------------- /python/ods/dllist.py: -------------------------------------------------------------------------------- 1 | """A doubly-linked list implementation with O(1+min{i, n-i}) update time""" 2 | from .base import BaseList 3 | 4 | class DLList(BaseList): 5 | 6 | class Node(object): 7 | def __init__(self, x): 8 | self.x = x 9 | self.next = None 10 | self.prev = None 11 | 12 | def __init__(self, iterable=[]): 13 | self._initialize() 14 | self.add_all(iterable) 15 | 16 | def _initialize(self): 17 | self.n = 0 18 | self.dummy = DLList.Node(None) 19 | self.dummy.prev = self.dummy 20 | self.dummy.next = self.dummy 21 | 22 | def get_node(self, i): 23 | if i < self.n/2: 24 | p = self.dummy.next 25 | for _ in range(i): 26 | p = p.next 27 | else: 28 | p = self.dummy 29 | for _ in range(self.n, i, -1): 30 | p = p.prev 31 | return p 32 | 33 | def get(self, i): 34 | if i < 0 or i >= self.n: raise IndexError() 35 | return self.get_node(i).x 36 | 37 | def set(self, i, x): #@ReservedAssignment 38 | if i < 0 or i >= self.n: raise IndexError() 39 | u = self.get_node(i) 40 | y = u.x 41 | u.x = x 42 | return y 43 | 44 | def _remove(self, w): 45 | w.prev.next = w.next 46 | w.next.prev = w.prev 47 | self.n -= 1 48 | 49 | def remove(self, i): 50 | if i < 0 or i >= self.n: raise IndexError() 51 | self._remove(self.get_node(i)) 52 | 53 | def add_before(self, w, x): 54 | u = DLList.Node(x) 55 | u.prev = w.prev 56 | u.next = w 57 | u.next.prev = u 58 | u.prev.next = u 59 | self.n += 1 60 | return u 61 | 62 | def add(self, i, x): 63 | if i < 0 or i > self.n: raise IndexError() 64 | self.add_before(self.get_node(i), x) 65 | 66 | def __iter__(self): 67 | u = self.dummy.next 68 | while u != self.dummy: 69 | yield u.x 70 | u = u.next 71 | 72 | -------------------------------------------------------------------------------- /python/ods/meldableheap.py: -------------------------------------------------------------------------------- 1 | """An implementation of Gambin and Malinowsky's randomized meldable heaps 2 | 3 | A. Gambin and A. Malinowski. Randomized meldable priority queues. 4 | Proceedings of the XXVth Seminar on Current Trends in Theory and Practice 5 | of Informatics (SOFSEM'98), pp. 344-349, 1998 6 | """ 7 | 8 | import random 9 | from .base import BaseSet 10 | from .binarytree import BinaryTree 11 | 12 | def random_bit(): 13 | return random.getrandbits(1) == 0 14 | 15 | class MeldableHeap(BinaryTree, BaseSet): 16 | class Node(BinaryTree.Node): 17 | def __init__(self, x): 18 | super(MeldableHeap.Node, self).__init__() 19 | self.x = x 20 | 21 | def __init__(self, iterable=[]): 22 | super(MeldableHeap, self).__init__() 23 | self.n = 0 24 | 25 | def _new_node(self, x): 26 | return MeldableHeap.Node(x) 27 | 28 | def find_min(self): 29 | if n == 0: raise IndexError('find_min on empty queue') 30 | return self.r.x 31 | 32 | def add(self, x): 33 | u = self._new_node(x) 34 | self.r = self.merge(u, self.r) 35 | self.r.parent = self.nil 36 | self.n += 1 37 | return True 38 | 39 | def remove(self): 40 | if self.n == 0: raise IndexError('remove from empty heap') 41 | x = self.r.x 42 | self.r = self.merge(self.r.left, self.r.right) 43 | if self.r != self.nil: self.r.parent = self.nil 44 | self.n -= 1 45 | return x 46 | 47 | def merge(self, h1, h2): 48 | if h1 == self.nil: return h2 49 | if h2 == self.nil: return h1 50 | if h2.x < h1.x: (h1, h2) = (h2, h1) 51 | if random_bit(): 52 | h1.left = self.merge(h1.left, h2) 53 | h1.left.parent = h1 54 | else: 55 | h1.right = self.merge(h1.right, h2) 56 | h1.right.parent = h1 57 | return h1 58 | 59 | def __iter__(self): 60 | u = self.first_node() 61 | while u != self.nil: 62 | yield u.x 63 | u = self.next_node(u) 64 | 65 | -------------------------------------------------------------------------------- /latex/latex2html-init: -------------------------------------------------------------------------------- 1 | 2 | $REUSE=0; # Fixes a problem with image reuse 3 | 4 | $HTML_VERSION = 4.0; 5 | $LOCAL_ICONS = 1; 6 | 7 | $DVIPSOPT = ' -E'; # remove -Ppdf flag 8 | # Force white background and black text 9 | $BODYTEXT = "text=\"\#000000\" bgcolor=\"\#FFFFFF\""; 10 | 11 | # This ensures that some figures do not end up with a grey background 12 | $WHITE_BACKGROUND = 1; 13 | # Tell LATEX: 14 | $LATEX_COLOR = "\\pagecolor{white}"; 15 | $STYLESHEET = '../ods-book.css'; 16 | 17 | $ACCENT_IMAGES = 1; 18 | 19 | $CONTENTS_IN_NAVIGATION = 1; 20 | $SHOW_SECTION_NUMBERS = 1; 21 | $TOC_DEPTH = 2; 22 | 23 | $MAX_SPLIT_DEPTH = -2; 24 | 25 | $NO_FOOTNODE = 1; 26 | $NUMBERED_FOOTNOTES = 1; 27 | 28 | $ADDRESS = <<'.END'; 29 | opendatastructures.org 30 | 42 | .END 43 | 44 | $EXTERNAL_UP_LINK = "http://opendatastructures.org/"; 45 | $EXTERNAL_UP_TITLE = "Open Data Structures"; 46 | 47 | # No mini tables of contents 48 | $MAX_LINK_DEPTH = 1; 49 | 50 | $INFO = <<'.END'; 51 |

52 | This document is released under a Creative 53 | Commons Attribution License (CC-BY). Visit opendatastructures.org for 55 | more information. 56 |

57 |

58 | This document was generated using latex2html and this process may 59 | have produced partially erroneous output, including missing figures, 60 | missing formulas, unnumbered figures, and broken links. The PDF files 61 | at opendatastructures.org 62 | are a more reliable source. 63 |

64 | .END 65 | 66 | $LONG_TITLES=10; 67 | 68 | -------------------------------------------------------------------------------- /python/ods/arraystack.py: -------------------------------------------------------------------------------- 1 | """Um ArrayStack implementa a interface de lista usando um array. 2 | 3 | Uma implementação de lista baseada em matriz com tempo de atualização 4 | amortizado de O(1 + n-i). 5 | 6 | Armazena a lista em uma matriz, a, de modo que o i-ésimo item da lista 7 | seja armazenado em a[(j+i)%len(a)]. 8 | 9 | Usa uma estratégia de duplicação para redimensionar a quando fica cheio 10 | ou muito vazio. 11 | """ 12 | from .utils import new_array 13 | 14 | from .base import BaseList 15 | 16 | 17 | class ArrayStack(BaseList): 18 | """Um ArrayStack implementa a interface de lista usando um array. 19 | 20 | Métodos Públicos: get(i), set(i, x), add(i, x), remove(i). 21 | """ 22 | 23 | def __init__(self, iterable=[]): 24 | """Inicializa ArrayStack. 25 | 26 | Args: iterable: lista de elementos (opcional) 27 | """ 28 | self._initialize() 29 | self.add_all(iterable) 30 | 31 | def _initialize(self): 32 | self.a = new_array(1) 33 | self.n = 0 34 | 35 | def get(self, i): 36 | """Devolve elemento na posição i.""" 37 | if i < 0 or i >= self.n: 38 | raise IndexError() 39 | return self.a[i] 40 | 41 | def set(self, i, x): 42 | """Atribui x à posição i.""" 43 | if i < 0 or i >= self.n: 44 | raise IndexError() 45 | y = self.a[i] 46 | self.a[i] = x 47 | return y 48 | 49 | def add(self, i, x): 50 | """Adiciona x na posição i, deslocando outros itens.""" 51 | if i < 0 or i > self.n: 52 | raise IndexError() 53 | if self.n == len(self.a): 54 | self._resize() 55 | self.a[i + 1 : self.n + 1] = self.a[i : self.n] 56 | self.a[i] = x 57 | self.n += 1 58 | 59 | def remove(self, i): 60 | if i < 0 or i >= self.n: raise IndexError() 61 | x = self.a[i] 62 | self.a[i:self.n-1] = self.a[i+1:self.n] 63 | self.n -= 1 64 | if len(self.a) >= 3*self.n: self._resize() 65 | return x 66 | 67 | def _resize(self): 68 | b = new_array(max(1, 2*self.n)) 69 | b[0:self.n] = self.a[0:self.n] 70 | self.a = b 71 | -------------------------------------------------------------------------------- /java/ods/SString.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | /** 4 | * This class represents a string that can be efficiently split and for which substrings 5 | * can be efficiently extracted 6 | * @author morin 7 | * 8 | */ 9 | public class SString { 10 | int i; // index of first character 11 | int m; // length 12 | byte[] data; // data 13 | 14 | public SString(String s) { 15 | data = s.getBytes(); 16 | i = 0; 17 | m = s.length(); 18 | } 19 | 20 | protected SString(byte[] data, int i, int m) { 21 | this.data = data; 22 | this.i = i; 23 | this.m = m; 24 | } 25 | 26 | /** 27 | * Truncate this SString so that its length is j and return a new SString 28 | * consisting the trailing m-j characters of the this SString 29 | * @param j 30 | * @return 31 | */ 32 | public SString split(int j) { 33 | if (j < 0 || j >= m) throw new IndexOutOfBoundsException(); 34 | SString s = new SString(data, i+j, m-j); 35 | this.m = j; 36 | return s; 37 | } 38 | 39 | /** 40 | * Return a new string consisting of characters j,...,m-1. 41 | * @param j 42 | * @return 43 | */ 44 | public SString suffix(int j) { 45 | if (j < 0 || j >= m) throw new IndexOutOfBoundsException(); 46 | return new SString(data, i+j, m-j); 47 | } 48 | 49 | /** 50 | * Return a new string consisting of characters 0,...,j-1 51 | * @param j 52 | * @return 53 | */ 54 | public SString prefix(int j) { 55 | if (j < 0 || j >= m) throw new IndexOutOfBoundsException(); 56 | return new SString(data, 0, j); 57 | } 58 | 59 | /** 60 | * Return a new string consisting of characters j,...,j+n-1 61 | * @param j 62 | * @param n 63 | * @return 64 | */ 65 | public SString subString(int j, int n) { 66 | if (j < 0 || j >= m) throw new IndexOutOfBoundsException(); 67 | if (n < 0 || j + n > m) throw new IndexOutOfBoundsException(); 68 | return new SString(data, i+j, n); 69 | } 70 | 71 | /** 72 | * The length of this string 73 | * @return 74 | */ 75 | public int length() { 76 | return m; 77 | } 78 | 79 | /** 80 | * Return the character at index j 81 | * @param j 82 | * @return 83 | */ 84 | public char charAt(int j) { 85 | return (char)data[i+j]; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /cpp/array.h: -------------------------------------------------------------------------------- 1 | /* 2 | * array.h 3 | * 4 | * Created on: 2011-11-24 5 | * Author: morin 6 | */ 7 | 8 | #ifndef ARRAY_H_ 9 | #define ARRAY_H_ 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | namespace ods { 17 | 18 | /** 19 | * A simple array class that simulates Java's arrays implementation - kind of 20 | * TODO: Make a reference-counted version so that the = operator doesn't have 21 | * to destroy its right-hand side. 22 | */ 23 | template 24 | class array { 25 | protected: 26 | T *a; 27 | public: 28 | int length; 29 | array(int len); 30 | array(int len, T init); 31 | void fill(T x); 32 | virtual ~array(); 33 | 34 | array& operator=(array &b) { 35 | if (a != NULL) delete[] a; 36 | a = b.a; 37 | b.a = NULL; 38 | length = b.length; 39 | return *this; 40 | } 41 | 42 | T& operator[](int i) { 43 | assert(i >= 0 && i < length); 44 | return a[i]; 45 | } 46 | 47 | T* operator+(int i) { 48 | return &a[i]; 49 | } 50 | 51 | void swap(int i, int j) { 52 | T x = a[i]; 53 | a[i] = a[j]; 54 | a[j] = x; 55 | } 56 | 57 | static void copyOfRange(array &a0, array &a, int i, int j); 58 | virtual void reverse(); 59 | }; 60 | 61 | template 62 | array::array(int len) { 63 | length = len; 64 | a = new T[length]; 65 | } 66 | 67 | template 68 | array::array(int len, T init) { 69 | length = len; 70 | a = new T[length]; 71 | for (int i = 0; i < length; i++) 72 | a[i] = init; 73 | } 74 | 75 | template 76 | array::~array() { 77 | if (a != NULL) delete[] a; 78 | } 79 | 80 | template 81 | void array::reverse() { 82 | for (int i = 0; i < length/2; i++) { 83 | swap(i, length-i-1); 84 | } 85 | } 86 | 87 | template 88 | void array::copyOfRange(array &a0, array &a, int i, int j) { 89 | array b(j-i); 90 | std::copy(a.a, a.a+j-i, b.a); 91 | a0 = b; 92 | } 93 | 94 | template 95 | void array::fill(T x) { 96 | std::fill(a, a+length, x); 97 | } 98 | 99 | 100 | } /* namespace ods */ 101 | #endif /* ARRAY_H_ */ 102 | -------------------------------------------------------------------------------- /python/ods/chainedhashtable.py: -------------------------------------------------------------------------------- 1 | """A Set implementation that uses hashing with chaining""" 2 | import random 3 | 4 | from .utils import new_array 5 | from .arraystack import ArrayStack 6 | from .base import BaseSet 7 | 8 | w = 32 9 | 10 | class ChainedHashTable(BaseSet): 11 | def __init__(self, iterable=[]): 12 | self._initialize() 13 | self.add_all(iterable) 14 | 15 | def _initialize(self): 16 | self.d = 1 17 | self.t = self._alloc_table((1<> (w-self.d) 44 | 45 | def add(self, x): 46 | if self.find(x) is not None: return False 47 | if self.n+1 > len(self.t): self._resize() 48 | self.t[self._hash(x)].append(x) 49 | self.n += 1 50 | return True 51 | 52 | def remove(self, x): 53 | ell = self.t[self._hash(x)] 54 | for y in ell: 55 | if y == x: 56 | ell.remove_value(y) 57 | self.n -= 1 58 | if 3*self.n < len(self.t): self._resize() 59 | return y 60 | return None 61 | 62 | def find(self, x): 63 | for y in self.t[self._hash(x)]: 64 | if y == x: 65 | return y 66 | return None 67 | 68 | def __iter__(self): 69 | for ell in self.t: 70 | for x in ell: 71 | yield x 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /python/ods/treap.py: -------------------------------------------------------------------------------- 1 | """An implementation of Treaps/Cartesian trees 2 | 3 | This is an implementation of the data structure called a Treap by Aragon 4 | and Seidel: 5 | 6 | C. R. Aragon and R. Seidel. Randomized Search Trees. In Algorithmica, 7 | Vol. 16, Number 4/5, pp. 464-497, 1996. 8 | 9 | Pretty-much the same structure was discovered earlier by Vuillemin: 10 | 11 | J. Vuillemin. A unifying look at data structures. 12 | Communications of the ACM, 23(4), 229-239, 1980. 13 | """ 14 | import random 15 | 16 | from .binarysearchtree import BinarySearchTree 17 | 18 | class Treap(BinarySearchTree): 19 | class Node(BinarySearchTree.Node): 20 | def __init__(self, x): 21 | super(Treap.Node, self).__init__(x) 22 | self.p = random.random() 23 | 24 | def __str__(self): 25 | return "[%r,%f]" % (self.x, self.p) 26 | 27 | def __init__(self, iterable=[]): 28 | super(Treap, self).__init__(iterable) 29 | 30 | def _new_node(self, x): 31 | return Treap.Node(x) 32 | 33 | def add(self, x): 34 | u = self._new_node(x) 35 | if self.add_node(u): 36 | self.bubble_up(u) 37 | return True 38 | return False 39 | 40 | def bubble_up(self, u): 41 | while u != self.r and u.parent.p > u.p: 42 | if u.parent.right == u: 43 | self.rotate_left(u.parent) 44 | else: 45 | self.rotate_right(u.parent) 46 | 47 | if u.parent == self.nil: 48 | self.r = u 49 | 50 | def remove(self, x): 51 | u = self._find_last(x) 52 | if u is not None and u.x == x: 53 | self.trickle_down(u) 54 | self.splice(u) 55 | return True 56 | return False 57 | 58 | def trickle_down(self, u): 59 | while u.left is not None or u.right is not None: 60 | if u.left is None: 61 | self.rotate_left(u) 62 | elif u.right is None: 63 | self.rotate_right(u) 64 | elif u.left.p < u.right.p: 65 | self.rotate_right(u) 66 | else: 67 | self.rotate_left(u) 68 | if self.r == u: 69 | self.r = u.parent 70 | 71 | -------------------------------------------------------------------------------- /python/ods/dualarraydeque.py: -------------------------------------------------------------------------------- 1 | ''' 2 | An array-based list implementation with O(1+min{i,n-i}) amortized update time. 3 | 4 | This running time is achieved by gluing together two ArrayStacks, 5 | called front and back, so that they are back to back. 6 | 7 | Items are redistributed even between front and back whenever one is more than 8 | three times the size of the other. 9 | ''' 10 | 11 | from .arraystack import ArrayStack 12 | 13 | from .base import BaseList 14 | 15 | class DualArrayDeque(BaseList): 16 | def __init__(self, iterable=[]): 17 | self._initialize() 18 | self.add_all(iterable) 19 | 20 | def _initialize(self): 21 | self.front = ArrayStack() 22 | self.back = ArrayStack() 23 | 24 | def get(self, i): 25 | if i < self.front.size(): 26 | return self.front.get(self.front.size()-i-1) 27 | else: 28 | return self.back.get(i-self.front.size()) 29 | 30 | def set(self, i, x): 31 | if i < self.front.size(): 32 | return self.front.set(self.front.size()-i-1, x) 33 | else: 34 | return self.back.set(i-self.front.size(), x) 35 | 36 | def add(self, i, x): 37 | if i < self.front.size(): 38 | self.front.add(self.front.size()-i, x) 39 | else: 40 | self.back.add(i-self.front.size(), x) 41 | self._balance() 42 | 43 | def remove(self, i): 44 | if i < self.front.size(): 45 | x = self.front.remove(self.front.size()-i-1) 46 | else: 47 | x = self.back.remove(i-self.front.size()) 48 | self._balance() 49 | return x 50 | 51 | def _balance(self): 52 | n = self.size() 53 | mid = n//2 54 | if 3*self.front.size() < self.back.size() or 3*self.back.size() < self.front.size(): 55 | f = ArrayStack() 56 | for i in range(mid): 57 | f.add(i, self.get(mid-i-1)) 58 | b = ArrayStack() 59 | for i in range(n-mid): 60 | b.add(i, self.get(mid+i)) 61 | self.front = f 62 | self.back = b 63 | 64 | def clear(self): 65 | self.front.clear() 66 | self.back.clear() 67 | 68 | def size(self): 69 | return self.front.size() + self.back.size() 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /python/ods/arraydeque.py: -------------------------------------------------------------------------------- 1 | ''' 2 | An array-based list implementation with O(1+min{i,n-i}) amortized update time. 3 | 4 | Stores the list in an array, a, so that the i'th list item is stored 5 | at a[(j+i)%len(a)]. 6 | 7 | Uses a doubling strategy for resizing a when it becomes full or too empty. 8 | ''' 9 | from .utils import new_array 10 | from .base import BaseList 11 | 12 | class ArrayDeque(BaseList): 13 | def __init__(self, iterable=[]): 14 | self._initialize() 15 | self.add_all(iterable) 16 | 17 | def _initialize(self): 18 | self.a = new_array(1) 19 | self.j = 0 20 | self.n = 0 21 | 22 | def get(self, i): 23 | if i < 0 or i >= self.n: raise IndexError() 24 | return self.a[(i+self.j)%len(self.a)] 25 | 26 | def set(self, i, x): 27 | if i < 0 or i >= self.n: raise IndexError() 28 | y = self.a[(i+self.j)%len(self.a)] 29 | self.a[(i+self.j)%len(self.a)] = x 30 | return y 31 | 32 | def add(self, i, x): 33 | if i < 0 or i > self.n: raise IndexError() 34 | if self.n == len(self.a): self._resize() 35 | if i < self.n/2: 36 | self.j = (self.j-1) % len(self.a) 37 | for k in range(i): 38 | self.a[(self.j+k)%len(self.a)] = self.a[(self.j+k+1)%len(self.a)] 39 | else: 40 | for k in range(self.n, i, -1): 41 | self.a[(self.j+k)%len(self.a)] = self.a[(self.j+k-1)%len(self.a)] 42 | self.a[(self.j+i)%len(self.a)] = x 43 | self.n += 1 44 | 45 | def remove(self, i): 46 | if i < 0 or i >= self.n: raise IndexError() 47 | x = self.a[(self.j+i)%len(self.a)] 48 | if i < self.n / 2: 49 | for k in range(i, 0, -1): 50 | self.a[(self.j+k)%len(self.a)] = self.a[(self.j+k-1)%len(self.a)] 51 | self.j = (self.j+1) % len(self.a) 52 | else: 53 | for k in range(i, self.n-1): 54 | self.a[(self.j+k)%len(self.a)] = self.a[(self.j+k+1)%len(self.a)] 55 | self.n -= 1 56 | if len(self.a) >= 3*self.n: self._resize() 57 | return x 58 | 59 | def _resize(self): 60 | b = new_array(max(1, 2*self.n)) 61 | for k in range(self.n): 62 | b[k] = self.a[(self.j+k)%len(self.a)] 63 | self.a = b 64 | self.j = 0 65 | 66 | 67 | -------------------------------------------------------------------------------- /cpp/YFastTrie.h: -------------------------------------------------------------------------------- 1 | /* 2 | * YFastTrie.h 3 | * 4 | * Created on: 2012-01-27 5 | * Author: morin 6 | */ 7 | 8 | #ifndef YFASTTRIE_H_ 9 | #define YFASTTRIE_H_ 10 | 11 | #include "Treap.h" 12 | #include "XFastTrie.h" 13 | 14 | namespace ods { 15 | 16 | 17 | /** 18 | * Warning YFastTrie depends on XFastTrie, so you can't use it to store 19 | * the values UINT_MAX-1 or UINT_MAX-2 20 | */ 21 | template 22 | class YPair { 23 | public: 24 | unsigned ix; 25 | Treap1 *t; 26 | YPair(unsigned ix0, Treap1 *t0) { ix = ix0; t = t0; } 27 | YPair(unsigned ix0) { ix = ix0; } 28 | YPair() { } 29 | }; 30 | 31 | 32 | template 33 | unsigned intValue(const YPair &p) { 34 | return p.ix; 35 | } 36 | 37 | 38 | template 39 | class YFastTrie { 40 | static const int w = 32; // FIXME portability 41 | XFastTrie1 > xft; 42 | int n; 43 | public: 44 | YFastTrie(); 45 | virtual ~YFastTrie(); 46 | T find(T x); 47 | bool add(T x); 48 | bool remove(T x); 49 | int size() { return n; } 50 | void clear() {} ; 51 | }; 52 | 53 | template 54 | YFastTrie::YFastTrie() : xft() { 55 | xft.add(YPair(UINT_MAX, new Treap1())); 56 | n = 0; 57 | } 58 | 59 | template 60 | YFastTrie::~YFastTrie() { 61 | /* FIXME: Need to iterate over the YFastTrie elements 62 | XFastTrieNode1 > *u = xft.dummy.next; 63 | while (u != &xft.dummy) { 64 | delete u->x.t; 65 | u = u->next; 66 | } 67 | */ 68 | xft.clear(); 69 | n = 0; 70 | } 71 | 72 | template 73 | T YFastTrie::find(T x) { 74 | return xft.find(YPair(intValue(x))).t->find(x); 75 | } 76 | 77 | template 78 | bool YFastTrie::add(T x) { 79 | unsigned ix = intValue(x); 80 | Treap1 *t = xft.find(YPair(ix)).t; 81 | if (t->add(x)) { 82 | n++; 83 | if (rand() % w == 0) { 84 | Treap1 *t1 = (Treap1*)t->split(x); 85 | xft.add(YPair(ix, t1)); 86 | } 87 | return true; 88 | } 89 | return false; 90 | return true; 91 | } 92 | 93 | template 94 | bool YFastTrie::remove(T x) { 95 | unsigned ix = intValue(x); 96 | XFastTrieNode1 > *u = xft.findNode(ix); 97 | bool ret = u->x.t->remove(x); 98 | if (ret) n--; 99 | if (u->x.ix == ix && ix != UINT_MAX) { 100 | Treap1 *t2 = u->child[1]->x.t; 101 | t2->absorb(*u->x.t); 102 | xft.remove(u->x); 103 | } 104 | return ret; 105 | } 106 | 107 | } /* namespace ods */ 108 | #endif /* YFASTTRIE_H_ */ 109 | -------------------------------------------------------------------------------- /python/ods/binaryheap.py: -------------------------------------------------------------------------------- 1 | """An implemnetation of a binary heap using an array""" 2 | from .utils import new_array 3 | from .base import BaseSet 4 | 5 | def left(i): 6 | return 2*i + 1 7 | 8 | def right(i): 9 | return 2*(i+1) 10 | 11 | def parent(i): 12 | return (i-1)//2 13 | 14 | class BinaryHeap(BaseSet): 15 | def __init__(self, iterable=[], a=None): 16 | if a: 17 | self._make_heap(a) 18 | else: 19 | self._initialize() 20 | self.add_all(iterable) 21 | 22 | def _make_heap(self, a): 23 | self.a = a 24 | self.n = len(a) 25 | for i in range(self.n//2-1, -1, -1): 26 | self.trickle_down(i) 27 | 28 | def _initialize(self): 29 | self.a = new_array(1) 30 | self.n = 0 31 | 32 | clear = _initialize 33 | 34 | def resize(self): 35 | b = new_array(max(2*self.n, 1)) 36 | for i in range(self.n): 37 | b[i] = self.a[i] 38 | self.a = b 39 | 40 | def add(self, x): 41 | if len(self.a) < self.n+1: 42 | self.resize() 43 | self.a[self.n] = x 44 | self.n += 1 45 | self.bubble_up(self.n-1) 46 | return True 47 | 48 | def bubble_up(self, i): 49 | p = parent(i) 50 | while i > 0 and self.a[i] < self.a[p]: 51 | self.a[i], self.a[p] = self.a[p], self.a[i] 52 | i = p 53 | p = parent(i) 54 | 55 | def remove(self): 56 | x = self.a[0] 57 | self.a[0] = self.a[self.n-1] 58 | self.n -= 1 59 | self.trickle_down(0) 60 | if 3*self.n < len(self.a): 61 | self.resize() 62 | return x 63 | 64 | def trickle_down(self, i): 65 | while i >= 0: 66 | j = -1 67 | r = right(i) 68 | if r < self.n and self.a[r] < self.a[i]: 69 | l = left(i) 70 | if self.a[l] < self.a[r]: 71 | j = l 72 | else: 73 | j = r 74 | else: 75 | l = left(i) 76 | if l < self.n and self.a[l] < self.a[i]: 77 | j = l 78 | if j >= 0: 79 | self.a[j], self.a[i] = self.a[i], self.a[j] 80 | i = j 81 | 82 | 83 | 84 | def find_min(self): 85 | if n == 0: raise IndexError() 86 | return a[0] 87 | 88 | def __iter__(self): 89 | for i in range(self.n): 90 | yield self.a[i] 91 | 92 | 93 | -------------------------------------------------------------------------------- /cpp/DLList.h: -------------------------------------------------------------------------------- 1 | /* 2 | * DLList.h 3 | * 4 | * Created on: 2011-11-24 5 | * Author: morin 6 | */ 7 | 8 | #ifndef DLLIST_H_ 9 | #define DLLIST_H_ 10 | 11 | namespace ods { 12 | 13 | template 14 | class DLList { 15 | protected: 16 | struct Node { 17 | T x; 18 | Node *prev, *next; 19 | }; 20 | Node dummy; 21 | int n; 22 | void remove(Node *w); 23 | Node* addBefore(Node *w, T x); 24 | Node* getNode(int i); 25 | public: 26 | DLList(); 27 | virtual ~DLList(); 28 | int size() { return n; } 29 | T get(int i); 30 | T set(int i, T x); 31 | virtual void add(int i, T x); 32 | virtual void add(T x) { add(size(), x); } 33 | virtual T remove(int i); 34 | virtual void clear(); 35 | }; 36 | 37 | template 38 | DLList::DLList() { 39 | dummy.next = &dummy; 40 | dummy.prev = &dummy; 41 | n = 0; 42 | } 43 | 44 | template 45 | typename DLList::Node* DLList::addBefore(Node *w, T x) { 46 | Node *u = new Node; 47 | u->x = x; 48 | u->prev = w->prev; 49 | u->next = w; 50 | u->next->prev = u; 51 | u->prev->next = u; 52 | n++; 53 | return u; 54 | } 55 | 56 | template 57 | typename DLList::Node* DLList::getNode(int i) { 58 | Node* p; 59 | if (i < n / 2) { 60 | p = dummy.next; 61 | for (int j = 0; j < i; j++) 62 | p = p->next; 63 | } else { 64 | p = &dummy; 65 | for (int j = n; j > i; j--) 66 | p = p->prev; 67 | } 68 | return (p); 69 | } 70 | 71 | 72 | template 73 | DLList::~DLList() { 74 | clear(); 75 | } 76 | 77 | template 78 | void DLList::clear() { 79 | Node *u = dummy.next; 80 | while (u != &dummy) { 81 | Node *w = u->next; 82 | delete u; 83 | u = w; 84 | } 85 | n = 0; 86 | } 87 | 88 | 89 | 90 | template 91 | void DLList::remove(Node *w) { 92 | w->prev->next = w->next; 93 | w->next->prev = w->prev; 94 | delete w; 95 | n--; 96 | } 97 | 98 | 99 | template 100 | T DLList::get(int i) { 101 | return getNode(i)->x; 102 | } 103 | 104 | template 105 | T DLList::set(int i, T x) { 106 | Node* u = getNode(i); 107 | T y = u->x; 108 | u->x = x; 109 | return y; 110 | } 111 | 112 | template 113 | void DLList::add(int i, T x) { 114 | addBefore(getNode(i), x); 115 | } 116 | 117 | template 118 | T DLList::remove(int i) { 119 | Node *w = getNode(i); 120 | T x = w->x; 121 | remove(w); 122 | return x; 123 | } 124 | 125 | 126 | } /* namespace ods */ 127 | #endif /* DLLIST_H_ */ 128 | -------------------------------------------------------------------------------- /cpp/ChainedHashTable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ChainedHashTable.h 3 | * 4 | * Created on: 2011-11-30 5 | * Author: morin 6 | */ 7 | 8 | #ifndef CHAINEDHASHTABLE_H_ 9 | #define CHAINEDHASHTABLE_H_ 10 | #include 11 | #include "utils.h" 12 | #include "array.h" 13 | #include "ArrayStack.h" 14 | 15 | namespace ods { 16 | 17 | template 18 | class ChainedHashTable { 19 | protected: 20 | typedef ArrayStack List; 21 | T null; 22 | array t; 23 | int n; 24 | int d; 25 | int z; 26 | static const int w = 32; //sizeof(int)*8; 27 | void resize(); 28 | int hash(T x) { 29 | return ((unsigned)(z * hashCode(x))) >> (w-d); 30 | } 31 | 32 | public: 33 | ChainedHashTable(); 34 | virtual ~ChainedHashTable(); 35 | bool add(T x); 36 | T remove(T x); 37 | T find(T x); 38 | int size() { 39 | return n; 40 | } 41 | void clear(); 42 | }; 43 | 44 | /** 45 | * FIXME: A copy-constructor for arrays would be useful here 46 | */ 47 | template 48 | void ChainedHashTable::resize() { 49 | d = 1; 50 | while (1< newTable(1< 62 | ChainedHashTable::ChainedHashTable() : t(2) { 63 | n = 0; 64 | d = 1; 65 | null = INT_MIN; 66 | z = rand() | 1; // is a random odd integer 67 | } 68 | 69 | 70 | 71 | template 72 | ChainedHashTable::~ChainedHashTable() { 73 | } 74 | 75 | 76 | template 77 | bool ChainedHashTable::add(T x) { 78 | if (find(x) != null) return false; 79 | if (n+1 > t.length) resize(); 80 | t[hash(x)].add(x); 81 | n++; 82 | return true; 83 | } 84 | 85 | 86 | template 87 | T ChainedHashTable::remove(T x) { 88 | int j = hash(x); 89 | for (int i = 0; i < t[j].size(); i++) { 90 | T y = t[j].get(i); 91 | if (x == y) { 92 | t[j].remove(i); 93 | n--; 94 | return y; 95 | } 96 | } 97 | return null; 98 | } 99 | 100 | 101 | template 102 | T ChainedHashTable::find(T x) { 103 | int j = hash(x); 104 | for (int i = 0; i < t[j].size(); i++) 105 | if (x == t[j].get(i)) 106 | return t[j].get(i); 107 | return null; 108 | } 109 | 110 | 111 | template 112 | void ChainedHashTable::clear() { 113 | n = 0; 114 | d = 1; 115 | array b(2); 116 | t = b; 117 | } 118 | 119 | } /* namespace ods */ 120 | #endif /* CHAINEDHASHTABLE_H_ */ 121 | -------------------------------------------------------------------------------- /cpp/ArrayDeque.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ArrayDeque.h 3 | * 4 | * Created on: 2011-11-23 5 | * Author: morin 6 | */ 7 | 8 | #ifndef ARRAYDEQUE_H_ 9 | #define ARRAYDEQUE_H_ 10 | #include "array.h" 11 | #include "utils.h" 12 | 13 | namespace ods { 14 | 15 | template 16 | class ArrayDeque { 17 | protected: 18 | array a; 19 | int j; 20 | int n; 21 | void resize(); 22 | public: 23 | ArrayDeque(); 24 | virtual ~ArrayDeque(); 25 | int size(); 26 | T get(int i); 27 | T set(int i, T x); 28 | virtual void add(int i, T x); 29 | virtual T remove(int i); 30 | virtual void clear(); 31 | }; 32 | 33 | template inline 34 | T ArrayDeque::get(int i) { 35 | return a[(j + i) % a.length]; 36 | } 37 | 38 | template inline 39 | T ArrayDeque::set(int i, T x) { 40 | T y = a[(j + i) % a.length]; 41 | a[(j + i) % a.length] = x; 42 | return y; 43 | } 44 | 45 | template 46 | void ArrayDeque::clear() { 47 | n = 0; 48 | j = 0; 49 | array b(1); 50 | a = b; 51 | } 52 | 53 | template 54 | ArrayDeque::ArrayDeque() : a(1) { 55 | n = 0; 56 | j = 0; 57 | } 58 | 59 | template 60 | ArrayDeque::~ArrayDeque() { 61 | } 62 | 63 | template 64 | void ArrayDeque::resize() { 65 | array b(max(1, 2*n)); 66 | for (int k = 0; k < n; k++) 67 | b[k] = a[(j+k)%a.length]; 68 | a = b; 69 | j = 0; 70 | } 71 | 72 | template 73 | int ArrayDeque::size() { 74 | return n; 75 | } 76 | 77 | template 78 | void ArrayDeque::add(int i, T x) { 79 | if (n + 1 > a.length) resize(); 80 | if (i < n/2) { // shift a[0],..,a[i-1] left one position 81 | j = (j == 0) ? a.length - 1 : j - 1; 82 | for (int k = 0; k <= i-1; k++) 83 | a[(j+k)%a.length] = a[(j+k+1)%a.length]; 84 | } else { // shift a[i],..,a[n-1] right one position 85 | for (int k = n; k > i; k--) 86 | a[(j+k)%a.length] = a[(j+k-1)%a.length]; 87 | } 88 | a[(j+i)%a.length] = x; 89 | n++; 90 | } 91 | 92 | template 93 | T ArrayDeque::remove(int i) { 94 | T x = a[(j+i)%a.length]; 95 | if (i < n/2) { // shift a[0],..,[i-1] right one position 96 | for (int k = i; k > 0; k--) 97 | a[(j+k)%a.length] = a[(j+k-1)%a.length]; 98 | j = (j + 1) % a.length; 99 | } else { // shift a[i+1],..,a[n-1] left one position 100 | for (int k = i; k < n-1; k++) 101 | a[(j+k)%a.length] = a[(j+k+1)%a.length]; 102 | } 103 | n--; 104 | if (3*n < a.length) resize(); 105 | return x; 106 | } 107 | 108 | } /* namespace ods */ 109 | 110 | 111 | #endif /* ARRAYDEQUE_H_ */ 112 | -------------------------------------------------------------------------------- /java/ods/SSet.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.Comparator; 4 | import java.util.Iterator; 5 | 6 | /** 7 | * The SSet interface is a simple interface that allows a class to implement 8 | * all the functionality of the (more complicated) SortedSet interface. Any 9 | * class that implements SSet can be wrapped in a SortedSSet to obtain an 10 | * implementation of SortedSet 11 | * 12 | * @author morin 13 | * 14 | * @param 15 | * @see SortedSSet 16 | */ 17 | public interface SSet extends Iterable { 18 | /** 19 | * @return the comparator used by this SSet 20 | */ 21 | public Comparator comparator(); 22 | 23 | /** 24 | * @return the number of elements in this SSet 25 | */ 26 | public int size(); 27 | 28 | /** 29 | * Find the smallest element in the SSet that is greater than or equal to x. 30 | * 31 | * @param x 32 | * @return the smallest element in the SSet that is greater than or equal to 33 | * x or null if no such element exists 34 | */ 35 | public T find(T x); 36 | 37 | /** 38 | * Find the smallest element in the SSet that is greater than or equal to x. 39 | * If x is null, return the smallest element in the SSet 40 | * 41 | * @param x 42 | * @return the smallest element in the SSet that is greater than or equal to 43 | * x or null if no such element exists. If x is null then the 44 | * smallest element in the SSet 45 | */ 46 | public T findGE(T x); 47 | 48 | /** 49 | * Find the largest element in the SSet that is greater than to x. If x is 50 | * null, return the largest element in the SSet 51 | * 52 | * @param x 53 | * @return the largest element in the SSet that is less than x. If x is null 54 | * then the smallest element in the SSet 55 | */ 56 | public T findLT(T x); 57 | 58 | /** 59 | * Add the element x to the SSet 60 | * 61 | * @param x 62 | * @return true if the element was added or false if x was already in the 63 | * set 64 | */ 65 | public boolean add(T x); 66 | 67 | /** 68 | * Remove the element x from the SSet 69 | * 70 | * @param x 71 | * @return true if x was removed and false if x was not removed (because x 72 | * was not present) 73 | */ 74 | public boolean remove(T x); 75 | 76 | /** 77 | * Clear the SSet, removing all elements from the set 78 | */ 79 | public void clear(); 80 | 81 | /** 82 | * Return an iterator that iterates over the elements in sorted order, 83 | * starting at the first element that is greater than or equal to x. 84 | */ 85 | public Iterator iterator(T x); 86 | } 87 | -------------------------------------------------------------------------------- /python/ods/rootisharraystack.py: -------------------------------------------------------------------------------- 1 | """ 2 | A list implementation with O(1+n-i) update time and O(sqrt(n)) wasted space 3 | 4 | Implements the List interface using a collection of arrays of sizes 5 | 1, 2, 3,..., and so on. The main advantage of this representation is that 6 | it uses only O(sqrt(n)) pointers and there are never more than O(sqrt(n)) 7 | unused array entries. 8 | 9 | This is an implementation of the (simpler) data structure described by 10 | Brodnik et al: 11 | 12 | Andrej Brodnik, Svante Carlsson, Erik D. Demaine, J. Ian Munro, 13 | Robert Sedgewick: Resizable Arrays in Optimal Time and Space. WADS 1999: 37-48 14 | """ 15 | from math import ceil, sqrt 16 | 17 | from .utils import new_array 18 | from .arraystack import ArrayStack 19 | from .base import BaseList 20 | 21 | class RootishArrayStack(BaseList): 22 | def __init__(self, iterable=[]): 23 | self._initialize() 24 | self.add_all(iterable) 25 | 26 | def _initialize(self): 27 | self.n = 0 28 | self.blocks = ArrayStack() 29 | 30 | def _i2b(self, i): 31 | return int(ceil((-3.0 + sqrt(9 + 8*i)) / 2.0)) 32 | 33 | def grow(self): 34 | self.blocks.append(new_array(self.blocks.size()+1)) 35 | 36 | def shrink(self): 37 | r = self.blocks.size() 38 | while r > 0 and (r-2)*(r-1)/2 >= self.n: 39 | self.blocks.remove(self.blocks.size()-1) 40 | r -= 1 41 | 42 | def get(self, i): 43 | if i < 0 or i > self.n - 1: raise IndexError() 44 | b = self._i2b(i) 45 | j = i - b*(b+1)/2 46 | return self.blocks.get(b)[j] 47 | 48 | def set(self, i, x): 49 | if i < 0 or i > self.n - 1: raise IndexError() 50 | b = self._i2b(i) 51 | j = i - b*(b+1)/2 52 | y = self.blocks.get(b)[j] 53 | self.blocks.get(b)[j] = x 54 | return y 55 | 56 | def add(self, i, x): 57 | if i < 0 or i > self.n: raise IndexError() 58 | r = self.blocks.size() 59 | if r*(r+1)/2 < self.n + 1: self.grow() 60 | self.n += 1 61 | for j in range(self.n-1, i, -1): 62 | self.set(j, self.get(j-1)) 63 | self.set(i, x) 64 | 65 | def remove(self, i): 66 | if i < 0 or i > self.n - 1: raise IndexError() 67 | x = self.get(i) 68 | for j in range(i, self.n-1): 69 | self.set(j, self.get(j+1)) 70 | self.n -= 1 71 | r = self.blocks.size() 72 | if (r-2)*(r-1)/2 >= self.n: self.shrink() 73 | return x 74 | 75 | def clear(self): 76 | self.blocks.clear() 77 | self.n = 0 78 | 79 | 80 | -------------------------------------------------------------------------------- /cpp/DualArrayDeque.h: -------------------------------------------------------------------------------- 1 | /* 2 | * DualArrayDeque.h 3 | * 4 | * Created on: 2011-11-23 5 | * Author: morin 6 | */ 7 | 8 | #ifndef DUALARRAYDEQUE_H_ 9 | #define DUALARRAYDEQUE_H_ 10 | #include "ArrayStack.h" 11 | 12 | namespace ods { 13 | 14 | template 15 | class DualArrayDeque { 16 | protected: 17 | ArrayStack front; 18 | ArrayStack back; 19 | void balance(); 20 | public: 21 | DualArrayDeque(); 22 | virtual ~DualArrayDeque(); 23 | int size(); 24 | T get(int i); 25 | T set(int i, T x); 26 | virtual void add(int i, T x); 27 | virtual T remove(int i); 28 | virtual void clear(); 29 | }; 30 | 31 | template inline 32 | T DualArrayDeque::get(int i) { 33 | if (i < front.size()) { 34 | return front.get(front.size() - i - 1); 35 | } else { 36 | return back.get(i - front.size()); 37 | } 38 | } 39 | 40 | template inline 41 | T DualArrayDeque::set(int i, T x) { 42 | if (i < front.size()) { 43 | return front.set(front.size() - i - 1, x); 44 | 45 | } else { 46 | return back.set(i - front.size(), x); 47 | } 48 | } 49 | 50 | template 51 | DualArrayDeque::DualArrayDeque() { 52 | } 53 | 54 | template 55 | DualArrayDeque::~DualArrayDeque() { 56 | } 57 | 58 | template 59 | int DualArrayDeque::size() { 60 | return front.size() + back.size(); 61 | } 62 | 63 | template 64 | void DualArrayDeque::add(int i, T x) { 65 | if (i < front.size()) { 66 | front.add(front.size() - i, x); 67 | } else { 68 | back.add(i - front.size(), x); 69 | } 70 | balance(); 71 | } 72 | 73 | template 74 | T DualArrayDeque::remove(int i) { 75 | T x; 76 | if (i < front.size()) { 77 | x = front.remove(front.size()-i-1); 78 | } else { 79 | x = back.remove(i-front.size()); 80 | } 81 | balance(); 82 | return x; 83 | } 84 | 85 | template 86 | void DualArrayDeque::balance() { 87 | if (3*front.size() < back.size() 88 | || 3*back.size() < front.size()) { 89 | int n = front.size() + back.size(); 90 | int nf = n/2; 91 | array af(max(2*nf, 1)); 92 | for (int i = 0; i < nf; i++) { 93 | af[nf-i-1] = get(i); 94 | } 95 | int nb = n - nf; 96 | array ab(max(2*nb, 1)); 97 | for (int i = 0; i < nb; i++) { 98 | ab[i] = get(nf+i); 99 | } 100 | front.a = af; 101 | front.n = nf; 102 | back.a = ab; 103 | back.n = nb; 104 | } 105 | } 106 | 107 | template 108 | void DualArrayDeque::clear() { 109 | front.clear(); 110 | back.clear(); 111 | } 112 | 113 | } /* namespace ods */ 114 | #endif /* DUALARRAYDEQUE_H_ */ 115 | -------------------------------------------------------------------------------- /cpp/RootishArrayStack.h: -------------------------------------------------------------------------------- 1 | /* 2 | * RootishArrayStack.h 3 | * 4 | * Created on: 2011-11-23 5 | * Author: morin 6 | */ 7 | 8 | #ifndef ROOTISHARRAYSTACK_H_ 9 | #define ROOTISHARRAYSTACK_H_ 10 | #include 11 | #include "ArrayStack.h" 12 | 13 | namespace ods { 14 | 15 | template 16 | class RootishArrayStack { 17 | protected: 18 | ArrayStack blocks; 19 | int n; 20 | 21 | int i2b(int i); 22 | void grow(); 23 | void shrink(); 24 | public: 25 | RootishArrayStack(); 26 | virtual ~RootishArrayStack(); 27 | int size(); 28 | T get(int i); 29 | T set(int i, T x); 30 | virtual void add(int i, T x); 31 | virtual T remove(int i); 32 | virtual void clear(); 33 | }; 34 | 35 | 36 | 37 | template inline 38 | int RootishArrayStack::size() { 39 | return n; 40 | } 41 | 42 | template inline 43 | T RootishArrayStack::get(int i) { 44 | int b = i2b(i); 45 | int j = i - b*(b+1)/2; 46 | return blocks.get(b)[j]; 47 | } 48 | 49 | template inline 50 | T RootishArrayStack::set(int i, T x) { 51 | int b = i2b(i); 52 | int j = i - b*(b+1)/2; 53 | T y = blocks.get(b)[j]; 54 | blocks.get(b)[j] = x; 55 | return y; 56 | } 57 | 58 | template inline 59 | int RootishArrayStack::i2b(int i) { 60 | double db = (-3.0 + sqrt(9 + 8*i)) / 2.0; 61 | int b = (int)ceil(db); 62 | return b; 63 | } 64 | 65 | template 66 | RootishArrayStack::RootishArrayStack() { 67 | n = 0; 68 | } 69 | 70 | template 71 | RootishArrayStack::~RootishArrayStack() { 72 | } 73 | 74 | template 75 | void RootishArrayStack::add(int i, T x) { 76 | int r = blocks.size(); 77 | if (r*(r+1)/2 < n + 1) grow(); 78 | n++; 79 | for (int j = n-1; j > i; j--) 80 | set(j, get(j-1)); 81 | set(i, x); 82 | } 83 | 84 | template 85 | T RootishArrayStack::remove(int i) { 86 | T x = get(i); 87 | for (int j = i; j < n-1; j++) 88 | set(j, get(j+1)); 89 | n--; 90 | int r = blocks.size(); 91 | if ((r-2)*(r-1)/2 >= n) shrink(); 92 | return x; 93 | } 94 | 95 | template 96 | void RootishArrayStack::grow() { 97 | blocks.add(blocks.size(), new T[blocks.size()+1]); 98 | } 99 | 100 | template 101 | void RootishArrayStack::shrink() { 102 | int r = blocks.size(); 103 | while (r > 0 && (r-2)*(r-1)/2 >= n) { 104 | delete [] blocks.remove(blocks.size()-1); 105 | r--; 106 | } 107 | } 108 | 109 | template 110 | void RootishArrayStack::clear() { 111 | while (blocks.size() > 0) { 112 | delete [] blocks.remove(blocks.size()-1); 113 | } 114 | } 115 | 116 | } /* namespace ods */ 117 | #endif /* ROOTISHARRAYSTACK_H_ */ 118 | -------------------------------------------------------------------------------- /latex/why-ptbr.tex: -------------------------------------------------------------------------------- 1 | \chapter*{Por que este Livro?} 2 | \addcontentsline{toc}{chapter}{Por que este Livro?} 3 | 4 | Há uma abundância de livros que ensinam estruturas introdutórias de dados. 5 | Alguns deles são muito bons. A maioria deles custa caro, e a grande 6 | maioria dos estudantes de graduação em ciência da computação 7 | desembolsará pelo menos algum dinheiro em um livro de estruturas 8 | de dados. 9 | 10 | Vários livros de código aberto de estruturas de dados estão disponíveis on-line. Alguns são muito bons, mas a maioria deles estão ficando velhos. A maioria desses livros tornaram-se gratuitos quando seus autores e/ou editores decidiram parar de atualizá-los. A atualização desses livros geralmente não é possível, por duas razões: (1)~O copyright pertence ao autor e/ou editor, qualquer um dos quais não pode permitir. (2)~O \emph{código fonte} para esses livros muitas vezes não está disponível. Ou seja, o Word, WordPerfect, FrameMaker ou fonte \LaTeX\ para o livro não está disponível, e até mesmo a versão do software que manipula essa fonte pode não estar disponível. 11 | 12 | O objetivo deste projeto é liberar estudantes de ciência da computação de graduação de ter que pagar por um livro introdutório de estruturas de dados. 13 | Decidi implementar este objetivo tratando este livro como um projeto de software Open Source 14 | \index{Open Source}. 15 | Os scripts do fonte em \LaTeX, fontes em \lang\ e de construção para o livro estão disponíveis para download no site do autor\footnote{\url{http://opendatastructures.org}} ou da versão em português\footnote{\url{https://www.araujo.eng.uerj.br/}}, e também, mais importante, em uma fonte confiável de gerenciamento de código.\footnote{\url{https://github.com/patmorin/ods}}\footnote{\url{https://github.com/jaraujouerj/Estruturas-de-Dados-Abertos}} 16 | 17 | O código-fonte no site é disponível sob uma licença Creative Commons Attribution, o que significa que qualquer pessoa é livre para \emph{compartilhar}, 18 | \index{share} para copiar, distribuir e transmitir a obra; e para \emph{remixar}: 19 | \index{remix} 20 | para adaptar o trabalho, incluindo o direito de fazer uso comercial da obra. A única condição para esses direitos é a \emph{atribuição}: você deve reconhecer que o trabalho derivado contém código e/ou texto de \url{opendatastructures.org}. 21 | 22 | Qualquer um pode contribuir com correções usando o sistema de gerenciamento de código-fonte \texttt{git}. 23 | \index{git@\texttt{git}} 24 | Qualquer pessoa pode também derivar fontes do livro para desenvolver uma versão separada (por exemplo, em outra linguagem de programação). 25 | Minha esperança é que, fazendo as coisas desta maneira, este livro continue a ser um livro de texto útil muito depois de terminar meu interesse no projeto, ou meu pulso (o que ocorrer primeiro). 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /cpp/MeldableHeap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MeldableHeap.h 3 | * 4 | * Created on: 2011-11-30 5 | * Author: morin 6 | */ 7 | 8 | #ifndef MELDABLEHEAP_H_ 9 | #define MELDABLEHEAP_H_ 10 | 11 | #include "BinaryTree.h" 12 | 13 | namespace ods { 14 | 15 | template class MeldableHeap; 16 | 17 | template 18 | class MHeapNode : public BTNode { 19 | public: 20 | T x; 21 | }; 22 | 23 | 24 | template 25 | class MeldableHeap: public BinaryTree { 26 | protected: 27 | using BinaryTree::r; 28 | using BinaryTree::nil; 29 | int n; 30 | Node *merge(Node *h1, Node *h2); 31 | public: 32 | MeldableHeap(); 33 | virtual ~MeldableHeap(); 34 | bool add(T x); 35 | T findMin(); 36 | T remove(); 37 | void remove(Node *u); 38 | int size() { 39 | return n; 40 | } 41 | }; 42 | 43 | template 44 | class MHeapNode1 : public MHeapNode, T> { }; 45 | 46 | template 47 | class MeldableHeap1 : public MeldableHeap, T> { }; 48 | 49 | 50 | template 51 | Node* MeldableHeap::merge(Node *h1, Node *h2) { 52 | if (h1 == nil) return h2; 53 | if (h2 == nil) return h1; 54 | if (compare(h1->x, h2->x) > 0) return merge(h2, h1); 55 | // now we know h1->x <= h2->x 56 | if (rand() % 2) { 57 | h1->left = merge(h1->left, h2); 58 | if (h1->left != nil) h1->left->parent = h1; 59 | } else { 60 | h1->right = merge(h1->right, h2); 61 | if (h1->right != nil) h1->right->parent = h1; 62 | } 63 | return h1; 64 | } 65 | 66 | template 67 | MeldableHeap::MeldableHeap() { 68 | n = 0; 69 | } 70 | 71 | template 72 | MeldableHeap::~MeldableHeap() { 73 | // nothing to do 74 | } 75 | 76 | template 77 | bool MeldableHeap::add(T x) { 78 | Node *u = new Node(); 79 | u->left = u->right = u->parent = nil; 80 | u->x = x; 81 | r = merge(u, r); 82 | r->parent = nil; 83 | n++; 84 | return true; 85 | } 86 | 87 | 88 | 89 | template 90 | T MeldableHeap::findMin() { 91 | return r->x; 92 | } 93 | 94 | 95 | 96 | template 97 | T MeldableHeap::remove() { 98 | T x = r->x; 99 | Node *tmp = r; 100 | r = merge(r->left, r->right); 101 | delete tmp; 102 | if (r != nil) r->parent = nil; 103 | n--; 104 | return x; 105 | } 106 | 107 | 108 | 109 | template 110 | void MeldableHeap::remove(Node *u) { 111 | if (u == r) { 112 | remove(); 113 | } else { 114 | if (u == u->parent->left) { 115 | u->parent->left = nil; 116 | } else { 117 | u->parent->right = nil; 118 | } 119 | u->parent = nil; 120 | r = merge(r, u->left); 121 | r = merge(r, u->right); 122 | r->parent = nil; 123 | n--; 124 | } 125 | } 126 | 127 | 128 | } /* namespace ods */ 129 | #endif /* MELDABLEHEAP_H_ */ 130 | -------------------------------------------------------------------------------- /cpp/BinaryHeap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * BinaryHeap.h 3 | * 4 | * Created on: 2011-11-30 5 | * Author: morin 6 | */ 7 | 8 | #ifndef BINARYHEAP_H_ 9 | #define BINARYHEAP_H_ 10 | 11 | #include 12 | #include "utils.h" 13 | #include "array.h" 14 | 15 | namespace ods { 16 | 17 | template 18 | class BinaryHeap { 19 | protected: 20 | array a; 21 | int n; 22 | void resize(); 23 | void bubbleUp(int i); 24 | void trickleDown(int i); 25 | static int left(int i) { 26 | return 2*i + 1; 27 | } 28 | static int right(int i) { 29 | return 2*i + 2; 30 | } 31 | static int parent(int i) { 32 | return (i-1)/2; 33 | } 34 | public: 35 | BinaryHeap(); 36 | BinaryHeap(array& b); 37 | virtual ~BinaryHeap(); 38 | bool add(T x); 39 | T findMin() { 40 | return a[0]; 41 | } 42 | T remove(); 43 | void clear(); 44 | int size() { 45 | return n; 46 | } 47 | static void sort(array &b); 48 | }; 49 | 50 | 51 | template 52 | void BinaryHeap::resize() { 53 | array b(max(2*n, 1)); 54 | std::copy(a+0, a+n, b+0); 55 | a = b; 56 | } 57 | 58 | template 59 | void BinaryHeap::sort(array &b) { 60 | BinaryHeap h(b); 61 | while (h.n > 1) { 62 | h.a.swap(--h.n, 0); 63 | h.trickleDown(0); 64 | } 65 | b = h.a; 66 | b.reverse(); 67 | } 68 | 69 | 70 | template 71 | bool BinaryHeap::add(T x) { 72 | if (n + 1 > a.length) resize(); 73 | a[n++] = x; 74 | bubbleUp(n-1); 75 | return true; 76 | } 77 | 78 | 79 | 80 | template 81 | void BinaryHeap::bubbleUp(int i) { 82 | int p = parent(i); 83 | while (i > 0 && compare(a[i], a[p]) < 0) { 84 | a.swap(i,p); 85 | i = p; 86 | p = parent(i); 87 | } 88 | } 89 | 90 | 91 | 92 | template 93 | T BinaryHeap::remove() { 94 | T x = a[0]; 95 | a[0] = a[--n]; 96 | trickleDown(0); 97 | if (3*n < a.length) resize(); 98 | return x; 99 | } 100 | 101 | 102 | 103 | template 104 | void BinaryHeap::trickleDown(int i) { 105 | do { 106 | int j = -1; 107 | int r = right(i); 108 | if (r < n && compare(a[r], a[i]) < 0) { 109 | int l = left(i); 110 | if (compare(a[l], a[r]) < 0) { 111 | j = l; 112 | } else { 113 | j = r; 114 | } 115 | } else { 116 | int l = left(i); 117 | if (l < n && compare(a[l], a[i]) < 0) { 118 | j = l; 119 | } 120 | } 121 | if (j >= 0) a.swap(i, j); 122 | i = j; 123 | } while (i >= 0); 124 | } 125 | 126 | 127 | 128 | template 129 | BinaryHeap::BinaryHeap() : a(1) { 130 | n = 0; 131 | } 132 | 133 | 134 | 135 | template 136 | BinaryHeap::BinaryHeap(array &b) : a(0) { 137 | a = b; 138 | n = a.length; 139 | for (int i = n/2-1; i >= 0; i--) { 140 | trickleDown(i); 141 | } 142 | } 143 | 144 | 145 | 146 | template 147 | BinaryHeap::~BinaryHeap() { 148 | // nothing to do 149 | } 150 | 151 | 152 | 153 | template 154 | void BinaryHeap::clear() { 155 | } 156 | 157 | } /* namespace ods */ 158 | #endif /* BINARYHEAP_H_ */ 159 | -------------------------------------------------------------------------------- /java/ods/ArrayDeque.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.AbstractList; 4 | 5 | /** 6 | * An implementation of the List interface that allows for fast modifications 7 | * at both the head and tail. 8 | * 9 | * The implementation is as a circular array. The List item of rank i is stored 10 | * at a[(j+i)%a.length]. Insertions and removals at position i take 11 | * O(1+min{i, size()-i}) amortized time. 12 | * @author morin 13 | * 14 | * @param the type of objects stored in this list 15 | * TODO: Implement addAll() and removeAll() efficiently 16 | */ 17 | public class ArrayDeque extends AbstractList { 18 | /** 19 | * The class of elements stored in this queue 20 | */ 21 | protected Factory f; 22 | 23 | /** 24 | * Array used to store elements 25 | */ 26 | protected T[] a; 27 | 28 | /** 29 | * Index of next element to de-queue 30 | */ 31 | protected int j; 32 | 33 | /** 34 | * Number of elements in the queue 35 | */ 36 | protected int n; 37 | 38 | /** 39 | * Grow the internal array 40 | */ 41 | protected void resize() { 42 | T[] b = f.newArray(Math.max(2*n,1)); 43 | for (int k = 0; k < n; k++) 44 | b[k] = a[(j+k) % a.length]; 45 | a = b; 46 | j = 0; 47 | } 48 | 49 | /** 50 | * Constructor 51 | */ 52 | public ArrayDeque(Class t) { 53 | f = new Factory(t); 54 | a = f.newArray(1); 55 | j = 0; 56 | n = 0; 57 | } 58 | 59 | public int size() { 60 | return n; 61 | } 62 | 63 | public T get(int i) { 64 | if (i < 0 || i > n-1) throw new IndexOutOfBoundsException(); 65 | return a[(j+i)%a.length]; 66 | } 67 | 68 | public T set(int i, T x) { 69 | if (i < 0 || i > n-1) throw new IndexOutOfBoundsException(); 70 | T y = a[(j+i)%a.length]; 71 | a[(j+i)%a.length] = x; 72 | return y; 73 | } 74 | 75 | public void add(int i, T x) { 76 | if (i < 0 || i > n) throw new IndexOutOfBoundsException(); 77 | if (n+1 > a.length) resize(); 78 | if (i < n/2) { // shift a[0],..,a[i-1] left one position 79 | j = (j == 0) ? a.length - 1 : j - 1; //(j-1)mod a.length 80 | for (int k = 0; k <= i-1; k++) 81 | a[(j+k)%a.length] = a[(j+k+1)%a.length]; 82 | } else { // shift a[i],..,a[n-1] right one position 83 | for (int k = n; k > i; k--) 84 | a[(j+k)%a.length] = a[(j+k-1)%a.length]; 85 | } 86 | a[(j+i)%a.length] = x; 87 | n++; 88 | } 89 | 90 | public T remove(int i) { 91 | if (i < 0 || i > n - 1) throw new IndexOutOfBoundsException(); 92 | T x = a[(j+i)%a.length]; 93 | if (i < n/2) { // shift a[0],..,[i-1] right one position 94 | for (int k = i; k > 0; k--) 95 | a[(j+k)%a.length] = a[(j+k-1)%a.length]; 96 | j = (j + 1) % a.length; 97 | } else { // shift a[i+1],..,a[n-1] left one position 98 | for (int k = i; k < n-1; k++) 99 | a[(j+k)%a.length] = a[(j+k+1)%a.length]; 100 | } 101 | n--; 102 | if (3*n < a.length) resize(); 103 | return x; 104 | } 105 | 106 | public void clear() { 107 | n = 0; 108 | resize(); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /java/ods/RootishArrayStack.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.AbstractList; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | /** 8 | * This class implements the List interface using a collection of arrays of 9 | * sizes 1, 2, 3, 4, and so on. The main advantages of this over an 10 | * implementation like ArrayList is that there is never more than O(sqrt(size()) 11 | * space being used to store anything other than the List elements themselves. 12 | * Insertions and removals take O(size() - i) amortized time. 13 | * 14 | * This provides a space-efficient implementation of an ArrayList. 15 | * The total space used beyond what is required to store elements is O(sqrt(n)) 16 | * @author morin 17 | * 18 | * @param the type of objects stored in this list 19 | */ 20 | public class RootishArrayStack extends AbstractList { 21 | /** 22 | * The type of objects stored in this list 23 | */ 24 | Factory f; 25 | 26 | /* 27 | * The blocks that contains the list elements 28 | */ 29 | List blocks; 30 | 31 | /** 32 | * The number of elements in the list 33 | */ 34 | int n; 35 | 36 | /** 37 | * Convert a list index i into a block number 38 | * @param i 39 | * @return the index of the block that contains list 40 | * element i 41 | */ 42 | protected static int i2b(int i) { 43 | double db = (-3.0 + Math.sqrt(9 + 8*i)) / 2.0; 44 | int b = (int)Math.ceil(db); 45 | return b; 46 | } 47 | 48 | protected void grow() { 49 | blocks.add(f.newArray(blocks.size()+1)); 50 | } 51 | 52 | protected void shrink() { 53 | int r = blocks.size(); 54 | while (r > 0 && (r-2)*(r-1)/2 >= n) { 55 | blocks.remove(blocks.size()-1); 56 | r--; 57 | } 58 | } 59 | 60 | public T get(int i) { 61 | if (i < 0 || i > n - 1) throw new IndexOutOfBoundsException(); 62 | int b = i2b(i); 63 | int j = i - b*(b+1)/2; 64 | return blocks.get(b)[j]; 65 | } 66 | 67 | public T set(int i, T x) { 68 | if (i < 0 || i > n - 1) throw new IndexOutOfBoundsException(); 69 | int b = i2b(i); 70 | int j = i - b*(b+1)/2; 71 | T y = blocks.get(b)[j]; 72 | blocks.get(b)[j] = x; 73 | return y; 74 | } 75 | 76 | public void add(int i, T x) { 77 | if (i < 0 || i > n) throw new IndexOutOfBoundsException(); 78 | int r = blocks.size(); 79 | if (r*(r+1)/2 < n + 1) grow(); 80 | n++; 81 | for (int j = n-1; j > i; j--) 82 | set(j, get(j-1)); 83 | set(i, x); 84 | } 85 | 86 | public T remove(int i) { 87 | if (i < 0 || i > n - 1) throw new IndexOutOfBoundsException(); 88 | T x = get(i); 89 | for (int j = i; j < n-1; j++) 90 | set(j, get(j+1)); 91 | n--; 92 | int r = blocks.size(); 93 | if ((r-2)*(r-1)/2 >= n) shrink(); 94 | return x; 95 | } 96 | 97 | public int size() { 98 | return n; 99 | } 100 | 101 | public RootishArrayStack(Class t) { 102 | f = new Factory(t); 103 | n = 0; 104 | blocks = new ArrayList(); 105 | } 106 | 107 | public void clear() { 108 | blocks.clear(); 109 | n = 0; 110 | } 111 | } 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /java/ods/SVGTreap.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.io.PrintStream; 4 | 5 | public class SVGTreap extends Treap { 6 | 7 | protected static double pagewidth=215.9; // 8.5 in 8 | protected static double pageheight=279.4; // 11 in 9 | protected static double width = 152.4; // 6 in 10 | protected static double height = 76.2; // 3 in 11 | protected static int maxp = 2000000000; 12 | 13 | protected double radius, thickness, xscale, yscale; 14 | 15 | protected static double min(double a, double b) { 16 | return a < b ? a : b; 17 | } 18 | public SVGTreap(int n) { 19 | super(); 20 | for (int i = 0; i < n; i++) { 21 | add(i); 22 | } 23 | radius = width / (3*n); 24 | thickness = radius / 3; 25 | xscale = width / n; 26 | yscale = 3*height / maxp; 27 | } 28 | 29 | public boolean add(Integer x) { 30 | Node u = new Node(); 31 | u.x = x; 32 | u.p = rand.nextInt(maxp); 33 | double tmp = Math.log(u.p); 34 | u.p = (int)((tmp / 22.) * maxp); 35 | if (super.add(u)) { 36 | bubbleUp(u); 37 | return true; 38 | } 39 | return false; 40 | } 41 | 42 | protected void draw(PrintStream s) { 43 | System.out.println(""); 44 | System.out.println(""); 46 | System.out.println(""); 47 | System.out.println(" "); 48 | Node u = firstNode(); 49 | while (u.left != null) u = u.left; 50 | while (u != null) { 51 | if (u != r) 52 | edge(s, getX(u.parent), getY(u.parent), getX(u), getY(u)); 53 | u = nextNode(u); 54 | } 55 | u = firstNode(); 56 | while (u.left != null) u = u.left; 57 | while (u != null) { 58 | node(s, getX(u), getY(u)); 59 | u = nextNode(u); 60 | } 61 | 62 | s.println(" "); 63 | s.println(""); 64 | 65 | } 66 | 67 | protected void node(PrintStream s, double x, double y) { 68 | s.print(" "); 69 | s.println(""); 74 | } 75 | 76 | protected void edge(PrintStream s, double x1, double y1, double x2, 77 | double y2) { 78 | s.print(" "); 79 | s.println(""); 82 | } 83 | 84 | protected void printIt(PrintStream s) { 85 | 86 | } 87 | 88 | protected double getX(Node u) { 89 | return u.x * xscale + (pagewidth-width)/2; 90 | } 91 | 92 | protected double getY(Node u) { 93 | return u.p * yscale + (pageheight-height)/2; 94 | } 95 | 96 | public static void main(String[] args) { 97 | int n = 100; 98 | if (args.length == 1) { 99 | n = Integer.parseInt(args[0]); 100 | } 101 | new SVGTreap(n).draw(System.out); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /java/ods/ArrayQueue.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.AbstractQueue; 4 | import java.util.Iterator; 5 | import java.util.NoSuchElementException; 6 | import java.util.Queue; 7 | 8 | /** 9 | * An implementation of the Queue interface using an array 10 | * 11 | * All operations takes constant amortized time. 12 | * @author morin 13 | * 14 | * @param 15 | */ 16 | public class ArrayQueue extends AbstractQueue { 17 | /** 18 | * The class of elements stored in this queue 19 | */ 20 | protected Factory f; 21 | 22 | /** 23 | * Array used to store elements 24 | */ 25 | protected T[] a; 26 | 27 | /** 28 | * Index of next element to de-queue 29 | */ 30 | protected int j; 31 | 32 | /** 33 | * Number of elements in the queue 34 | */ 35 | protected int n; 36 | 37 | /** 38 | * Grow the internal array 39 | */ 40 | protected void resize() { 41 | T[] b = f.newArray(Math.max(1,n*2)); 42 | for (int k = 0; k < n; k++) 43 | b[k] = a[(j+k) % a.length]; 44 | a = b; 45 | j = 0; 46 | } 47 | 48 | /** 49 | * Constructor 50 | */ 51 | public ArrayQueue(Class t) { 52 | f = new Factory(t); 53 | a = f.newArray(1); 54 | j = 0; 55 | n = 0; 56 | } 57 | 58 | /** 59 | * Return an iterator for the elements of the queue. 60 | * This iterator does not support the remove operation 61 | */ 62 | public Iterator iterator() { 63 | class QueueIterator implements Iterator { 64 | int k; 65 | 66 | public QueueIterator() { 67 | k = 0; 68 | } 69 | 70 | public boolean hasNext() { 71 | return (k < n); 72 | } 73 | 74 | public T next() { 75 | if (k > n) throw new NoSuchElementException(); 76 | T x = a[(j+k) % a.length]; 77 | k++; 78 | return x; 79 | } 80 | 81 | public void remove() { 82 | throw new UnsupportedOperationException(); 83 | } 84 | } 85 | return new QueueIterator(); 86 | } 87 | 88 | public int size() { 89 | return n; 90 | } 91 | 92 | public boolean offer(T x) { 93 | return add(x); 94 | } 95 | 96 | public boolean add(T x) { 97 | if (n + 1 > a.length) resize(); 98 | a[(j+n) % a.length] = x; 99 | n++; 100 | return true; 101 | } 102 | 103 | public T peek() { 104 | T x = null; 105 | if (n > 0) { 106 | x = a[j]; 107 | } 108 | return x; 109 | } 110 | 111 | public T remove() { 112 | if (n == 0) throw new NoSuchElementException(); 113 | T x = a[j]; 114 | j = (j + 1) % a.length; 115 | n--; 116 | if (a.length >= 3*n) resize(); 117 | return x; 118 | } 119 | 120 | public T poll() { 121 | return n == 0 ? null : remove(); 122 | } 123 | 124 | public static void main(String args[]) { 125 | int m = 10000, n = 50; 126 | Queue q = new ArrayQueue(Integer.class); 127 | for (int i = 0; i < m; i++) { 128 | q.add(new Integer(i)); 129 | if (q.size() > n) { 130 | Integer x = q.remove(); 131 | assert(x == i - n); 132 | } 133 | } 134 | Iterator i = q.iterator(); 135 | while (i.hasNext()) { 136 | System.out.println(i.next()); 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /python/ods/sllist.py: -------------------------------------------------------------------------------- 1 | """An implementation of a singly-linked list""" 2 | from .base import BaseList 3 | 4 | class SLList(BaseList): 5 | 6 | class Node(object): 7 | def __init__(self, x): 8 | self.x = x 9 | self.next = None 10 | 11 | def __init__(self, iterable=[]): 12 | self._initialize() 13 | self.add_all(iterable) 14 | 15 | def _initialize(self): 16 | self.n = 0 17 | self.head = None 18 | self.tail = None 19 | 20 | def new_node(self, x): 21 | return SLList.Node(x) 22 | 23 | def _add(self,x): 24 | u = self.new_node(x) 25 | if self.n == 0: 26 | self.head = u 27 | else: 28 | self.tail.next = u 29 | self.tail = u 30 | self.n += 1 31 | return True 32 | 33 | def push(self,x): 34 | u = self.new_node(x) 35 | u.next = self.head 36 | self.head = u 37 | if self.n == 0: 38 | self.tail = u 39 | self.n += 1 40 | return x 41 | 42 | def append(self, x): 43 | u = self.new_node(x) 44 | if self.n == 0: 45 | self.head = u 46 | else: 47 | self.tail.next = u 48 | self.tail = u 49 | self.n += 1 50 | return True 51 | 52 | def get_node(self, i): 53 | u = self.head 54 | for _ in range(i): 55 | u = u.next 56 | return u 57 | 58 | def get(self, i): 59 | if i < 0 or i > self.n-1: raise IndexError() 60 | return self.get_node(i).x 61 | 62 | def set(self, i, x): 63 | if i < 0 or i > self.n-1: raise IndexError() 64 | u = self.get_node(i) 65 | y, u.x = u.x, x 66 | return y 67 | 68 | def add(self, i, x): 69 | if i < 0 or i > self.n: raise IndexError() 70 | if i == 0: self.push(x); return True 71 | u = self.head 72 | for _ in range(i-1): 73 | u = u.next 74 | w = self.new_node(x) 75 | w.next = u.next 76 | u.next = w 77 | self.n += 1 78 | return True 79 | 80 | def remove(self, i): 81 | if i < 0 or i > self.n-1: raise IndexError() 82 | if i == 0: return self.pop() 83 | u = self.head 84 | for _ in range(i-1): 85 | u = u.next 86 | w = u.next 87 | u.next = u.next.next 88 | self.n -= 1 89 | return w.x 90 | 91 | def pop(self): 92 | if self.n == 0: return None 93 | x = self.head.x 94 | self.head = self.head.next 95 | self.n -= 1 96 | if self.n == 0: 97 | self.tail = None 98 | return x 99 | 100 | def _remove(self): 101 | return self.pop() 102 | 103 | def __str__(self): 104 | s = "[" 105 | u = self.head 106 | while u is not None: 107 | s += "%r" % u.x 108 | u = u.next 109 | if u is not None: 110 | s += "," 111 | return s + "]" 112 | 113 | def __len__(self): 114 | return self.size() 115 | 116 | -------------------------------------------------------------------------------- /java/ods/RangeSSet.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.Comparator; 4 | import java.util.Iterator; 5 | import java.util.NoSuchElementException; 6 | import java.util.SortedSet; 7 | 8 | /** 9 | * This represents a view of the part of a SortedSSet in the interval [a,b). 10 | * This implementation adds only a constant additive overhead to methods except 11 | * size(), which runs in linear time. 12 | * 13 | * @author morin 14 | * 15 | * @param 16 | */ 17 | public class RangeSSet extends SortedSSet { 18 | T a; 19 | T b; 20 | 21 | public RangeSSet(SSet s, T a, T b) { 22 | super(s); 23 | this.a = a; 24 | this.b = b; 25 | } 26 | 27 | public Iterator iterator() { 28 | class IT implements Iterator { 29 | protected Iterator it; 30 | T next, prev; 31 | 32 | public IT(Iterator it) { 33 | this.it = it; 34 | if (it.hasNext()) { 35 | next = it.next(); 36 | } 37 | } 38 | 39 | public boolean hasNext() { 40 | return next != null 41 | && (b == null || s.comparator().compare(next, b) < 0); 42 | } 43 | 44 | public T next() { 45 | if (!hasNext()) 46 | throw new NoSuchElementException(); 47 | prev = next; 48 | next = it.next(); 49 | return prev; 50 | } 51 | 52 | public void remove() { 53 | s.remove(prev); 54 | } 55 | } 56 | return new IT(s.iterator(a)); 57 | } 58 | 59 | @SuppressWarnings("unchecked") 60 | public boolean contains(Object o) { 61 | T x = (T) o; 62 | Comparator c = s.comparator(); 63 | if (a != null && c.compare(x, a) < 0) 64 | return false; 65 | if (b != null && c.compare(x, b) >= 0) 66 | return false; 67 | return super.contains(x); 68 | } 69 | 70 | public T first() { 71 | return s.findGE(a); 72 | } 73 | 74 | public int size() { 75 | Iterator it = iterator(); 76 | int n = 0; 77 | while (it.hasNext()) { 78 | it.next(); 79 | n++; 80 | } 81 | return n; 82 | } 83 | 84 | public T last() { 85 | return s.findLT(b); 86 | } 87 | 88 | protected final T max(T x, T y) { 89 | if (x == null) 90 | return y; 91 | if (y == null) 92 | return x; 93 | if (s.comparator().compare(x, y) > 0) 94 | return x; 95 | return y; 96 | } 97 | 98 | protected final T min(T x, T y) { 99 | if (x == null) 100 | return y; 101 | if (y == null) 102 | return x; 103 | if (s.comparator().compare(x, y) < 0) 104 | return x; 105 | return y; 106 | } 107 | 108 | protected final void rangeCheck(T x) { 109 | Comparator c = s.comparator(); 110 | if ((a != null && c.compare(x, a) < 0) 111 | || (b != null && c.compare(x, b) >= 0)) 112 | throw new IllegalArgumentException(); 113 | } 114 | 115 | public boolean add(T x) { 116 | rangeCheck(x); 117 | return super.add(x); 118 | } 119 | 120 | @SuppressWarnings("unchecked") 121 | public boolean remove(Object x) { 122 | rangeCheck((T) x); 123 | return super.remove(x); 124 | } 125 | 126 | public SortedSet subSet(T a, T b) { 127 | return new RangeSSet(s, max(a, this.a), min(b, this.b)); 128 | } 129 | 130 | public SortedSet headSet(T b) { 131 | return subSet(a, b); 132 | } 133 | 134 | public SortedSet tailSet(T a) { 135 | return subSet(a, b); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /python/ods/binarytree.py: -------------------------------------------------------------------------------- 1 | """A basic binary tree implementation""" 2 | 3 | from .arrayqueue import ArrayQueue 4 | 5 | class BinaryTree(object): 6 | class Node(object): 7 | def __init__(self): 8 | self.left = self.right = self.parent = None 9 | 10 | def __init__(self): 11 | super(BinaryTree, self).__init__() 12 | self.nil = None 13 | self.r = None 14 | self.initialize() 15 | 16 | def initialize(self): 17 | self.r = None 18 | 19 | def depth(self, u): 20 | d = 0 21 | while (u != self.r): 22 | u = u.parent 23 | d += 1 24 | return d 25 | 26 | def size(self): 27 | return self._size(self.r) 28 | 29 | def _size(self, u): 30 | if u == self.nil: return 0 31 | return 1 + self._size(u.left) + self._size(u.right) 32 | 33 | def size2(self): 34 | u = self.r 35 | prv = self.nil 36 | n = 0 37 | while u != self.nil: 38 | if prv == u.parent: 39 | n += 1 40 | if u.left != self.nil: nxt = u.left 41 | elif u.right != self.nil: nxt = u.right 42 | else: nxt = u.parent 43 | elif prv == u.left: 44 | if u.right != self.nil: nxt = u.right 45 | else: nxt = u.parent 46 | else: 47 | nxt = u.parent 48 | prv = u 49 | u = nxt 50 | return n 51 | 52 | def height(self): 53 | return self._height(self.r) 54 | 55 | def _height(self, u): 56 | if u == self.nil: return -1 57 | return 1 + max(self._height(u.left), self._height(u.right)) 58 | 59 | def traverse(self, u): 60 | if u == self.nil: return 61 | self.traverse(u.left) 62 | self.traverse(u.right) 63 | 64 | def traverse2(self): 65 | u = self.r 66 | prv = self.nil 67 | while u != self.nil: 68 | if prv == u.parent: 69 | if u.left != self.nil: nxt = u.left 70 | elif u.right != self.nil: nxt = u.right 71 | else: nxt = u.parent 72 | elif prv == u.left: 73 | if u.right != self.nil: nxt = u.right 74 | else: nxt = u.parent 75 | else: 76 | nxt = u.parent 77 | prv = u 78 | u = nxt 79 | 80 | def bf_traverse(self): 81 | q = ArrayQueue() 82 | if self.r != self.nil: q.add(self.r) 83 | while q.size() > 0: 84 | u = q.remove() 85 | if u.left != self.nil: q.add(u.left) 86 | if u.right != self.nil: q.add(u.right) 87 | 88 | def first_node(self): 89 | """Find the first node in an in-order traversal""" 90 | w = self.r 91 | if w == self.nil: return self.nil 92 | while w.left != self.nil: 93 | w = w.left 94 | return w 95 | 96 | def next_node(self, w): 97 | """Find the node that follows w in an in-order traversal""" 98 | if w.right != self.nil: 99 | w = w.right 100 | while w.left != self.nil: 101 | w = w.left 102 | else: 103 | while w.parent != self.nil and w.parent.left != w: 104 | w = w.parent 105 | w = w.parent 106 | return w 107 | 108 | 109 | -------------------------------------------------------------------------------- /python/ods/skiplistsset.py: -------------------------------------------------------------------------------- 1 | """An implementation of Pugh's skiplist data structure 2 | 3 | 4 | W. Pugh. Skip Lists: A probabilistic alternative to balanced trees. 5 | In Communications of the ACM, 33(6), pp. 668-676, June 1990. 6 | 7 | W. Pugh. A skip list cookbook. CS-TR-2286.1, University of Maryland, 8 | College Park, 1990. 9 | """ 10 | 11 | import random 12 | from .utils import new_array 13 | from .base import BaseSet 14 | 15 | class SkiplistSSet(BaseSet): 16 | class Node(object): 17 | """A node in a skip list""" 18 | def __init__(self, x, h): 19 | self.x = x 20 | self.next = new_array(h+1) 21 | 22 | def height(self): 23 | return len(self.next) - 1 24 | 25 | def _new_node(self, x, h): 26 | return SkiplistSSet.Node(x, h) 27 | 28 | def __init__(self, iterable=[]): 29 | self._initialize() 30 | self.add_all(iterable) 31 | 32 | def _initialize(self): 33 | self.h = 0 34 | self.n = 0 35 | self.sentinel = self._new_node(None, 32) 36 | self.stack = new_array(self.sentinel.height()+1) 37 | 38 | def clear(self): 39 | self._initialize() 40 | 41 | def find_pred_node(self, x): 42 | u = self.sentinel 43 | r = self.h 44 | while r >= 0: 45 | while u.next[r] is not None and u.next[r].x < x: 46 | u = u.next[r] # go right in list r 47 | r -= 1 # go down into list r-1 48 | return u 49 | 50 | def find(self, x): 51 | u = self.find_pred_node(x) 52 | if u.next[0] is None: return None 53 | return u.next[0].x 54 | 55 | def add(self, x): 56 | u = self.sentinel 57 | r = self.h 58 | while r >= 0: 59 | while u.next[r] is not None and u.next[r].x < x: 60 | u = u.next[r] 61 | if u.next[r] is not None and u.next[r].x == x: return False 62 | self.stack[r] = u 63 | r -= 1 64 | w = self._new_node(x, self.pick_height()) 65 | while self.h < w.height(): 66 | self.h += 1 67 | self.stack[self.h] = self.sentinel # height increased 68 | for i in range(len(w.next)): 69 | w.next[i] = self.stack[i].next[i] 70 | self.stack[i].next[i] = w 71 | self.n += 1 72 | return True 73 | 74 | def remove(self, x): 75 | removed = False 76 | u = self.sentinel 77 | r = self.h 78 | while r >= 0: 79 | while u.next[r] is not None and u.next[r].x < x: 80 | u = u.next[r] 81 | if u.next[r] is not None and u.next[r].x == x: 82 | removed = True 83 | u.next[r] = u.next[r].next[r] 84 | if u == self.sentinel and u.next[r] is None: 85 | self.h -= 1 # height has decreased 86 | r -= 1 87 | if removed: self.n -= 1 88 | return removed 89 | 90 | def __iter__(self): 91 | u = self.sentinel.next[0] 92 | while u is not None: 93 | yield u.x 94 | u = u.next[0] 95 | 96 | def __len__(self): 97 | return self.n 98 | 99 | def pick_height(self): 100 | z = random.getrandbits(32) 101 | k = 0 102 | while z & 1: 103 | k += 1 104 | z = z // 2 105 | return k 106 | 107 | -------------------------------------------------------------------------------- /java/ods/SortedSSet.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.AbstractSet; 4 | import java.util.ArrayList; 5 | import java.util.Collection; 6 | import java.util.Comparator; 7 | import java.util.Iterator; 8 | import java.util.SortedSet; 9 | 10 | /** 11 | * This class is a wrapper that allows any class that implements SSet to 12 | * allow it to also implement SortedSet. 13 | * 14 | * @author morin 15 | * 16 | * @param 17 | */ 18 | public class SortedSSet extends AbstractSet implements SortedSet { 19 | protected SSet s; 20 | 21 | public SortedSSet(SSet s) { 22 | this.s = s; 23 | } 24 | 25 | public Comparator comparator() { 26 | return s.comparator(); 27 | } 28 | 29 | public T first() { 30 | return s.findGE(null); 31 | } 32 | 33 | public T last() { 34 | return s.findLT(null); 35 | } 36 | 37 | public SortedSet headSet(T b) { 38 | return new RangeSSet(s, null, b); 39 | } 40 | 41 | public SortedSet subSet(T a, T b) { 42 | return new RangeSSet(s, a, b); 43 | } 44 | 45 | public SortedSet tailSet(T a) { 46 | return new RangeSSet(s, a, null); 47 | } 48 | 49 | public boolean add(T x) { 50 | return s.add(x); 51 | } 52 | 53 | public void clear() { 54 | s.clear(); 55 | } 56 | 57 | @SuppressWarnings("unchecked") 58 | public boolean contains(Object o) { 59 | T y = s.findGE((T) o); 60 | return y != null && y.equals(o); 61 | } 62 | 63 | public Iterator iterator() { 64 | return s.iterator(); 65 | } 66 | 67 | @SuppressWarnings("unchecked") 68 | public boolean remove(Object x) { 69 | return s.remove((T) x); 70 | } 71 | 72 | public int size() { 73 | return s.size(); 74 | } 75 | 76 | public boolean isEmpty() { 77 | return !s.iterator().hasNext(); 78 | } 79 | 80 | public static void main(String[] args) { 81 | int n = 500000; 82 | Collection> css = new ArrayList>(); 83 | // css.add(new SortedSSet(new ScapegoatTree())); 84 | // css.add(new SortedSSet(new ScapegoatTree2())); 85 | css.add(new SortedSSet(new Treap())); 86 | css.add(new java.util.TreeSet()); 87 | // css.add(new SortedSSet(new Treap())); 88 | css.add(new SortedSSet(new RedBlackTree())); 89 | css.add(new SortedSSet(new BTree(10,Integer.class))); 90 | css.add(new SortedSSet(new BTree(50,Integer.class))); 91 | css.add(new SortedSSet(new BTree(100,Integer.class))); 92 | // css.add(new SortedSSet(new ScapegoatTree())); 93 | // css.add(new SortedSSet(new SkiplistSSet())); 94 | { 95 | class N extends XFastTrie.Nöde,T> {}; 96 | class I implements Integerizer { 97 | public int intValue(Integer i) { return i; } 98 | } 99 | class BT extends BinaryTrie,T> { 100 | public BT(Integerizer it) { super(new N(), it); } 101 | }; 102 | class XFT extends XFastTrie,T> { 103 | public XFT(Integerizer it) { super(new N(), it); } 104 | }; 105 | css.add(new SortedSSet(new BT(new I()))); 106 | css.add(new SortedSSet(new XFT(new I()))); 107 | css.add(new SortedSSet(new YFastTrie(new I()))); 108 | } 109 | // css.add(new java.util.TreeSet()); 110 | for (SortedSet ss : css) { 111 | System.out.println("Testing sanity of " + Testum.s(ss)); 112 | Testum.sortedSetSanityTests(ss, 100); 113 | } 114 | Testum.sortedSetSpeedTests(css, n); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /java/ods/ArrayStack.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.AbstractList; 4 | import java.util.Collection; 5 | 6 | /** 7 | * This is a copy of the JCF class ArrayList. It implements the List 8 | * interface as a single array a. Elements are stored at positions 9 | * a[0],...,a[size()-1]. Doubling/halving is used to resize the array 10 | * a when necessary. 11 | * @author morin 12 | * 13 | * @param the type of objects stored in the List 14 | */ 15 | public class ArrayStack extends AbstractList { 16 | /** 17 | * keeps track of the class of objects we store 18 | */ 19 | Factory f; 20 | 21 | /** 22 | * The array used to store elements 23 | */ 24 | T[] a; 25 | 26 | /** 27 | * The number of elements stored 28 | */ 29 | int n; 30 | 31 | /** 32 | * Resize the internal array 33 | */ 34 | protected void resize() { 35 | T[] b = f.newArray(Math.max(n*2,1)); 36 | for (int i = 0; i < n; i++) { 37 | b[i] = a[i]; 38 | } 39 | a = b; 40 | } 41 | 42 | /** 43 | * Resize the internal array 44 | */ 45 | protected void resize(int nn) { 46 | T[] b = f.newArray(nn); 47 | for (int i = 0; i < n; i++) { 48 | b[i] = a[i]; 49 | } 50 | a = b; 51 | } 52 | 53 | /** 54 | * Constructor 55 | * @param t0 the type of objects that are stored in this list 56 | */ 57 | public ArrayStack(Class t) { 58 | f = new Factory(t); 59 | a = f.newArray(1); 60 | n = 0; 61 | } 62 | 63 | public T get(int i) { 64 | if (i < 0 || i > n - 1) throw new IndexOutOfBoundsException(); 65 | return a[i]; 66 | } 67 | 68 | public int size() { 69 | return n; 70 | } 71 | 72 | public T set(int i, T x) { 73 | if (i < 0 || i > n - 1) throw new IndexOutOfBoundsException(); 74 | T y = a[i]; 75 | a[i] = x; 76 | return y; 77 | } 78 | 79 | public void add(int i, T x) { 80 | if (i < 0 || i > n) throw new IndexOutOfBoundsException(); 81 | if (n + 1 > a.length) resize(); 82 | for (int j = n; j > i; j--) 83 | a[j] = a[j-1]; 84 | a[i] = x; 85 | n++; 86 | } 87 | 88 | public T remove(int i) { 89 | if (i < 0 || i > n - 1) throw new IndexOutOfBoundsException(); 90 | T x = a[i]; 91 | for (int j = i; j < n-1; j++) 92 | a[j] = a[j+1]; 93 | n--; 94 | if (a.length >= 3*n) resize(); 95 | return x; 96 | } 97 | 98 | // The following methods are not strictly necessary. The parent 99 | // class, AbstractList, has default implementations of them, but 100 | // our implementations are more efficient - especially addAll 101 | 102 | /** 103 | * A small optimization for a frequently used method 104 | */ 105 | public boolean add(T x) { 106 | if (n + 1 > a.length) resize(); 107 | a[n++] = x; 108 | return true; 109 | } 110 | 111 | /** 112 | * We override addAll because AbstractList implements it by 113 | * repeated calls to add(i,x), which can take time 114 | * O(size()*c.size()). This happens, for example, when i = 0. 115 | * This version takes time O(size() + c.size()). 116 | */ 117 | public boolean addAll(int i, Collection c) { 118 | if (i < 0 || i > n) throw new IndexOutOfBoundsException(); 119 | int k = c.size(); 120 | if (n + k > a.length) resize(2*(n+k)); 121 | for (int j = n+k-1; j >= i+k; j--) 122 | a[j] = a[j-k]; 123 | for (T x : c) 124 | a[i++] = x; 125 | n += k; 126 | return true; 127 | } 128 | 129 | /** 130 | * We override this method because AbstractList implements by 131 | * repeated calls to remove(size()), which takes O(size()) time. 132 | * This implementation runs in O(1) time. 133 | */ 134 | public void clear() { 135 | n = 0; 136 | resize(); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /c/include/sllist.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * File : sllist.h 3 | * Author(s) : Tekin Ozbek 4 | ******************************************************************************/ 5 | 6 | #ifndef ODS_SLLIST_H_ 7 | #define ODS_SLLIST_H_ 8 | 9 | #include 10 | 11 | #include 12 | 13 | #define sllist_dequeue(l, elem) \ 14 | sllist_pop((l), (elem)) 15 | 16 | typedef struct slnode_t { 17 | 18 | void* data; 19 | struct slnode_t* next; 20 | 21 | } slnode_t; 22 | 23 | typedef struct { 24 | 25 | size_t elem_size; 26 | size_t length; 27 | slnode_t* head; 28 | slnode_t* tail; 29 | 30 | } sllist_t; 31 | 32 | /* FUNCTION 33 | * sllist_dispose 34 | * 35 | * DESCRIPTION 36 | * Releases all memory allocated by other sllist_* functions. If you have 37 | * any pointer references to nodes, they will be invalid after a call to 38 | * this function. 39 | * 40 | * PARAMETERS 41 | * l A valid pointer to an initialized sllist_t struct. 42 | */ 43 | extern void sllist_dispose(sllist_t* l); 44 | 45 | /* FUNCTION 46 | * sllist_enqueue 47 | * 48 | * DESCRIPTION 49 | * Adds an element to the tail of the list. 50 | * 51 | * PARAMETERS 52 | * l A valid pointer to an initialized sllist_t struct. 53 | * elem Pointer to the element that will be inserted. Cannot be 54 | * null. 55 | */ 56 | extern void sllist_enqueue(sllist_t* l, 57 | void* elem); 58 | 59 | /* FUNCTION 60 | * sllist_init 61 | * 62 | * DESCRIPTION 63 | * Initializes an sllist_t struct. 64 | * 65 | * PARAMETERS 66 | * l A valid pointer to an sllist_t struct. 67 | * elem_size Size of the elements that will be stored in the list. 68 | */ 69 | extern void sllist_init(sllist_t* l, 70 | size_t elem_size); 71 | 72 | /* FUNCTION 73 | * sllist_iterator 74 | * 75 | * ITERABLE 76 | * FORWARD start <= end 77 | * 78 | * DESCRIPTION 79 | * Initializes an iterator_t for the specified range [start, end]. 80 | * 81 | * PARAMETERS 82 | * l A valid pointer to an initialized sllist_t struct. 83 | * it A valid pointer to an iterator_t struct. 84 | * start Start position (inclusive, must be less than length). 85 | * end End position (inclusive, must be less than length). 86 | */ 87 | extern void sllist_iterator(sllist_t* l, 88 | iterator_t* it, 89 | size_t start, 90 | size_t end); 91 | 92 | /* FUNCTION 93 | * sllist_pop (sllist_dequeue) 94 | * 95 | * DESCRIPTION 96 | * Pops an element from the head of the list. 97 | * 98 | * PARAMETERS 99 | * l A valid pointer to an initialized sllist_t struct. 100 | * elem_out If not null, the popped element will be copied into this 101 | * memory. 102 | */ 103 | extern void sllist_pop(sllist_t* l, 104 | void* elem_out); 105 | 106 | /* FUNCTION 107 | * sllist_push 108 | * 109 | * DESCRIPTION 110 | * Pushes an element to the head of the list. 111 | * 112 | * PARAMETERS 113 | * l A valid pointer to an initialized sllist_t struct. 114 | * elem Pointer to the element that will be inserted. Cannot be 115 | * null. 116 | */ 117 | extern void sllist_push(sllist_t* l, 118 | void* elem); 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /java/ods/FastSqrt.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * Implement square roots without relying on Math.sqrt(x) 7 | * @author morin 8 | * 9 | */ 10 | public class FastSqrt { 11 | protected static final int[] sqrtab; 12 | protected static final int[] logtab; 13 | protected static final int halfint = 1 << 16; 14 | 15 | static { 16 | sqrtab = new int[halfint]; 17 | logtab = new int[halfint]; 18 | for (int d = 0; d < 16; d++) 19 | Arrays.fill(logtab, 1<= halfint) 49 | return 16 + logtab[x>>>16]; 50 | return logtab[x]; 51 | } 52 | 53 | protected static final int r = 29; 54 | 55 | /** 56 | * Compute the floor of the square root of x 57 | * @param x 58 | * @return the floor of the square root of x 59 | */ 60 | public static final int sqrt(int x) { 61 | int rp = log(x); 62 | int upgrade = ((r-rp)/2) * 2; 63 | int xp = x << upgrade; // xp has r or r-1 bits 64 | int s = sqrtab[xp>>(r/2)] >> (upgrade/2); 65 | while ((s+1)*(s+1) <= x) s++; // executes at most twice 66 | return s; 67 | } 68 | 69 | public static final int sqrt(int x, int r) { 70 | int s = sqrtab[x>>r/2]; 71 | while ((s+1)*(s+1) <= x) s++; // executes at most twice 72 | return s; 73 | } 74 | 75 | public static void main(String[] args) { 76 | int n = 1 << 30; 77 | // System.out.print("Testing correctness of " + n + " inputs..."); 78 | // for (int t = 1; t < n; t++) { 79 | // if (t % 10000000 == 0) System.out.print("."); 80 | // int x = t; 81 | // int logx = log(x); 82 | // if (((1 << logx) & x) == 0) 83 | // throw new RuntimeException("log(x) is incorrect [1]"); 84 | // if ( (( (1 << (logx+1)) - 1 ) & x) != x) 85 | // throw new RuntimeException("log(x) is incorrect [2]"); 86 | // double ms = Math.sqrt(x); 87 | // double fss = FastSqrt.sqrt(x); 88 | // // System.out.println(x + " " + logx + " " + ms + " " + fss + " " + Math.abs(ms-fss)); 89 | // if (Math.abs(ms-fss) > 2.0) 90 | // throw new RuntimeException("sqrt(x) is incorrect [1]"); 91 | // } 92 | // System.out.println("passed!"); 93 | 94 | 95 | n = 1 << 27; 96 | long start, stop; 97 | double elapsed; 98 | 99 | 100 | System.out.print("Performing " + n + " Math.sqrts..."); 101 | start = System.nanoTime(); 102 | for (int i = 0; i < n; i++) { 103 | Math.sqrt(i); 104 | } 105 | stop = System.nanoTime(); 106 | elapsed = (stop-start)*1e-9; 107 | System.out.println("done (" + elapsed + "s)"); 108 | 109 | System.out.print("Performing " + n + " FastSqrt.sqrts roots..."); 110 | start = System.nanoTime(); 111 | for (int i = 0; i < n; i++) { 112 | FastSqrt.sqrt(i); 113 | } 114 | stop = System.nanoTime(); 115 | elapsed = (stop-start)*1e-9; 116 | System.out.println("done (" + elapsed + "s)"); 117 | 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /python/ods/base.py: -------------------------------------------------------------------------------- 1 | """Algumas classes de base herdadas por outros módulos.""" 2 | 3 | 4 | class BaseCollection(object): 5 | """Base class for everything""" 6 | def __init__(self): 7 | super(BaseCollection, self).__init__() 8 | 9 | def size(self): 10 | """This implementation works for almost every class in ODS""" 11 | return self.n 12 | 13 | def __len__(self): 14 | """Retorna o número de elementos do objeto.""" 15 | return self.size() 16 | 17 | def __str__(self): 18 | """Retorna uma string com os elementos da estrutura.""" 19 | return "[" + ",".join([str(x) for x in self]) + "]" 20 | 21 | def __repr__(self): 22 | return self.__class__.__name__ \ 23 | + "(["+ ",".join([repr(x) for x in self]) +"])" 24 | 25 | 26 | class BaseSet(BaseCollection): 27 | """Base class for Set implementations""" 28 | def __init__(self): 29 | super(BaseSet, self).__init__() 30 | 31 | def add_all(self, a): 32 | for x in a: 33 | self.add(x) 34 | 35 | def __in__(self, x): 36 | """Testa se elemento x está na estrutura.""" 37 | return self.find(x) is not None 38 | 39 | def __eq__(self, a): 40 | if len(a) != len(self): return False 41 | for x in self: 42 | if not x in a: return False 43 | for x in a: 44 | if not x in self: return False 45 | return True 46 | 47 | def __ne__(self, a): 48 | return not self == a 49 | 50 | 51 | class BaseList(BaseCollection): 52 | """Base class for List implementations""" 53 | def __init__(self): 54 | super(BaseList, self).__init__() 55 | 56 | def append(self, x): 57 | self.add(self.size(), x) 58 | 59 | def add_all(self, iterable): 60 | for x in iterable: 61 | self.append(x) 62 | 63 | def clear(self): 64 | """This can be overridden with more efficient implementations""" 65 | while self.size() > 0: 66 | self.remove(self.size()-1) 67 | 68 | def add_first(self, x): 69 | return self.add(0, x) 70 | 71 | def remove_first(self): 72 | return self.remove(0) 73 | 74 | def add_last(self, x): 75 | return self.add(self.size(), x) 76 | 77 | def remove_last(self): 78 | return self.remove(self.size()-1) 79 | 80 | def insert(self, i, x): 81 | self.add(i, x) 82 | 83 | def __iter__(self): 84 | """This implementation is good enough for array-based lists""" 85 | for i in range(len(self)): 86 | yield(self.get(i)) 87 | 88 | def __eq__(self, a): 89 | if len(a) != len(self): return False 90 | it1 = iter(a) 91 | it2 = iter(self) 92 | for i in range(len(a)): 93 | if it1.next() != it2.next(): return False 94 | return True 95 | 96 | def __ne__(self, a): 97 | return not self == a 98 | 99 | def index(self, x): 100 | i = 0 101 | for y in self: 102 | if y == x: 103 | return i 104 | i += 1 105 | raise ValueError('%r is not in the list' % x) 106 | 107 | def remove_value(self, x): 108 | try: 109 | return self.remove(self.index(x)) 110 | except ValueError: 111 | return False 112 | 113 | def __getitem__(self, key): 114 | return self.get(key) 115 | 116 | def __setitem__(self, key, value): 117 | return self.set(key, value) 118 | 119 | def __delitem__(self, i): 120 | self.remove(i) 121 | 122 | 123 | -------------------------------------------------------------------------------- /python/ods/yfasttrie.py: -------------------------------------------------------------------------------- 1 | """An implementation of Willard's Y-Fast tries 2 | 3 | This structure is able to store w-bit integers with O(log w) time searches, 4 | additions, and removals. 5 | 6 | D. E. Willard. Log-logarithmic worst-case range queries are possible in 7 | space Theta(n). Information Processing Letters, 17, 81-84. 1984. 8 | """ 9 | import random 10 | 11 | from .base import BaseSet 12 | from .treap import Treap 13 | from .xfasttrie import XFastTrie 14 | from .utils import w 15 | 16 | class STreap(Treap): 17 | """A Treap that implements the split/absorb functionality""" 18 | 19 | def split(self, x): 20 | """Remove all values <= x and return a STreap containing these values""" 21 | u = self._find_last(x) 22 | s = self._new_node(None) 23 | if u.right is self.nil: 24 | u.right = s 25 | else: 26 | u = u.right 27 | while u.left is not self.nil: 28 | u = u.left 29 | u.left = s 30 | s.parent = u 31 | s.p = -1 32 | self.bubble_up(s) 33 | self.r = s.right 34 | if self.r is not self.nil: self.r.parent = self.nil 35 | ret = STreap() 36 | ret.r = s.left 37 | if ret.r is not ret.nil: ret.r.parent = ret.nil 38 | return ret 39 | 40 | def absorb(self, t): 41 | """Absorb the treap t (which must only contain smaller values)""" 42 | s = self._new_node(None) 43 | s.right = self.r 44 | if self.r is not self.nil: self.r.parent = s 45 | s.left = t.r 46 | if t.r is not t.nil: t.r.parent = s 47 | self.r = s 48 | t.r = t.nil 49 | self.trickle_down(s) 50 | self.splice(s) 51 | 52 | def size(self): 53 | """Raise an error because our implementation is only half-assed""" 54 | raise AttributeError(self.__class__.__name__ \ 55 | + "does not correctly maintain size()") 56 | 57 | class Pair(tuple): 58 | def __new__(cls, x, y=None): 59 | return super(Pair, cls).__new__(cls, (x, y)) 60 | 61 | @property 62 | def t(self): 63 | return self[1] 64 | 65 | @property 66 | def x(self): 67 | return self[0] 68 | 69 | def __int__(self): 70 | return int(self[0]) 71 | 72 | class YFastTrie(BaseSet): 73 | def __init__(self): 74 | super(YFastTrie, self).__init__() 75 | self._initialize() 76 | 77 | def _initialize(self): 78 | self.xft = XFastTrie() 79 | self.xft.add(Pair((1< 4 | ******************************************************************************/ 5 | 6 | #ifndef ODS_BINARYSEARCHTREE_H_ 7 | #define ODS_BINARYSEARCHTREE_H_ 8 | 9 | #include 10 | 11 | typedef struct btnode_t { 12 | 13 | void* data; 14 | 15 | struct btnode_t* parent; 16 | struct btnode_t* left; 17 | struct btnode_t* right; 18 | 19 | } btnode_t; 20 | 21 | typedef struct { 22 | 23 | btnode_t* root; 24 | 25 | size_t elem_size; 26 | size_t length; 27 | 28 | int (*cmp)(void *, void *); 29 | 30 | } binarysearchtree_t; 31 | 32 | /* FUNCTION 33 | * binarysearchtree_add 34 | * 35 | * DESCRIPTION 36 | * Adds an element to the tree. 37 | * 38 | * PARAMETERS 39 | * tree A valid pointer to an initialized binarysearchtree_t struct. 40 | * elem The element that will be copied into the tree. 41 | */ 42 | extern void binarysearchtree_add(binarysearchtree_t* tree, 43 | void* elem); 44 | 45 | /* FUNCTION 46 | * binarysearchtree_dispose 47 | * 48 | * DESCRIPTION 49 | * Frees allocated memory. Once disposed, a binarysearchtree_t structure 50 | * should be re-initialized before use. 51 | * 52 | * PARAMETERS 53 | * tree A valid pointer to an initialized binarysearchtree_t struct. 54 | */ 55 | void binarysearchtree_dispose(binarysearchtree_t* tree); 56 | 57 | /* FUNCTION 58 | * binarysearchtree_find 59 | * 60 | * DESCRIPTION 61 | * Finds an element in the tree. 62 | * 63 | * PARAMETERS 64 | * tree A valid pointer to an initialized binarysearchtree_t struct. 65 | * search The element that is being searched. 66 | * 67 | * RETURN VALUES 68 | * Returns a non-zero value if the element that was being searched is 69 | * found in the tree, zero otherwise. 70 | */ 71 | extern int binarysearchtree_find(binarysearchtree_t* tree, 72 | void* search); 73 | 74 | /* FUNCTION 75 | * binarysearchtree_init 76 | * 77 | * DESCRIPTION 78 | * Initializes the binarysearchtree_t struct. 79 | * 80 | * PARAMETERS 81 | * tree A valid pointer to a binarysearchtree_t struct. 82 | * elem_size Size of the type that will be inserted in the tree. 83 | * comparator Pointer to a comparator function that takes two void* 84 | * parameters and returns an int. The function must return 85 | * less than zero if the first parameter comes before the 86 | * second parameter and greater than zero if vice versa. 87 | * The function must return zero if arguments are equal. 88 | */ 89 | extern void binarysearchtree_init(binarysearchtree_t* tree, 90 | size_t elem_size, 91 | int(*comparator)(void *, void *)); 92 | 93 | /* FUNCTION 94 | * binarysearchtree_remove 95 | * 96 | * DESCRIPTION 97 | * Removes an element from the tree. 98 | * 99 | * PARAMETERS 100 | * tree A valid pointer to an initialized binarysearchtree_t struct. 101 | * search The element that will be removed from the tree. 102 | * 103 | * RETURN VALUES 104 | * Returns a non-zero value if the element was found and removed; returns 105 | * zero if the element was not found. 106 | */ 107 | extern int binarysearchtree_remove(binarysearchtree_t* tree, 108 | void* elem); 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /java/ods/DualArrayDeque.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.AbstractList; 4 | import java.util.ArrayList; 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | /** 9 | * Implements the List interface using two Lists 10 | * so that insertion/deletions at the front or back of the list 11 | * are fast. This can be used as an efficient Deque. 12 | * @author morin 13 | * 14 | * @param the type of data stored in this List 15 | */ 16 | public class DualArrayDeque extends AbstractList { 17 | /** 18 | * The class of objects stored in this structure 19 | */ 20 | protected Factory f; 21 | 22 | /** 23 | * the front "half" of the deque 24 | */ 25 | protected List front; 26 | 27 | /** 28 | * the back "half" of the deque 29 | */ 30 | protected List back; 31 | 32 | /** 33 | * Create a new empty List data structure. 34 | * 35 | * Subclasses should override this if they want to use 36 | * different structures for front and back. 37 | * @return 38 | */ 39 | protected List newStack() { 40 | return new ArrayList(); 41 | } 42 | 43 | /** 44 | * Constructor 45 | * @param t0 the class of the objects stored in this list 46 | */ 47 | public DualArrayDeque(Class t) { 48 | f = new Factory(t); 49 | front = newStack(); 50 | back = newStack(); 51 | } 52 | 53 | public T get(int i) { 54 | if (i < front.size()) { 55 | return front.get(front.size()-i-1); 56 | } else { 57 | return back.get(i-front.size()); 58 | } 59 | } 60 | 61 | public T set(int i, T x) { 62 | if (i < front.size()) { 63 | return front.set(front.size()-i-1, x); 64 | 65 | } else { 66 | return back.set(i-front.size(), x); 67 | } 68 | } 69 | 70 | public void add(int i, T x) { 71 | if (i < front.size()) { 72 | front.add(front.size()-i, x); 73 | } else { 74 | back.add(i-front.size(), x); 75 | } 76 | balance(); 77 | } 78 | 79 | /** 80 | * Rebalance the elements between front and back 81 | * if necessary 82 | */ 83 | protected void balance() { 84 | int n = size(); 85 | if (3*front.size() < back.size()) { 86 | int s = n/2 - front.size(); 87 | List l1 = newStack(); 88 | List l2 = newStack(); 89 | l1.addAll(back.subList(0,s)); 90 | Collections.reverse(l1); 91 | l1.addAll(front); 92 | l2.addAll(back.subList(s, back.size())); 93 | front = l1; 94 | back = l2; 95 | } else if (3*back.size() < front.size()) { 96 | int s = front.size() - n/2; 97 | List l1 = newStack(); 98 | List l2 = newStack(); 99 | l1.addAll(front.subList(s, front.size())); 100 | l2.addAll(front.subList(0, s)); 101 | Collections.reverse(l2); 102 | l2.addAll(back); 103 | front = l1; 104 | back = l2; 105 | } 106 | } 107 | 108 | public T remove(int i) { 109 | T x; 110 | if (i < front.size()) { 111 | x = front.remove(front.size()-i-1); 112 | } else { 113 | x = back.remove(i-front.size()); 114 | } 115 | balance(); 116 | return x; 117 | } 118 | 119 | public int size() { 120 | return front.size() + back.size(); 121 | } 122 | 123 | public void clear() { 124 | front.clear(); 125 | back.clear(); 126 | } 127 | 128 | public static void main(String args[]) { 129 | List l = new DualArrayDeque(Integer.class); 130 | for (int i = 0; i < 20; i++) { 131 | l.add(new Integer(i)); 132 | } 133 | System.out.println(l); 134 | for (int i = -1; i > -20; i--) { 135 | l.add(0,new Integer(i)); 136 | } 137 | System.out.println(l); 138 | 139 | Integer n = 1000; 140 | Integer x = 20; 141 | List q = new DualArrayDeque(Integer.class); 142 | for (int i = 0; i < n; i++) { 143 | q.add(i); 144 | } 145 | while (true) { 146 | q.add(x); 147 | q.remove(0); 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /java/ods/SLList.java: -------------------------------------------------------------------------------- 1 | package ods; 2 | 3 | import java.util.AbstractQueue; 4 | import java.util.Iterator; 5 | import java.util.Queue; 6 | 7 | /** 8 | * An implementation of a FIFO Queue as a singly-linked list. 9 | * This also includes the stack operations push and pop, which 10 | * operate on the head of the queue 11 | * @author morin 12 | * 13 | * @param the class of objects stored in the queue 14 | */ 15 | public class SLList extends AbstractQueue { 16 | class Node { 17 | T x; 18 | Node next; 19 | } 20 | 21 | /** 22 | * Front of the queue 23 | */ 24 | Node head; 25 | 26 | /** 27 | * Tail of the queue 28 | */ 29 | Node tail; 30 | 31 | /** 32 | * The number of elements in the queue 33 | */ 34 | int n; 35 | 36 | public Iterator iterator() { 37 | class SLIterator implements Iterator { 38 | protected Node p; 39 | 40 | public SLIterator() { 41 | p = head; 42 | } 43 | public boolean hasNext() { 44 | return p != null; 45 | } 46 | public T next() { 47 | T x = p.x; 48 | p = p.next; 49 | return x; 50 | } 51 | public void remove() { 52 | throw new UnsupportedOperationException(); 53 | } 54 | } 55 | return new SLIterator(); 56 | } 57 | 58 | @Override 59 | public int size() { 60 | // TODO Auto-generated method stub 61 | return n; 62 | } 63 | 64 | public boolean add(T x) { 65 | Node u = new Node(); 66 | u.x = x; 67 | if (n == 0) { 68 | head = u; 69 | } else { 70 | tail.next = u; 71 | } 72 | tail = u; 73 | n++; 74 | return true; 75 | } 76 | 77 | public boolean offer(T x) { 78 | return add(x); 79 | } 80 | 81 | @Override 82 | public T peek() { 83 | if (n == 0) return null; 84 | return head.x; 85 | } 86 | 87 | public T poll() { 88 | if (n == 0) 89 | return null; 90 | T x = head.x; 91 | head = head.next; 92 | if (--n == 0) 93 | tail = null; 94 | return x; 95 | } 96 | 97 | /** 98 | * Stack push operation - push x onto the head of the list 99 | * @param x the element to push onto the stack 100 | * @return x 101 | */ 102 | public T push(T x) { 103 | Node u = new Node(); 104 | u.x = x; 105 | u.next = head; 106 | head = u; 107 | if (n == 0) 108 | tail = u; 109 | n++; 110 | return x; 111 | } 112 | 113 | protected void deleteNext(Node u) { 114 | if (u.next == tail) 115 | tail = u; 116 | u.next = u.next.next; 117 | } 118 | 119 | protected void addAfter(Node u, Node v) { 120 | v = u.next.next; 121 | u.next = v; 122 | if (u == tail) 123 | tail = v; 124 | } 125 | 126 | protected Node getNode(int i) { 127 | Node u = head; 128 | for (int j = 0; j < i; j++) 129 | u = u.next; 130 | return u; 131 | } 132 | 133 | /** 134 | * Stack pop operation - pop off the head of the list 135 | * @return the element popped off 136 | */ 137 | public T remove() { 138 | if (n == 0) return null; 139 | T x = head.x; 140 | head = head.next; 141 | if (--n == 0) tail = null; 142 | return x; 143 | } 144 | 145 | public T pop() { 146 | if (n == 0) return null; 147 | T x = head.x; 148 | head = head.next; 149 | if (--n == 0) tail = null; 150 | return x; 151 | } 152 | 153 | 154 | public static void main(String[] args) { 155 | Queue q = new SLList(); 156 | for (int i = 0; i < 100; i++) { 157 | q.add(i); 158 | } 159 | System.out.println(q); 160 | for (int i = 0; i < 50; i++) { 161 | q.remove(); 162 | } 163 | System.out.println(q); 164 | for (int i = 100; i < 200; i++) { 165 | q.add(i); 166 | } 167 | System.out.println(q); 168 | for (int i = 0; i < 50; i++) { 169 | q.remove(); 170 | } 171 | System.out.println(q); 172 | while (!q.isEmpty()) { 173 | q.remove(); 174 | } 175 | System.out.println(q); 176 | 177 | } 178 | } 179 | --------------------------------------------------------------------------------