1 trees & more tables (walls & mirrors - chapter 10 & beginning of 11)

61
1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

Post on 21-Dec-2015

214 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

1

Trees & More Tables

(Walls & Mirrors - Chapter 10 & Beginning of 11)

Page 2: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

2

Overview

• Terminology

• Binary Trees

• Pointer-Based Representation of a Binary Tree

• Array-Based Representation of a Binary Tree

• Traversing a Binary Tree

• Binary Search Tree Implementation of a Table

• Treesort

Page 3: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

3

Terminology

• A tree is a collection of nodes and directed edges, satisfying the following properties:

– There is one specially designated node called the root, which has no edges pointing to it.

– Every node except the root has exactly one edge pointing to it.

– There is a unique path (of nodes and edges) from the root to each node.

Page 4: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

4

Graphical Representation

• Trees, as defined on the preceding slide, are typically drawn with circles (or rectangles) representing the nodes and arrows representing the edges.

• The root is typically placed at the top of the diagram, with the rest of the tree below it.

Trees: Not Trees:root

edge

node

Page 5: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

5

Terminology (Cont’d.)

• If an edge goes from node a to node b, then a is called the parent of b, and b is called a child of a.

• Children of the same parent are called siblings.

• If there is a path from a to b, then a is called an ancestor of b, and b is called a descendent of a.

• A node with all of its descendants is called a subtree.

• If a node has no children, then it is called a leaf of the tree.

• If a node has no parent (there will be exactly one of these), then it is the root of the tree.

Page 6: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

6

Terminology: Example

A

B C

D EF

G H

I

J K

• A is the root

• D, E, G, H, J & K are leaves

• B is the parent of D, E & F

• D, E & F are siblings and children of B

• I, J & K are descendants of B

• A & B are ancestors of I

subtree

Page 7: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

7

Binary Trees• Intuitively, a binary tree is LIKE a tree in which each node has

no more than two children.

• Formally, a binary tree is a set T of nodes such that either:

– T is empty, or

– T consists of a single node, r, called the root, and two (non-overlapping) binary trees, called the left and right subtrees of r.

• UNLIKE trees, binary trees may be empty, and they distinguish between left and right subtrees.

(These two binarytrees are distinct.)

Page 8: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

8

Binary Search Trees

• A binary search tree is a binary tree in which each node, n, has a value satisfying the following properties:

– n’s value is > all values in its left subtree, TL,

– n’s value is < all values in its right subtree, TR, and

– TL and TR are both binary search trees.

John

PeterBrenda

Amy Mary Tom

21

2

3

55

34

135

8

Page 9: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

9

Terminology (Cont’d.)

• Intuitively, the level of a node is the number of nodes on a path from the root to the node.

• Formally, level of node, n:

– If n is the root of a tree, then it is at level 1.

– Otherwise, its level is 1 greater than the level of its parent.

• Height of binary tree, T:

– If T is empty, its height is 0.

– Otherwise, its height is the maximum level of its nodes, or, equivalently, 1 greater than the height of the root’s taller subtree. Namely,

height(T) = 1 + max { height( TL ), height(TR ) }

Page 10: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

10

Terminology (Cont’d.)• Intuitively, a binary tree is full if it has no missing nodes.

• Formally, a binary tree of height h is full if

– It is empty (h = 0).

– Otherwise, the root’s subtrees are full binary trees of height h – 1.

• If not empty, each node has 2 children, except the nodes at level h which have no children.

• Alternatively, the binary tree has all of its leaves at level h.

Page 11: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

11

Terminology (Cont’d.)

• Intuitively, a binary tree of height h is complete if it is full down to level h – 1, and level h is filled from left to right.

• Formally, a binary tree of height h is complete if

– All nodes at level h – 2 and above have 2 children each,

– If a node at level h – 1 has children, all nodes to its left at the same level have 2 children each, and

– If a node at level h – 1 has 1 child, it is a left child.

Page 12: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

12

Terminology (Cont’d.)

• A binary tree is balanced if the difference in height between any node’s left and right subtree is 1.

• Note that:

– A full binary tree is also complete.

– A complete binary tree is not always full.

– Full and complete binary trees are also balanced.

– Balanced binary trees are not always full or complete.

Page 13: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

13

Binary Tree: Pointer-Based Representationstruct TreeNode; // Binary Tree nodes are struct’stypedef string TreeItemType; // items in TreeNodes are string’s

class BinaryTree{ public: // declarations of public member functions private: TreeNode *root; // pointer to root of Binary Tree};

struct TreeNode // node in a Binary Tree:{ // place in Implementation file TreeItemType item; TreeNode *leftChild; // pointer to TreeNode’s left child TreeNode *rightChild; // pointer to TreeNode’s right child};

Page 14: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

14

Binary Tree: Array-Based Representation

Basic Idea:

• Instead of using pointers to the left and right child of a node, use indices into the array of nodes representing the binary tree.

• Also, use variable free as an index to the first position in the array that is available for a new entry. Use either the left or right child indices to indicate additional, available positions.

• Together, the list of available positions in the array is called the free list.

Page 15: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

15

Binary Tree: Array-Based Representation

Index Item LeftChild

RightChild

0 Jane 1 2

1 Bob 3 4

2 Tom 5 -1

3 Alan -1 -1

4 Ellen -1 -1

5 Nancy -1 -1

6 ? -1 7

7 ? -1 8

8 ? -1 9

9 . . . . . . . . .

root

0

free

6 Jane

Alan

TomBob

NancyEllen

Page 16: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

16

Binary Tree: Array-Based Representation

Index Item LeftChild

RightChild

0 Jane 1 2

1 Bob 3 4

2 Tom 5 -1

3 Alan -1 -1

4 Ellen -1 -1

5 Nancy 6 -1

6 Mary -1 -1

7 ? -1 8

8 ? -1 9

9 . . . . . . . . .

root

0

free

7

* Mary Added under Nancy.

Jane

Alan

TomBob

NancyEllen

Mary

Page 17: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

17

Binary Tree: Array-Based Representation

Index Item LeftChild

RightChild

0 Jane 1 2

1 Bob 3 -1

2 Tom 5 -1

3 Alan -1 -1

4 ? -1 7

5 Nancy 6 -1

6 Mary -1 -1

7 ? -1 8

8 ? -1 9

9 . . . . . . . . .

root

0

free

4

* Ellen deleted.

Jane

Alan

TomBob

Nancy

Mary

Page 18: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

18

Binary Tree: Array-Based Representationconst int MaxNodes = 100; // maximum size of a Binary Treetypedef string TreeItemType; // items in TreeNodes are string’s

struct TreeNode // node in a Binary Tree{ TreeItemType item; int leftChild; // index of TreeNode’s left child int rightChild; // index of TreeNode’s right child};

class BinaryTree{ public: // declarations of public member functions private: TreeNode node[MaxNodes]; int root; // index of root of Binary Tree int free; // index of free list, linked by

rightChild};

Page 19: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

19

Traversing a Binary Tree

• Preorder

• Inorder

• Postorder

Page 20: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

20

Preorder Traversal of a Binary Tree

Basic Idea:

1) Visit the root.

2) Recursively invoke preorder on the left subtree.

3) Recursively invoke preorder on the right subtree.

Page 21: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

21

Preorder Traversal of a Binary Tree

Preorder Result: 60, 20, 10, 40, 30, 50, 70

60

4010

7020

30 50

1

4

5

3

2 7

6

Page 22: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

22

Inorder Traversal of a Binary Tree

Basic Idea:

1) Recursively invoke inorder on the left subtree.

2) Visit the root.

3) Recursively invoke inorder on the right subtree.

Page 23: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

23

Inorder Traversal of a Binary Tree

Inorder Result: 10, 20, 30, 40, 50, 60, 70

60

4010

7020

30 50

6

4

3

1

2 7

5

Page 24: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

24

Postorder Traversal of a Binary Tree

Basic Idea:

1) Recursively invoke postorder on the left subtree.

2) Recursively invoke postorder on the right subtree.

3) Visit the root.

Page 25: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

25

Postorder Traversal of a Binary Tree

Postorder Result: 10, 30, 50, 40, 20, 70, 60

60

4010

7020

30 50

7

4

2

1

5 6

3

Page 26: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

26

Pointer-Based, Preorder Traversal in C++

// FunctionType is a pointer to a function with argument// (TreeItemType &) that returns void.

typedef void (*FunctionType) (TreeItemType &treeItem);

// Public member function

void BinaryTree::preorderTraverse( FunctionType visit ){ preorder( root, visit );}

Page 27: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

27

Pointer-Based, Preorder Traversal in C++

// Private member function

void BinaryTree::preorder( TreeNode *treePtr, FunctionType visit ){ if( treePtr != NULL ) { visit( treePtr -> item );

preorder( treePtr -> leftChild, visit );

preorder( treePtr -> rightChild, visit ); }}

Page 28: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

28

Pointer-Based, Preorder Traversal in C++

Suppose that we define the function

void printItem( TreeItemType &treeItem ) { cout << treeItem << endl; }

Then, // create myTree BinaryTree myTree;

// load data into myTree . . .

// print TreeItems encountered in preorder traversal of myTree myTree.preorderTraverse( &printItem );

Page 29: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

29

Pointer-Based,Inorder & Postorder Traversal

The functions for Inorder and Postorder traversal of a binary tree are very similar to the function for Preorder traversal, and are left as an exercise.

Page 30: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

30

Nonrecursive Traversal of a Binary Tree

Basic Idea for a Nonrecursive, Inorder Traversal:

1) Push a pointer to the root of the binary tree onto a stack.

2) Follow leftChild pointers, pushing each one onto the stack, until a NULL leftChild pointer is found.

3) Process (visit) the item in this node.

4) Get the node’s rightChild pointer:

– If it is not NULL, then push it onto the stack, and return to step 2 with the leftChild pointer of this rightChild.

– If it is NULL, then pop a node pointer from the stack, and return to step 3. If the stack is empty (so nothing could be popped), then stop — the traversal is done.

Page 31: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

31

Nonrecursive Traversal of a Binary Tree

• The logic for a nonrecursive, preorder or postorder traversal is similar to what was presented on the previous slide for an inorder traversal.

• ~14 lines of code (see chapter 10 of Walls & Mirrors) plus the code for manipulating a stack are required to implement a nonrecursive traversal. Compare this with the 5 lines of code that were required for our recursive solutions.

• This example illustrates how recursion can sometimes be used to produce a clear and concise implementation.

Page 32: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

32

Binary Search Tree Implementationof a Table

Recall that the supported operations for an ADT Table include:

– Create an empty table

– Destroy a table

– Determine whether a table is empty

– Determine the number of items in a table

– Insert a new item into a table

– Delete the item with a given search key from a table

– Retrieve the item with a given search key from a table

– Traverse the items in a table in sorted, search-key order

Page 33: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

33

Table: Binary Search Tree Implementationtypedef string KeyType; // Table search-keys are strings

struct dataItem // all data for an item is put into

{ KeyType key; // one struct for convenience

// other data members are included here};

typedef dataItem TableItemType; // items in Table are dataItems

// returns tableItem’s searchKeyKeyType getKey( const TableItemType &tableItem )

{ return( tableItem.key );}

// FunctionType is a pointer to a function with argument // (TableItemType &) that returns void, used by Table traverse( )

typedef void (*FunctionType) (TableItemType &tableItem);

Page 34: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

34

Table: Binary Search Tree Implementationtypedef TableItemType TreeItemType; // TableItems are storedstruct TreeNode; // in TreeNodes

class Table{ public: // declarations of public member functions private: TreeNode *root; // root of Binary Search Tree int size; // number of items in Table};

struct TreeNode // node in a Binary Search Tree:{ // place in Implementation file TreeItemType item; TreeNode *leftChild; // pointer to TreeNode’s left child TreeNode *rightChild; // pointer to TreeNode’s right child};

Page 35: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

35

Table: Binary Search Tree ImplementationAn alternative (and perhaps, better) implementation of a Table as a Binary Search Tree would define

struct dataItem{ KeyType key; // other data members are included here};

andstruct TreeNode{ TreeItemType item; TreeNode *leftChild; TreeNode *rightChild;};

as Classes, with constructors to set the key for a dataItem and to initialize leftChild and rightChild to NULL. getKey( ) would become a public member function, providing access to key.(See chapter 10 of Walls & Mirrors for details.)

Page 36: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

36

Table: Public Member Function Definitions

// default constructor, which creates a new empty Table

Table::Table( ) : root( NULL ), size( 0 ) { }

// copy constructor, which copies origTable to a new Table

Table::Table( const Table &origTable )

{ copyTree( origTable.root, root );

size = origTable.size;

}

// destructor, which destroys a Table

Table::~Table( )

{ destroyTree( root );

}

Page 37: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

37

Table: Private Member Function Definition

// copies tree rooted at origTreePtr to a new tree rooted at newTreePtr

void Table::copyTree( TreeNode *origTreePtr,

TreeNode *&newTreePtr ) const

{ if( origTreePtr != NULL ) // copy nodes using preorder traversal

{ newTreePtr = new TreeNode;

assert( newTreePtr != NULL );

newTreePtr -> item = origTreePtr -> item;

copyTree( origTreePtr -> leftChild, newTreePtr -> leftChild );

copyTree( origTreePtr -> rightChild, newTreePtr -> rightChild );

}

else

newTreePtr = NULL;

}

Page 38: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

38

Table: Private Member Function Definition

// destroys tree rooted at treePtr

void Table::destroyTree( TreeNode *&treePtr )

{

if( treePtr != NULL )

{ // delete nodes using postorder traversal

destroyTree( treePtr -> leftChild );

destroyTree( treePtr -> rightChild );

delete treePtr;

treePtr = NULL;

}

}

Page 39: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

39

Table: Public Member Function Definitions

// returns true if the Table is empty, otherwise returns false

bool Table::isEmpty( ) const

{ return size = = 0;

}

// returns the number of items in the Table

int Table::length( ) const

{ return size;

}

Page 40: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

40

Table: Public Member Function Definitions// inserts newItem into a Table in sorted order

bool Table::insert( TableItemType &newItem )

{ if( treeInsertItem( root, newItem ) )

{ size++; return true; } return false;}

// removes item with the given searchKey from a Table

bool Table::remove( KeyType searchKey )

{ if( treeDeleteItem( root, searchKey ) )

{ size – –; return true; } return false;}

Page 41: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

41

Table: Public Member Function Definitions

// retrieves a copy of item with the given searchKey from a Table

bool Table::retrieve( KeyType searchKey,

TableItemType &tableItem ) const

{

return treeRetrieveItem( root, searchKey, tableItem );}

Page 42: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

42

Table: Private Member Function Definition// inserts newItem into a Binary Search Tree rooted at treePtr

bool Table::treeInsertItem( TreeNode *&treePtr, const TreeItemType &newItem )

{ if( treePtr = = NULL ) { treePtr = new TreeNode; assert( treePtr != NULL ); treePtr -> item = newItem; treePtr -> leftChild = treePtr -> rightChild = NULL; return true; }

if( getKey( newItem ) = = getKey( treePtr -> item ) ) return false;

if( getKey( newItem ) < getKey( treePtr -> item ) ) return treeInsertItem( treePtr -> leftChild, newItem ); else return treeInsertItem( treePtr -> rightChild, newItem );}

Page 43: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

43

Table: Private Member Function Definition// retrieves a copy of item with the given searchKey from a Binary// Search Tree rooted at treePtr

bool Table::treeRetrieveItem( TreeNode *treePtr, KeyType searchKey, TreeItemType &treeItem ) const

{ if( treePtr = = NULL ) return false;

KeyType itemKey = getKey( treePtr -> item );

if( searchKey = = itemKey ) { treeItem = treePtr -> item; return true;

}

if( searchKey < itemKey ) return treeRetrieveItem( treePtr -> leftChild, searchKey, treeItem );

else return treeRetrieveItem( treePtr -> rightChild, searchKey, treeItem );}

Page 44: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

44

Table: Private Member Function Definition

// deletes item with the given searchKey from a Binary Search Tree// rooted at treePtr

bool Table::treeDeleteItem( TreeNode *&treePtr, KeyType searchKey )

{ if( treePtr = = NULL ) return false;

KeyType itemKey = getKey( treePtr -> item );

if( searchKey = = itemKey ) { treeDeleteNode( treePtr ); return true; }

if( searchKey < itemKey ) return treeDeleteItem( treePtr -> leftChild, searchKey );

else return treeDeleteItem( treePtr -> rightChild, searchKey );

}

Page 45: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

45

Delete Node at treePtr from a Tree

There are 4 cases:

1) treePtr points to a leaf

2) treePtr points to a node with no leftChild

3) treePtr points to a node with no rightChild

4) treePtr points to a node with both leftChild and rightChild

Page 46: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

46

Table: Private Member Function Definition

// delete node at treePtr from a tree

void Table::treeDeleteNode( TreeNode *&treePtr )

{ if( treePtr -> leftChild = = NULL && treePtr -> rightChild = = NULL ) { /* delete leaf pointed to by treePtr */ }

else if( treePtr -> leftChild = = NULL ) { /* delete node at treePtr, making treePtr point to rightChild */ }

else if( treePtr -> rightChild = = NULL ) { /* delete node at treePtr, making treePtr point to leftChild */ }

else { /* copy item from leftmost descendant of rightChild */ /* to node at treePtr; delete leftmost descendant */ }}

Page 47: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

47

Case 1: treePtr Points to a Leaf

1) Delete the leaf

2) Set treePtr to NULL

60

4010

7020

30 50

treePtr

Page 48: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

48

Case 1: treePtr Points to a Leaf

/* delete leaf pointed to by treePtr */

delete treePtr;

treePtr = NULL;

Page 49: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

49

Case 2: treePtr Points to a Node with No leftChild

1) Save treePtr to delPtr

2) Set treePtr to treePtr -> rightChild

3) Delete node at delPtr

70

3010

8020

50

treePtr

delPtr

40 60

Page 50: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

50

Case 2: treePtr Points to a Node with No leftChild

/* delete node at treePtr, making treePtr point to rightChild */

TreeNode *delPtr = treePtr;

treePtr = treePtr -> rightChild;

delPtr -> rightChild = NULL;

delete delPtr;

Page 51: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

51

Case 3: treePtr Points to a Node with No rightChild

1) Save treePtr to delPtr

2) Set treePtr to treePtr -> leftChild

3) Delete node at delPtr

treePtr

70

6010

8020

40

delPtr

30 50

Page 52: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

52

Case 3: treePtr Points to a Node with No rightChild

/* delete node at treePtr, making treePtr point to leftChild */

TreeNode *delPtr = treePtr;

treePtr = treePtr -> leftChild;

delPtr -> leftChild = NULL;

delete delPtr;

Page 53: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

53

Case 4: treePtr Points to a Node with Both leftChild and rightChild

1) Let nodePtr be the TreeNode pointer that points to the leftmost descendant of treePtr -> rightChild

2) Save nodePtr -> item to treeItem

3) Save nodePtr to delPtr

4) Set nodePtr to nodePtr -> rightChild

5) Delete node at delPtr

6) Set treePtr -> item to treeItem

treeItem 50

60

90

7020

9540

50 80

treePtr

3010

nodePtr

delPtr

Page 54: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

54

Case 4: treePtr Points to a Node with Both leftChild and rightChild

/* copy item from leftmost descendant of rightChild to node *//* at treePtr; delete leftmost descendant */

TreeItemType leftmostItem;

processLeftmost( treePtr -> rightChild, leftmostItem );

treePtr -> item = leftmostItem;

Page 55: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

55

Table: Private Member Function Definition

/* find leftmost descendant of the node pointed to by nodePtr; *//* copy its item to treeItem, then delete it */

void Table::processLeftmost( TreeNode *&nodePtr, TreeItemType &treeItem )

{ if( nodePtr -> leftChild != NULL )

processLeftmost( nodePtr -> leftChild, treeItem ); else { treeItem = nodePtr -> item;

TreeNode *delPtr = nodePtr;

nodePtr = nodePtr -> rightChild;

delPtr -> rightChild = NULL;

delete delPtr; }}

Page 56: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

56

Table: Public Member Function Definition

// traverses a Table in sorted search-key order, calling// function visit( ) once for each item in the Table

void Table::traverse( FunctionType visit )

{

treeTraverse( root, visit );

}

Page 57: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

57

Table: Private Member Function Definition

// performs inorder traverse of a Binary Search Tree, calling// function visit( ) once at each node in the tree

void Table::treeTraverse( TreeNode *treePtr, FunctionType visit )

{ if( treePtr != NULL )

{

treeTraverse( treePtr -> leftChild, visit );

visit( treePtr -> item );

treeTraverse( treePtr -> rightChild, visit );

}

}

Page 58: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

58

Treesort: Basic Idea

Problem: Sort an array of items into search-key order.

1) Insert items from the array into a Binary Search Tree (or Binary-Search-Tree-based Table).

2) Perform an inorder traversal of the Binary Search Tree, copying each item back into the array.

When step 2 is done, the array will be in sorted order!

Page 59: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

59

Treesort

void treeSort( TableItemType a[ ], int n )

{ Table table;

// insert items from a[ ] into table

for( int i = 0; i < n; i++ )

table.insert( a[i] );

// copy items from table into a[ ] in sorted, search-key order

table.traverse( &copyItem, a );

}

void copyItem( TableItemType &tableItem, TableItemType a[ ] )

{ static int k = 0;

a[k++] = tableItem;

}

Page 60: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

60

Treesort (Cont’d.)

typedef void (*FunctionType2) (TableItemType &tableItem,

TableItemType a[ ] );

void Table::traverse( FunctionType2 visit, TableItemType a[ ] )

{ treeTraverse( root, visit, a );

}

void Table::treeTraverse( TreeNode *treePtr,FunctionType2 visit, TableItemType a[ ] );

{ if( treePtr != NULL )

{ treeTraverse( treePtr -> leftChild, visit, a );

visit( treePtr -> item, a );

treeTraverse( treePtr -> rightChild, visit, a );

}

}

Page 61: 1 Trees & More Tables (Walls & Mirrors - Chapter 10 & Beginning of 11)

61

Treesort: Efficiency

• Each insertion into a Binary Search Tree requires O( log n ) operations in the best and average cases and O( n ) operations in the worst case.

• So, performing n insertions requires O( n * log n ) operations in the best and average cases and O( n2 ) operations in the worst case.

• Traversal of the Binary Search Tree requires O( n ) operations in all cases.

• Therefore, the overall Growth Rate of Treesort is O( n * log n ) operations in the best and average cases and O( n2 ) operations in the worst case — the same as Quicksort.

• Binary-Search-Tree algorithms are efficient as long as the tree is balanced. If not balanced, Binary-Search-Tree algorithms can become as inefficient as algorithms on a linear List. We will learn about maintaining balanced trees in the coming chapters.