trees 3: construction of dynamic binary trees

54
Trees 3: Trees 3: Construction of Construction of Dynamic Binary Dynamic Binary Trees Trees Andy Wang Andy Wang Data Structures, Data Structures, Algorithms, and Generic Algorithms, and Generic Programming Programming

Upload: qiana

Post on 15-Jan-2016

34 views

Category:

Documents


0 download

DESCRIPTION

Trees 3: Construction of Dynamic Binary Trees. Andy Wang Data Structures, Algorithms, and Generic Programming. Overview. Definition of class TBinaryTree Recursive methods Inserting elements Removing elements Binary tree construction from file. Defining Class TBinaryTree. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Trees 3:  Construction of Dynamic Binary Trees

Trees 3: Construction Trees 3: Construction of Dynamic Binary of Dynamic Binary

TreesTrees

Andy WangAndy Wang

Data Structures, Algorithms, Data Structures, Algorithms, and Generic Programmingand Generic Programming

Page 2: Trees 3:  Construction of Dynamic Binary Trees

OverviewOverview

Definition of class TBinaryTreeDefinition of class TBinaryTree Recursive methodsRecursive methods Inserting elementsInserting elements Removing elementsRemoving elements Binary tree construction from fileBinary tree construction from file

Page 3: Trees 3:  Construction of Dynamic Binary Trees

Defining Class TBinaryTreeDefining Class TBinaryTreetemplate <typename T>template <typename T>

class TBinaryTree {class TBinaryTree {

friend class TBinaryTreeNavigator<T>;friend class TBinaryTreeNavigator<T>;

public:public:

typedef T value_type;typedef T value_type;

// constructors// constructors

TBinaryTree();TBinaryTree();

virtual ~TBinaryTree();virtual ~TBinaryTree();

TBinaryTree(const TBinaryTree<T>& B);TBinaryTree(const TBinaryTree<T>& B);

TBinaryTree<T>& operator=(const TBinaryTree<T>& B);TBinaryTree<T>& operator=(const TBinaryTree<T>& B);

// read-only operations// read-only operations

int Empty() const;int Empty() const;

size_t Size() const;size_t Size() const;

int Height() const;int Height() const;

Page 4: Trees 3:  Construction of Dynamic Binary Trees

Defining Class TBinaryTreeDefining Class TBinaryTreevoid Display(std::ostream os, char ofc = ‘\0’) const;void Display(std::ostream os, char ofc = ‘\0’) const;

void Dump(std::ostream os, chcar ofc) const;void Dump(std::ostream os, chcar ofc) const;

void Dump(std::ostream os, const T& fill, char ofc) const;void Dump(std::ostream os, const T& fill, char ofc) const;

// operations// operations

int InsertRoot(const T& t);int InsertRoot(const T& t);

int InsertLeft(Navigator& N, const T& t);int InsertLeft(Navigator& N, const T& t);

int InsertRight(Navigator& N, const T& t);int InsertRight(Navigator& N, const T& t);

int Insert(Iterator& I, const T& t);int Insert(Iterator& I, const T& t);

int Remove(Iterator& I);int Remove(Iterator& I);

size_t Remove(const T& t);size_t Remove(const T& t);

void Clear();void Clear();

void Clear(Navigator &N); // clear subtree with root Nvoid Clear(Navigator &N); // clear subtree with root N

Page 5: Trees 3:  Construction of Dynamic Binary Trees

Defining Class TBinaryTreeDefining Class TBinaryTree// iterator operators// iterator operators

typedef TBinaryTreeInorderIterator<T> Iterator;typedef TBinaryTreeInorderIterator<T> Iterator;

typedef TBinaryTreePreorderIterator<T> PreorderIterator;typedef TBinaryTreePreorderIterator<T> PreorderIterator;

typedef TBinaryTreePostorderIterator<T> PostorderIterator;typedef TBinaryTreePostorderIterator<T> PostorderIterator;

typedef TBinaryTreeLevelorderIterator<T> LevelorderIterator;typedef TBinaryTreeLevelorderIterator<T> LevelorderIterator;

typedef TBinaryTreeNavigator<T> Navigator;typedef TBinaryTreeNavigator<T> Navigator;

Navigator Root() const;Navigator Root() const;

Iterator Begin() const;Iterator Begin() const;

Iterator End() const;Iterator End() const;

Iterator rBegin() const;Iterator rBegin() const;

Iterator rBegin() const;Iterator rBegin() const;

Page 6: Trees 3:  Construction of Dynamic Binary Trees

Defining Class TBinaryTreeDefining Class TBinaryTreeprotected:protected:

class TNode {class TNode {

friend class TBinaryTree<T>;friend class TBinaryTree<T>;

friend class TBinaryTreeNavigator<T>;friend class TBinaryTreeNavigator<T>;

TNode(const T&);TNode(const T&);

TNode(const TNode&);TNode(const TNode&);

T value;T value;

char color;char color;

TNode *parent, *lchild, *rchild;TNode *parent, *lchild, *rchild;

};};

TNode *root;TNode *root;

static void RRelease(TNode *N); // recursive deletion of N’s childrenstatic void RRelease(TNode *N); // recursive deletion of N’s children

static TNode* RClone(const TNode *N); // deep copy of Nstatic TNode* RClone(const TNode *N); // deep copy of N

static size_t RSize(const TNode *N); // return number of nodes at Nstatic size_t RSize(const TNode *N); // return number of nodes at N

static int RHeight(const TNode *N); // return height of tree at Nstatic int RHeight(const TNode *N); // return height of tree at N

};};

Page 7: Trees 3:  Construction of Dynamic Binary Trees

Recursive Protected Recursive Protected MethodsMethods

template <typename T>template <typename T>

size_t TBinaryTree<T>::RSize(const TNode *N) {size_t TBinaryTree<T>::RSize(const TNode *N) {

if (N == 0) return 0;if (N == 0) return 0;

return (1 + RSize(N->lchild) + RSize(N->rchild));return (1 + RSize(N->lchild) + RSize(N->rchild));

}}

template <typename T>template <typename T>

int TBinaryTree<T>::RHeight(const TNode *N) {int TBinaryTree<T>::RHeight(const TNode *N) {

if (N == 0) return -1;if (N == 0) return -1;

return (1 + max(RHeight(N->lchild), RHeight(N->rchild)));return (1 + max(RHeight(N->lchild), RHeight(N->rchild)));

}}

Page 8: Trees 3:  Construction of Dynamic Binary Trees

Recursive Protected Recursive Protected MethodsMethods

template <typename T>template <typename T>

void TBinaryTree<T>::RRelease(TBinaryTree<T>::TNode *N) {void TBinaryTree<T>::RRelease(TBinaryTree<T>::TNode *N) {

if (N != 0) {if (N != 0) {

if (N->lchild != 0) {if (N->lchild != 0) {

TBinaryTree<T>::RRelease(N->lchild);TBinaryTree<T>::RRelease(N->lchild);

delete N->lchild:delete N->lchild:

N->lchild = 0;N->lchild = 0;

}}

if (N->rchild != 0) {if (N->rchild != 0) {

TBinaryTree<T>::RRelease(N->rchild);TBinaryTree<T>::RRelease(N->rchild);

delete N->rchild;delete N->rchild;

N->rchild = 0;N->rchild = 0;

}}

}}

}}

Page 9: Trees 3:  Construction of Dynamic Binary Trees

Recursive Protected Recursive Protected MethodsMethods

template <typename T>template <typename T>

TBinaryTree<T>::TNode* TBinaryTree<T>::TNode*

TBinaryTree<T>::RClone(const TBinaryTree<T>::TNode *N) {TBinaryTree<T>::RClone(const TBinaryTree<T>::TNode *N) {

if (N == 0) return 0;if (N == 0) return 0;

TBinaryTree<T>::TNode *newN = new TBinaryTree<T>::TNode(N->value);TBinaryTree<T>::TNode *newN = new TBinaryTree<T>::TNode(N->value);

newN->lchild = TBinaryTree<T>::RClone(N->lchild);newN->lchild = TBinaryTree<T>::RClone(N->lchild);

newN->rchild = TBinaryTree<T>::RClone(N->rchild);newN->rchild = TBinaryTree<T>::RClone(N->rchild);

if (newN->lchild) {if (newN->lchild) {

newN->lchild->parent = newN;newN->lchild->parent = newN;

}}

if (newN->rchild) {if (newN->rchild) {

newN->rchild->parent = newN;newN->rchild->parent = newN;

}}

return newN;return newN;

}}

Page 10: Trees 3:  Construction of Dynamic Binary Trees

Recursive Protected CallsRecursive Protected Callstemplate <typename T>template <typename T>

void TBinaryTree<T>::Dump(ostream& os, const T& fill) const {void TBinaryTree<T>::Dump(ostream& os, const T& fill) const {

// idea: BFS// idea: BFS

1

2 3

4 5

root 1

2 3

4 5

root

Page 11: Trees 3:  Construction of Dynamic Binary Trees

Recursive Protected CallsRecursive Protected Callstemplate <typename T>template <typename T>

void TBinaryTree<T>::Dump(ostream& os, const T& fill) const {void TBinaryTree<T>::Dump(ostream& os, const T& fill) const {

if (root == 0) return;if (root == 0) return;

TBinaryTree<T>::TNode *fillNode = new TBinaryTree<T>::TNode(fill);TBinaryTree<T>::TNode *fillNode = new TBinaryTree<T>::TNode(fill);

CQueue<TList<TBinaryTree<T, P>::TNode *> > Que;CQueue<TList<TBinaryTree<T, P>::TNode *> > Que;

TBinaryTree<T>::TNode *current;TBinaryTree<T>::TNode *current;

unsigned int currLayerSize, nextLayerSize, j, k;unsigned int currLayerSize, nextLayerSize, j, k;

Que.Push(root);Que.Push(root);

k = 1 // always 2^(layer number)k = 1 // always 2^(layer number)

for (curLayerSize = 1, nextLayerSize = 0; for (curLayerSize = 1, nextLayerSize = 0;

currLayerSize > 0;currLayerSize > 0;

currLayerSize = nextLayerSize) {currLayerSize = nextLayerSize) {

1

2 3

4 5 76

root

Page 12: Trees 3:  Construction of Dynamic Binary Trees

Recursive Protected CallsRecursive Protected Callsfor (j = 0; j < k; ++j) {for (j = 0; j < k; ++j) {

current = Que.Front();current = Que.Front();

Que.Pop();Que.Pop();

os << current->value;os << current->value;

if (current->lchild != 0) {if (current->lchild != 0) {

Que.Push(current->lchild);Que.Push(current->lchild);

++nextLayerSize;++nextLayerSize;

} else {} else {

Que.Push(fillNode);Que.Push(fillNode);

}}

if (current->rchild != 0) {if (current->rchild != 0) {

Que.Push(current->rchild);Que.Push(current->rchild);

++nextLayerSize;++nextLayerSize;

} else {} else {

Que.Push(fillNode);Que.Push(fillNode);

}}

}}

os << endl;os << endl;

k *= 2;k *= 2;

}}

Page 13: Trees 3:  Construction of Dynamic Binary Trees

Recursive Protected CallsRecursive Protected CallsQue.Clear();Que.Clear();

delete fillNode;delete fillNode;

}}

Page 14: Trees 3:  Construction of Dynamic Binary Trees

Helper FunctionsHelper Functionstemplate <typename T>template <typename T>

int TBinaryTree<T>::Empty() const { return (root == 0); }int TBinaryTree<T>::Empty() const { return (root == 0); }

template <typename T>template <typename T>

int TBinaryTree<T>::Height() const { return RHeight(root); }int TBinaryTree<T>::Height() const { return RHeight(root); }

template <typename T>template <typename T>

size_t TBinaryTree::Size() const { return RSize(root); }size_t TBinaryTree::Size() const { return RSize(root); }

template <typename T>template <typename T>

void TBinaryTree<T>::Clear() {void TBinaryTree<T>::Clear() {

TBinaryTree<T>::RRelease(root);TBinaryTree<T>::RRelease(root);

delete root;delete root;

root = 0;root = 0;

}}

Page 15: Trees 3:  Construction of Dynamic Binary Trees

Helper FunctionsHelper Functions

template <typename T>template <typename T>

void TBinaryTree<T>::Clear(TBinaryTreeNavigator<T>& N) {void TBinaryTree<T>::Clear(TBinaryTreeNavigator<T>& N) {

if (N.Valid()) {if (N.Valid()) {

TNode *P = N.currentNode->parent;TNode *P = N.currentNode->parent;

if (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = 0;P->lchild = 0;

} else if (N.IsRightChild()) {} else if (N.IsRightChild()) {

P->rchild = 0;P->rchild = 0;

}}

TBinaryTree<T>::RRelease(N.currNode);TBinaryTree<T>::RRelease(N.currNode);

delete N.currNode;delete N.currNode;

N.currNode = P;N.currNode = P;

}}

}}

Page 16: Trees 3:  Construction of Dynamic Binary Trees

Helper FunctionsHelper Functions

template <typename T>template <typename T>

TBinaryTree<T>& TBinaryTree<T>::operator=(const TBinaryTree<T>& b) {TBinaryTree<T>& TBinaryTree<T>::operator=(const TBinaryTree<T>& b) {

if (this != &b) {if (this != &b) {

Clear();Clear();

root = TBinaryTree<T>::RClone(b.root);root = TBinaryTree<T>::RClone(b.root);

} }

return *this;return *this;

}}

Page 17: Trees 3:  Construction of Dynamic Binary Trees

Supports for Iterators and Supports for Iterators and NavigatorsNavigators

template <typename T>template <typename T>

TBinaryTreeInorderIterator<T> TBinaryTree<T>::Begin() const {TBinaryTreeInorderIterator<T> TBinaryTree<T>::Begin() const {

TBinaryTree<T>::Iterator I;TBinaryTree<T>::Iterator I;

I.Initialize(*this);I.Initialize(*this);

return I;return I;

}}

template <typename T>template <typename T>

TBinaryTreeInorderIterator<T> TBinaryTree<T>::End() const {TBinaryTreeInorderIterator<T> TBinaryTree<T>::End() const {

TBinaryTree<T>::Iterator I;TBinaryTree<T>::Iterator I;

return I;return I;

}}

Page 18: Trees 3:  Construction of Dynamic Binary Trees

Supports for Iterators and Supports for Iterators and NavigatorsNavigators

template <typename T>template <typename T>

TBinaryTreeInorderIterator<T> TBinaryTree<T>::rBegin() const {TBinaryTreeInorderIterator<T> TBinaryTree<T>::rBegin() const {

TBinaryTree<T>::Iterator I;TBinaryTree<T>::Iterator I;

I.rInitialize(*this);I.rInitialize(*this);

return I;return I;

}}

template <typename T>template <typename T>

TBinaryTreeInorderIterator<T> TBinaryTree<T>::rEnd() const {TBinaryTreeInorderIterator<T> TBinaryTree<T>::rEnd() const {

TBinaryTree<T>::Iterator I;TBinaryTree<T>::Iterator I;

return I;return I;

}}

template <typename T>template <typename T>

TBinaryTreeNavigator<T> TBinaryTree<T>::Root() const {TBinaryTreeNavigator<T> TBinaryTree<T>::Root() const {

TBinaryTree<T>::Navigator N;TBinaryTree<T>::Navigator N;

N.currNode = root;N.currNode = root;

return N;return N;

}}

Page 19: Trees 3:  Construction of Dynamic Binary Trees

ConstructorsConstructorstemplate <typename T>template <typename T>

TBinaryTree<T>::TNode::TNode(const T& t) : value(t), color(‘b’), parent(0), TBinaryTree<T>::TNode::TNode(const T& t) : value(t), color(‘b’), parent(0), lchild(0), rchild(0) {lchild(0), rchild(0) {

}}

template <typename T>template <typename T>

TBinaryTree<T>::TNode::TNode(const TNode& N) {TBinaryTree<T>::TNode::TNode(const TNode& N) {

std::cerr << “TBinaryTree<T>::TNode::TNode(const TNode&) called\n”std::cerr << “TBinaryTree<T>::TNode::TNode(const TNode&) called\n”

}}

template <typename T>template <typename T>

TBinaryTree<T>::TBinaryTree() : root(0) { }TBinaryTree<T>::TBinaryTree() : root(0) { }

template <typename T>template <typename T>

TBinaryTree<T>::~TBinaryTree() { Clear(); }TBinaryTree<T>::~TBinaryTree() { Clear(); }

template <typename T>template <typename T>

TBinaryTree<T>::TBinaryTree(const TBinaryTree<T>& b) {TBinaryTree<T>::TBinaryTree(const TBinaryTree<T>& b) {

root = TBinaryTree<T>::RClone(b.root);root = TBinaryTree<T>::RClone(b.root);

}}

Page 20: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationstemplate <typename T>template <typename T>

int TBinaryTree<T>::InsertRoot(const T& t) {int TBinaryTree<T>::InsertRoot(const T& t) {

if (root != 0) {if (root != 0) {

root->value = t;root->value = t;

return 1;return 1;

}}

root = new TBinaryTree<T>::TNode(t);root = new TBinaryTree<T>::TNode(t);

if (root == 0) {if (root == 0) {

return 0;return 0;

}}

return 1;return 1;

}}

Page 21: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationstemplate <typename T>template <typename T>

int TBinaryTree<T>::InsertLeft(Navigator& N, const T& t) {int TBinaryTree<T>::InsertLeft(Navigator& N, const T& t) {

if (!N.Valid()) {if (!N.Valid()) {

return 0;return 0;

}}

if (N.HasLeftChild()) {if (N.HasLeftChild()) {

++N;++N;

*N = t;*N = t;

return 1;return 1;

}}

N.currNode->lchild = new TBinaryTree<T>::TNode(t);N.currNode->lchild = new TBinaryTree<T>::TNode(t);

if (N.currNode->lchild == 0) {if (N.currNode->lchild == 0) {

return 0;return 0;

}}

N.currNode->lchild->parent = N.currNode;N.currNode->lchild->parent = N.currNode;

++N;++N;

return 1;return 1;

}}

Page 22: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationstemplate <typename T>template <typename T>

int TBinaryTree<T>::InsertRight(Navigator& N, const T& t) {int TBinaryTree<T>::InsertRight(Navigator& N, const T& t) {

if (!N.Valid()) {if (!N.Valid()) {

return 0;return 0;

}}

if (N.HasRightChild()) {if (N.HasRightChild()) {

N++;N++;

*N = t;*N = t;

return 1;return 1;

}}

N.currNode->rchild = new TBinaryTree<T>::TNode(t);N.currNode->rchild = new TBinaryTree<T>::TNode(t);

if (N.currNode->rchild == 0) {if (N.currNode->rchild == 0) {

return 0;return 0;

}}

N.currNode->rchild->parent = N.currNode;N.currNode->rchild->parent = N.currNode;

N++;N++;

return 1;return 1;

}}

Page 23: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationstemplate <typename T>template <typename T>

int TBinaryTree<T>::Insert(TBinaryTree<T>::Iterator& I, const T& Tval) {int TBinaryTree<T>::Insert(TBinaryTree<T>::Iterator& I, const T& Tval) {

// empty case: insert at root// empty case: insert at root

if (Empty()) {if (Empty()) {

if (InsertRoot(Tval) {if (InsertRoot(Tval) {

I.N = Root();I.N = Root();

return 1;return 1;

} else {} else {

return 0;return 0;

}}

}}

Page 24: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations// valid case, insert Tval at I, move Told to ++I// valid case, insert Tval at I, move Told to ++I

if (I.Valid()) {if (I.Valid()) {

T Told = *I;T Told = *I;

Navigator N = I.N;Navigator N = I.N;

if (N.HasRightChild())) {if (N.HasRightChild())) {

N++;N++;

while (N.HasLeftChild()) {while (N.HasLeftChild()) {

++N;++N;

}}

if (!InsertLeft(N, Told)) {if (!InsertLeft(N, Told)) {

return 0;return 0;

}}

} else {} else {

if (!InsertRight(N, Told)) {if (!InsertRight(N, Told)) {

return 0;return 0;

}}

}}

*I = Tval;*I = Tval;

return 1;return 1;

}}

Told

I ->

Page 25: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations// valid case, insert Tval at I, move Told to ++I// valid case, insert Tval at I, move Told to ++I

if (I.Valid()) {if (I.Valid()) {

T Told = *I;T Told = *I;

Navigator N = I.N;Navigator N = I.N;

if (N.HasRightChild())) {if (N.HasRightChild())) {

N++;N++;

while (N.HasLeftChild()) {while (N.HasLeftChild()) {

++N;++N;

}}

if (!InsertLeft(N, Told)) {if (!InsertLeft(N, Told)) {

return 0;return 0;

}}

} else {} else {

if (!InsertRight(N, Told)) {if (!InsertRight(N, Told)) {

return 0;return 0;

}}

}}

*I = Tval;*I = Tval;

return 1;return 1;

}}

Tval

I ->

Told

Page 26: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations// valid case, insert Tval at I, move Told to ++I// valid case, insert Tval at I, move Told to ++I

if (I.Valid()) {if (I.Valid()) {

T Told = *I;T Told = *I;

Navigator N = I.N;Navigator N = I.N;

if (N.HasRightChild())) {if (N.HasRightChild())) {

N++;N++;

while (N.HasLeftChild()) {while (N.HasLeftChild()) {

++N;++N;

}}

if (!InsertLeft(N, Told)) {if (!InsertLeft(N, Told)) {

return 0;return 0;

}}

} else {} else {

if (!InsertRight(N, Told)) {if (!InsertRight(N, Told)) {

return 0;return 0;

}}

}}

*I = Tval;*I = Tval;

return 1;return 1;

}}

Told

I ->

Page 27: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations// valid case, insert Tval at I, move Told to ++I// valid case, insert Tval at I, move Told to ++I

if (I.Valid()) {if (I.Valid()) {

T Told = *I;T Told = *I;

Navigator N = I.N;Navigator N = I.N;

if (N.HasRightChild())) {if (N.HasRightChild())) {

N++;N++;

while (N.HasLeftChild()) {while (N.HasLeftChild()) {

++N;++N;

}}

if (!InsertLeft(N, Told)) {if (!InsertLeft(N, Told)) {

return 0;return 0;

}}

} else {} else {

if (!InsertRight(N, Told)) {if (!InsertRight(N, Told)) {

return 0;return 0;

}}

}}

*I = Tval;*I = Tval;

return 1;return 1;

}}

Tval

I ->

Told

Page 28: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations// invalid iterator: insert at the end;// invalid iterator: insert at the end;

for (I.N = Root(); I.N.HasRightChild(); (I.N)++) { }for (I.N = Root(); I.N.HasRightChild(); (I.N)++) { }

if (InsertRight(I.N, Tval) {if (InsertRight(I.N, Tval) {

return 1;return 1;

} else {} else {

I = End();I = End();

return 0;return 0;

}}

}}

Page 29: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationstemplate <typename T>template <typename T>

int TBinaryTree<T>::Remove(Iterator &I) {int TBinaryTree<T>::Remove(Iterator &I) {

// remove element at I, leave I at ++(), and preserve inorder// remove element at I, leave I at ++(), and preserve inorder

if (!I.Valid()) {if (!I.Valid()) {

return 0;return 0;

}}

TBinaryTree<T>::Navigator N = I.N;TBinaryTree<T>::Navigator N = I.N;

++I; // I is now at the next place in an inorder traversal++I; // I is now at the next place in an inorder traversal

TBinaryTree<T>::TNode *R = N.currNode->rchild;TBinaryTree<T>::TNode *R = N.currNode->rchild;

TBinaryTree<T>::TNode *L = N.currNode->lchild;TBinaryTree<T>::TNode *L = N.currNode->lchild;

TBinaryTree<T>::TNode *P = N.currNode->parent;TBinaryTree<T>::TNode *P = N.currNode->parent;

N->I->

Page 30: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationstemplate <typename T>template <typename T>

int TBinaryTree<T>::Remove(Iterator &I) {int TBinaryTree<T>::Remove(Iterator &I) {

// remove element at I, leave I at ++(), and preserve inorder// remove element at I, leave I at ++(), and preserve inorder

if (!I.Valid()) {if (!I.Valid()) {

return 0;return 0;

}}

TBinaryTree<T>::Navigator N = I.N;TBinaryTree<T>::Navigator N = I.N;

++I; // I is now at the next place in an inorder traversal++I; // I is now at the next place in an inorder traversal

TBinaryTree<T>::TNode *R = N.currNode->rchild;TBinaryTree<T>::TNode *R = N.currNode->rchild;

TBinaryTree<T>::TNode *L = N.currNode->lchild;TBinaryTree<T>::TNode *L = N.currNode->lchild;

TBinaryTree<T>::TNode *P = N.currNode->parent;TBinaryTree<T>::TNode *P = N.currNode->parent;

N->

I->

Page 31: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationstemplate <typename T>template <typename T>

int TBinaryTree<T>::Remove(Iterator &I) {int TBinaryTree<T>::Remove(Iterator &I) {

// remove element at I, leave I at ++(), and preserve inorder// remove element at I, leave I at ++(), and preserve inorder

if (!I.Valid()) {if (!I.Valid()) {

return 0;return 0;

}}

TBinaryTree<T>::Navigator N = I.N;TBinaryTree<T>::Navigator N = I.N;

++I; // I is now at the next place in an inorder traversal++I; // I is now at the next place in an inorder traversal

TBinaryTree<T>::TNode *R = N.currNode->rchild;TBinaryTree<T>::TNode *R = N.currNode->rchild;

TBinaryTree<T>::TNode *L = N.currNode->lchild;TBinaryTree<T>::TNode *L = N.currNode->lchild;

TBinaryTree<T>::TNode *P = N.currNode->parent;TBinaryTree<T>::TNode *P = N.currNode->parent;

N->

L-> R->

I->

P->

Page 32: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations

N->

L-> R->

I->

P->

Nodes listed in inorder traversal Nodes listed in inorder traversal before removal: L, N, I, R, … Pbefore removal: L, N, I, R, … P

Nodes listed after removing N:Nodes listed after removing N:– L, I, R, …PL, I, R, …P

Page 33: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations

L-> R->

I->

P->

Nodes listed in inorder traversal Nodes listed in inorder traversal before removal: L, N, I, R, … Pbefore removal: L, N, I, R, … P

Nodes listed after removing N:Nodes listed after removing N:– L, I, R, …PL, I, R, …P

How do we reconnect How do we reconnect

L, P, and R?L, P, and R?

Page 34: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations

L->

R->

I->

P->

Nodes listed in inorder traversal Nodes listed in inorder traversal before removal: L, N, I, R, … Pbefore removal: L, N, I, R, … P

Nodes listed after removing N:Nodes listed after removing N:– L, I, R, …PL, I, R, …P

How do we reconnect How do we reconnect

L, P, and R?L, P, and R?

Page 35: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations// case 1: N has right child// case 1: N has right child

if (N.HasRightChild()) {if (N.HasRightChild()) {

if (I.N.HasLeftChild()) {if (I.N.HasLeftChild()) {

std::cerr << “Error: structural problem” << endl;std::cerr << “Error: structural problem” << endl;

return 0;return 0;

}}

if (L) {if (L) {

I.N.currNode->lchild = L;I.N.currNode->lchild = L;

L->parent = I.N.currNode;L->parent = I.N.currNode;

N.currNode->lchild = 0;N.currNode->lchild = 0;

}}

N->

L-> R->

I->

P->

Page 36: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations// case 1: N has right child// case 1: N has right child

if (N.HasRightChild()) {if (N.HasRightChild()) {

if (I.N.HasLeftChild()) {if (I.N.HasLeftChild()) {

std::cerr << “Error: structural problem” << endl;std::cerr << “Error: structural problem” << endl;

return 0;return 0;

}}

if (L) {if (L) {

I.N.currNode->lchild = L;I.N.currNode->lchild = L;

L->parent = I.N.currNode;L->parent = I.N.currNode;

N.currNode->lchild = 0;N.currNode->lchild = 0;

}}

N->

L-> R->

I->

P->

Page 37: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations// case 1: N has right child// case 1: N has right child

if (N.HasRightChild()) {if (N.HasRightChild()) {

if (I.N.HasLeftChild()) {if (I.N.HasLeftChild()) {

std::cerr << “Error: structural problem” << endl;std::cerr << “Error: structural problem” << endl;

return 0;return 0;

}}

if (L) {if (L) {

I.N.currNode->lchild = L;I.N.currNode->lchild = L;

L->parent = I.N.currNode;L->parent = I.N.currNode;

N.currNode->lchild = 0;N.currNode->lchild = 0;

}}

N->

L->

R->

I->

P->

Page 38: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations// case 1: N has right child// case 1: N has right child

if (N.HasRightChild()) {if (N.HasRightChild()) {

if (I.N.HasLeftChild()) {if (I.N.HasLeftChild()) {

std::cerr << “Error: structural problem” << endl;std::cerr << “Error: structural problem” << endl;

return 0;return 0;

}}

if (L) {if (L) {

I.N.currNode->lchild = L;I.N.currNode->lchild = L;

L->parent = I.N.currNode;L->parent = I.N.currNode;

N.currNode->lchild = 0;N.currNode->lchild = 0;

}}

N->

L->

R->

I->

P->

Page 39: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationsif (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = R;P->lchild = R;

R->parent = P;R->parent = P;

} else if (N.IsRightChild()) {} else if (N.IsRightChild()) {

P->rchild = R;P->rchild = R;

R->parent = P;R->parent = P;

} else {} else {

root = R;root = R;

R->parent = 0;R->parent = 0;

}}

delete N.currNode;delete N.currNode;

return 1;return 1;

}}

N->

L->

R->

I->

P->

Page 40: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationsif (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = R;P->lchild = R;

R->parent = P;R->parent = P;

} else if (N.IsRightChild()) {} else if (N.IsRightChild()) {

P->rchild = R;P->rchild = R;

R->parent = P;R->parent = P;

} else {} else {

root = R;root = R;

R->parent = 0;R->parent = 0;

}}

delete N.currNode;delete N.currNode;

return 1;return 1;

}}

N->

L->

R->

I->

P->

Page 41: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationsif (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = R;P->lchild = R;

R->parent = P;R->parent = P;

} else if (N.IsRightChild()) {} else if (N.IsRightChild()) {

P->rchild = R;P->rchild = R;

R->parent = P;R->parent = P;

} else {} else {

root = R;root = R;

R->parent = 0;R->parent = 0;

}}

delete N.currNode;delete N.currNode;

return 1;return 1;

}}

N->

L->

R->

I->

P->

Page 42: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationsif (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = R;P->lchild = R;

R->parent = P;R->parent = P;

} } else if (N.IsRightChild()) {else if (N.IsRightChild()) {

P->rchild = R;P->rchild = R;

R->parent = P;R->parent = P;

} else {} else {

root = R;root = R;

R->parent = 0;R->parent = 0;

}}

delete N.currNode;delete N.currNode;

return 1;return 1;

}}

N->

L->

R->

I->

P->

Page 43: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationsif (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = R;P->lchild = R;

R->parent = P;R->parent = P;

} else if (N.IsRightChild()) {} else if (N.IsRightChild()) {

P->rchild = R;P->rchild = R;

R->parent = P;R->parent = P;

} else {} else {

root = R;root = R;

R->parent = 0;R->parent = 0;

}}

delete N.currNode;delete N.currNode;

return 1;return 1;

}}

N->

L->

R->

I->

P->

Page 44: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationsif (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = R;P->lchild = R;

R->parent = P;R->parent = P;

} else if (N.IsRightChild()) {} else if (N.IsRightChild()) {

P->rchild = R;P->rchild = R;

R->parent = P;R->parent = P;

} else {} else {

root = R;root = R;

R->parent = 0;R->parent = 0;

}}

delete N.currNode;delete N.currNode;

return 1;return 1;

}}

N->

L->

R->

I->

P->

Page 45: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationsif (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = R;P->lchild = R;

R->parent = P;R->parent = P;

} else if (N.IsRightChild()) {} else if (N.IsRightChild()) {

P->rchild = R;P->rchild = R;

R->parent = P;R->parent = P;

} else {} else {

root = R;root = R;

R->parent = 0;R->parent = 0;

}}

delete N.currNode;delete N.currNode;

return 1;return 1;

}}

N->

L->

R->

I->

root->

Page 46: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationsif (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = R;P->lchild = R;

R->parent = P;R->parent = P;

} else if (N.IsRightChild()) {} else if (N.IsRightChild()) {

P->rchild = R;P->rchild = R;

R->parent = P;R->parent = P;

} else {} else {

root = R;root = R;

R->parent = 0;R->parent = 0;

}}

delete N.currNode;delete N.currNode;

return 1;return 1;

}}

N->

L->

R->

I->

root->

Page 47: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationsif (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = R;P->lchild = R;

R->parent = P;R->parent = P;

} else if (N.IsRightChild()) {} else if (N.IsRightChild()) {

P->rchild = R;P->rchild = R;

R->parent = P;R->parent = P;

} else {} else {

root = R;root = R;

R->parent = 0;R->parent = 0;

}}

delete N.currNode;delete N.currNode;

return 1;return 1;

}}

N->

L->

R->

I->

root->

Page 48: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations// case 2: N has no right child and has parent// case 2: N has no right child and has parent

if (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = L;P->lchild = L;

if (L) {if (L) {

L->parent = P;L->parent = P;

}}

} else if (N.IsRightChild()) {} else if (N.IsRightChild()) {

P->rchild = L;P->rchild = L;

if (L) {if (L) {

L->parent = PL->parent = P

}}

} else { // case 3: N has no right child and has no parent} else { // case 3: N has no right child and has no parent

root = L;root = L;

if (L) {if (L) {

L->parent = 0;L->parent = 0;

}}

}}

delete N.currNode;delete N.currNode;

return 1;return 1;

}}

N->

L->

I-> P->

Page 49: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations// case 2: N has no right child and has parent// case 2: N has no right child and has parent

if (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = L;P->lchild = L;

if (L) {if (L) {

L->parent = P;L->parent = P;

}}

} else if (N.IsRightChild()) {} else if (N.IsRightChild()) {

P->rchild = L;P->rchild = L;

if (L) {if (L) {

L->parent = PL->parent = P

}}

} else { // case 3: N has no right child and has no parent} else { // case 3: N has no right child and has no parent

root = L;root = L;

if (L) {if (L) {

L->parent = 0;L->parent = 0;

}}

}}

delete N.currNode;delete N.currNode;

return 1;return 1;

}}

L->

I-> P->

Page 50: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations// case 2: N has no right child and has parent// case 2: N has no right child and has parent

if (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = L;P->lchild = L;

if (L) {if (L) {

L->parent = P;L->parent = P;

}}

} else if (N.IsRightChild()) {} else if (N.IsRightChild()) {

P->rchild = L;P->rchild = L;

if (L) {if (L) {

L->parent = PL->parent = P

}}

} else { // case 3: N has no right child and has no parent} else { // case 3: N has no right child and has no parent

root = L;root = L;

if (L) {if (L) {

L->parent = 0;L->parent = 0;

}}

}}

delete N.currNode;delete N.currNode;

return 1;return 1;

}}

N->

L->

P->

Page 51: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations// case 2: N has no right child and has parent// case 2: N has no right child and has parent

if (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = L;P->lchild = L;

if (L) {if (L) {

L->parent = P;L->parent = P;

}}

} else if (N.IsRightChild()) {} else if (N.IsRightChild()) {

P->rchild = L;P->rchild = L;

if (L) {if (L) {

L->parent = PL->parent = P

}}

} else { // case 3: N has no right child and has no parent} else { // case 3: N has no right child and has no parent

root = L;root = L;

if (L) {if (L) {

L->parent = 0;L->parent = 0;

}}

}}

delete N.currNode;delete N.currNode;

return 1;return 1;

}}

L->

P->

Page 52: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations// case 2: N has no right child and has parent// case 2: N has no right child and has parent

if (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = L;P->lchild = L;

if (L) {if (L) {

L->parent = P;L->parent = P;

}}

} else if (N.IsRightChild()) {} else if (N.IsRightChild()) {

P->rchild = L;P->rchild = L;

if (L) {if (L) {

L->parent = PL->parent = P

}}

} else { // case 3: N has no right child and has no parent} else { // case 3: N has no right child and has no parent

root = L;root = L;

if (L) {if (L) {

L->parent = 0;L->parent = 0;

}}

}}

delete N.currNode;delete N.currNode;

return 1;return 1;

}}

N->

L->

root->

Page 53: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operations// case 2: N has no right child and has parent// case 2: N has no right child and has parent

if (N.IsLeftChild()) {if (N.IsLeftChild()) {

P->lchild = L;P->lchild = L;

if (L) {if (L) {

L->parent = P;L->parent = P;

}}

} else if (N.IsRightChild()) {} else if (N.IsRightChild()) {

P->rchild = L;P->rchild = L;

if (L) {if (L) {

L->parent = PL->parent = P

}}

} else { // case 3: N has no right child and has no parent} else { // case 3: N has no right child and has no parent

root = L;root = L;

if (L) {if (L) {

L->parent = 0;L->parent = 0;

}}

}}

delete N.currNode;delete N.currNode;

return 1;return 1;

}}

L->root->

Page 54: Trees 3:  Construction of Dynamic Binary Trees

Tree OperationsTree Operationstemplate <typename T>template <typename T>

size_t TBinaryTree<T>::Remove(const T& t) {size_t TBinaryTree<T>::Remove(const T& t) {

size_t count(0);size_t count(0);

TBinaryTree<T>::Iterator I = Begin();TBinaryTree<T>::Iterator I = Begin();

while (I.Valid()) {while (I.Valid()) {

if (t == *I) {if (t == *I) {

Remove(I);Remove(I);

++count;++count;

} else {} else {

++I;++I;

}}

}}

return count;return count;

}}