CSCS-200 Data Structure and Algorithms Lecture-19-20.

Post on 06-Jan-2018

222 views 0 download

description

3 Level-order Traversal Level-order:

transcript

CSCS-200 Data Structure and Algorithms

Lecture-19-20

2

Level-order Traversal

• There is yet another way of traversing a binary tree that is not related to recursive traversal procedures discussed previously.

• In level-order traversal, we visit the nodes at each level before proceeding to the next level.

• At each level, we visit the nodes in a left-to-right order.

3

Level-order Traversal

Level-order: 14 4 15 3 9 18 7 16 20 5 17

14

4

9

7

3

5

15

18

16 20

17

4

Level-order Traversal

• How do we do level-order traversal?• Surprisingly, if we use a queue instead of

a stack, we can visit the nodes in level-order.

• Here is the code for level-order traversal:

5

Level-order Traversalvoid levelorder(TreeNode<int>* treeNode){ Queue<TreeNode<int>* > q; if( treeNode == NULL ) return; q.enqueue( treeNode); while( !q.empty() ) { treeNode = q.dequeue(); cout << *(treeNode->getInfo()) << " "; if(treeNode->getLeft() != NULL )

q.enqueue( treeNode->getLeft()); if(treeNode->getRight() != NULL )

q.enqueue( treeNode->getRight()); } cout << endl;}

6

Level-order Traversalvoid levelorder(TreeNode<int>* treeNode){ Queue<TreeNode<int>* > q; if( treeNode == NULL ) return; q.enqueue( treeNode); while( !q.empty() ) { treeNode = q.dequeue(); cout << *(treeNode->getInfo()) << " "; if(treeNode->getLeft() != NULL )

q.enqueue( treeNode->getLeft()); if(treeNode->getRight() != NULL )

q.enqueue( treeNode->getRight()); } cout << endl;}

7

Level-order Traversalvoid levelorder(TreeNode<int>* treeNode){ Queue<TreeNode<int>* > q; if( treeNode == NULL ) return; q.enqueue( treeNode); while( !q.empty() ) { treeNode = q.dequeue(); cout << *(treeNode->getInfo()) << " "; if(treeNode->getLeft() != NULL )

q.enqueue( treeNode->getLeft()); if(treeNode->getRight() != NULL )

q.enqueue( treeNode->getRight()); } cout << endl;}

8

Level-order Traversalvoid levelorder(TreeNode<int>* treeNode){ Queue<TreeNode<int>* > q; if( treeNode == NULL ) return; q.enqueue( treeNode); while( !q.empty() ) { treeNode = q.dequeue(); cout << *(treeNode->getInfo()) << " "; if(treeNode->getLeft() != NULL )

q.enqueue( treeNode->getLeft()); if(treeNode->getRight() != NULL )

q.enqueue( treeNode->getRight()); } cout << endl;}

9

Level-order Traversalvoid levelorder(TreeNode<int>* treeNode){ Queue<TreeNode<int>* > q; if( treeNode == NULL ) return; q.enqueue( treeNode); while( !q.empty() ) { treeNode = q.dequeue(); cout << *(treeNode->getInfo()) << " "; if(treeNode->getLeft() != NULL )

q.enqueue( treeNode->getLeft()); if(treeNode->getRight() != NULL )

q.enqueue( treeNode->getRight()); } cout << endl;}

10

Level-order Traversalvoid levelorder(TreeNode<int>* treeNode){ Queue<TreeNode<int>* > q; if( treeNode == NULL ) return; q.enqueue( treeNode); while( !q.empty() ) { treeNode = q.dequeue(); cout << *(treeNode->getInfo()) << " "; if(treeNode->getLeft() != NULL )

q.enqueue( treeNode->getLeft()); if(treeNode->getRight() != NULL )

q.enqueue( treeNode->getRight()); } cout << endl;}

11

Level-order Traversalvoid levelorder(TreeNode<int>* treeNode){ Queue<TreeNode<int>* > q; if( treeNode == NULL ) return; q.enqueue( treeNode); while( !q.empty() ) { treeNode = q.dequeue(); cout << *(treeNode->getInfo()) << " "; if(treeNode->getLeft() != NULL )

q.enqueue( treeNode->getLeft()); if(treeNode->getRight() != NULL )

q.enqueue( treeNode->getRight()); } cout << endl;}

12

Level-order Traversalvoid levelorder(TreeNode<int>* treeNode){ Queue<TreeNode<int>* > q; if( treeNode == NULL ) return; q.enqueue( treeNode); while( !q.empty() ) { treeNode = q.dequeue(); cout << *(treeNode->getInfo()) << " "; if(treeNode->getLeft() != NULL )

q.enqueue( treeNode->getLeft()); if(treeNode->getRight() != NULL )

q.enqueue( treeNode->getRight()); } cout << endl;}

13

Level-order Traversal

Queue: 14Output:

14

4

9

7

3

5

15

18

16 20

17

14

Level-order Traversal

Queue: 4 15Output: 14

14

4

9

7

3

5

15

18

16 20

17

15

Level-order Traversal

Queue: 15 3 9Output: 14 4

14

4

9

7

3

5

15

18

16 20

17

16

Level-order Traversal

Queue: 3 9 18Output: 14 4 15

14

4

9

7

3

5

15

18

16 20

17

17

Level-order Traversal

Queue: 9 18Output: 14 4 15 3

14

4

9

7

3

5

15

18

16 20

17

18

Level-order Traversal

Queue: 18 7Output: 14 4 15 3 9

14

4

9

7

3

5

15

18

16 20

17

19

Level-order Traversal

Queue: 7 16 20Output: 14 4 15 3 9 18

14

4

9

7

3

5

15

18

16 20

17

20

Level-order Traversal

Queue: 16 20 5Output: 14 4 15 3 9 18 7

14

4

9

7

3

5

15

18

16 20

17

21

Level-order Traversal

Queue: 20 5 17Output: 14 4 15 3 9 18 7 16

14

4

9

7

3

5

15

18

16 20

17

22

Level-order Traversal

Queue: 5 17Output: 14 4 15 3 9 18 7 16 20

14

4

9

7

3

5

15

18

16 20

17

23

Level-order Traversal

Queue: 17Output: 14 4 15 3 9 18 7 16 20 5

14

4

9

7

3

5

15

18

16 20

17

24

Level-order Traversal

Queue:Output: 14 4 15 3 9 18 7 16 20 5 17

14

4

9

7

3

5

15

18

16 20

17

25

Storing other Type of Data

• The examples of binary trees so far have been storing integer data in the tree node.

• This is surely not a requirement. Any type of data can be stored in a tree node.

• Here, for example, is the C++ code to build a tree with character strings.

26

Binary Search Tree with Stringsvoid wordTree(){

TreeNode<char>* root = new TreeNode<char>();static char* word[] = "babble", "fable", "jacket", "backup", "eagle","daily","gain","bandit","abandon", "abash","accuse","economy","adhere","advise","cease", "debunk","feeder","genius","fetch","chain", NULL};root->setInfo( word[0] );

for(i=1; word[i]; i++ )

insert(root, word[i] );inorder( root ); cout << endl;

}

27

Binary Search Tree with Stringsvoid wordTree(){

TreeNode<char>* root = new TreeNode<char>();static char* word[] = "babble", "fable", "jacket", "backup", "eagle","daily","gain","bandit","abandon", "abash","accuse","economy","adhere","advise","cease", "debunk","feeder","genius","fetch","chain", NULL};root->setInfo( word[0] );

for(i=1; word[i]; i++ )

insert(root, word[i] );inorder( root ); cout << endl;

}

28

Binary Search Tree with Stringsvoid wordTree(){

TreeNode<char>* root = new TreeNode<char>();static char* word[] = "babble", "fable", "jacket", "backup", "eagle","daily","gain","bandit","abandon", "abash","accuse","economy","adhere","advise","cease", "debunk","feeder","genius","fetch","chain", NULL};root->setInfo( word[0] );

for(i=1; word[i]; i++ )

insert(root, word[i] );inorder( root ); cout << endl;

}

29

Binary Search Tree with Stringsvoid wordTree(){

TreeNode<char>* root = new TreeNode<char>();static char* word[] = "babble", "fable", "jacket", "backup", "eagle","daily","gain","bandit","abandon", "abash","accuse","economy","adhere","advise","cease", "debunk","feeder","genius","fetch","chain", NULL};root->setInfo( word[0] );

for(i=1; word[i]; i++ )

insert(root, word[i] );inorder( root ); cout << endl;

}

30

Binary Search Tree with Stringsvoid wordTree(){

TreeNode<char>* root = new TreeNode<char>();static char* word[] = "babble", "fable", "jacket", "backup", "eagle","daily","gain","bandit","abandon", "abash","accuse","economy","adhere","advise","cease", "debunk","feeder","genius","fetch","chain", NULL};root->setInfo( word[0] );

for(i=1; word[i]; i++ )

insert(root, word[i] );inorder( root ); cout << endl;

}

31

Binary Search Tree with Stringsvoid insert(TreeNode<char>* root, char* info){ TreeNode<char>* node = new TreeNode<char>(info); TreeNode<char> *p, *q; p = q = root; while( strcmp(info, p->getInfo()) != 0 && q != NULL ) { p = q; if( strcmp(info, p->getInfo()) < 0 ) q = p->getLeft(); else q = p->getRight(); }

32

Binary Search Tree with Stringsvoid insert(TreeNode<char>* root, char* info){ TreeNode<char>* node = new TreeNode<char>(info); TreeNode<char> *p, *q; p = q = root; while( strcmp(info, p->getInfo()) != 0 && q != NULL ) { p = q; if( strcmp(info, p->getInfo()) < 0 ) q = p->getLeft(); else q = p->getRight(); }

33

Binary Search Tree with Stringsvoid insert(TreeNode<char>* root, char* info){ TreeNode<char>* node = new TreeNode<char>(info); TreeNode<char> *p, *q; p = q = root; while( strcmp(info, p->getInfo()) != 0 && q != NULL ) { p = q; if( strcmp(info, p->getInfo()) < 0 ) q = p->getLeft(); else q = p->getRight(); }

34

Binary Search Tree with Stringsvoid insert(TreeNode<char>* root, char* info){ TreeNode<char>* node = new TreeNode<char>(info); TreeNode<char> *p, *q; p = q = root; while( strcmp(info, p->getInfo()) != 0 && q != NULL ) { p = q; if( strcmp(info, p->getInfo()) < 0 ) q = p->getLeft(); else q = p->getRight(); }

35

Binary Search Tree with Stringsvoid insert(TreeNode<char>* root, char* info){ TreeNode<char>* node = new TreeNode<char>(info); TreeNode<char> *p, *q; p = q = root; while( strcmp(info, p->getInfo()) != 0 && q != NULL ) { p = q; if( strcmp(info, p->getInfo()) < 0 ) q = p->getLeft(); else q = p->getRight(); }

36

Binary Search Tree with Stringsif( strcmp(info, p->getInfo()) == 0 ){

cout << "attempt to insert duplicate: " << *info << endl; delete node;

}else if( strcmp(info, p->getInfo()) < 0 )

p->setLeft( node );else

p->setRight( node ); }

37

Binary Search Tree with Stringsif( strcmp(info, p->getInfo()) == 0 ){

cout << "attempt to insert duplicate: " << *info << endl; delete node;

}else if( strcmp(info, p->getInfo()) < 0 )

p->setLeft( node );else

p->setRight( node ); }

38

Binary Search Tree with Stringsif( strcmp(info, p->getInfo()) == 0 ){

cout << "attempt to insert duplicate: " << *info << endl; delete node;

}else if( strcmp(info, p->getInfo()) < 0 )

p->setLeft( node );else

p->setRight( node ); }

39

Binary Search Tree with StringsOutput:

abandonabashaccuseadhereadvisebabblebackupbanditceasechaindailydebunkeagleeconomyfablefeederfetchgaingeniusjacket

40

Binary Search Tree with Stringsabandonabashaccuseadhereadvisebabblebackupbanditceasechaindailydebunkeagleeconomyfablefeederfetchgaingeniusjacket

Notice that the words are sorted in increasing order when we traversed the tree in inorder manner.

41

Binary Search Tree with Stringsabandonabashaccuseadhereadvisebabblebackupbanditceasechaindailydebunkeagleeconomyfablefeederfetchgaingeniusjacket

Notice that the words are sorted in increasing order when we traversed the tree in inorder manner.

This should not come as a surprise if you consider how we built the BST.

42

Binary Search Tree with Stringsabandonabashaccuseadhereadvisebabblebackupbanditceasechaindailydebunkeagleeconomyfablefeederfetchgaingeniusjacket

Notice that the words are sorted in increasing order when we traversed the tree in inorder manner.

This should not come as a surprise if you consider how we built the BST.

For a given node, values less than the info in the node were all in the left subtree and values greater or equal were in the right.

43

Binary Search Tree with Stringsabandonabashaccuseadhereadvisebabblebackupbanditceasechaindailydebunkeagleeconomyfablefeederfetchgaingeniusjacket

Notice that the words are sorted in increasing order when we traversed the tree in inorder manner.

This should not come as a surprise if you consider how we built the BST.

For a given node, values less than the info in the node were all in the left subtree and values greater or equal were in the right.

Inorder prints the left subtree, then the node finally the right subtree.

44

Binary Search Tree with Stringsabandonabashaccuseadhereadvisebabblebackupbanditceasechaindailydebunkeagleeconomyfablefeederfetchgaingeniusjacket

Notice that the words are sorted in increasing order when we traversed the tree in inorder manner.

This should not come as a surprise if you consider how we built the BST.

For a given node, values less than the info in the node were all in the left subtree and values greater or equal were in the right.

Inorder prints the left subtree, then the node finally the right subtree.

Building a BST and doing an inorder traversal leads to a sorting algorithm.

45

Binary Search Tree with Stringsabandonabashaccuseadhereadvisebabblebackupbanditceasechaindailydebunkeagleeconomyfablefeederfetchgaingeniusjacket

Notice that the words are sorted in increasing order when we traversed the tree in inorder manner.

This should not come as a surprise if you consider how we built the BST.

For a given node, values less than the info in the node were all in the left subtree and values greater or equal were in the right.

Inorder prints the left subtree, then the node finally the right subtree.

Building a BST and doing an inorder traversal leads to a sorting algorithm.

46

Deleting a node in BST

• As is common with many data structures, the hardest operation is deletion.

• Once we have found the node to be deleted, we need to consider several possibilities.

• If the node is a leaf, it can be deleted immediately.

47

Deleting a node in BST• If the node has one child, the node can be

deleted after its parent adjusts a pointer to bypass the node and connect to inorder successor.

6

2

4

3

1

8

48

Deleting a node in BST

• The inorder traversal order has to be maintained after the delete.

6

2

4

3

1

8

6

2

4

3

1

8

49

Deleting a node in BST

• The inorder traversal order has to be maintained after the delete.

6

2

4

3

1

8

6

2

4

3

1

8

6

2

31

8

50

Deleting a node in BST

• The complicated case is when the node to be deleted has both left and right subtrees.

• The strategy is to replace the data of this node with the smallest data of the right subtree and recursively delete that node.

51

Deleting a node in BSTDelete(2): locate inorder successor

6

2

5

3

1

8

4Inorder successor

52

Deleting a node in BSTDelete(2): locate inorder successor

6

2

5

3

1

8

4Inorder successor

Inorder successor will be the left-most node in the right subtree of 2.

The inorder successor will not have a left child because if it did, that child would be the left-most node.

53

Deleting a node in BSTDelete(2): copy data from inorder successor

6

2

5

3

1

8

4

6

3

5

3

1

8

4

54

Deleting a node in BSTDelete(2): remove the inorder successor

6

2

5

3

1

8

4

6

3

5

3

1

8

4

6

3

5

3

1

8

4

55

Deleting a node in BSTDelete(2)

6

3

5

4

1

8

6

3

5

3

1

8

4

56

C++ code for delete

• ‘delete’ is C++ keyword. We will call our deleteNode routine remove.

• Here is the C++ code for remove.

57

C++ code for delete

TreeNode<int>* remove(TreeNode<int>* tree, int info){ TreeNode<int>* t; int cmp = info - *(tree->getInfo()); if( cmp < 0 ){ t = remove(tree->getLeft(), info); tree->setLeft( t ); } else if( cmp > 0 ){ t = remove(tree->getRight(), info); tree->setRight( t ); }

58

C++ code for delete

TreeNode<int>* remove(TreeNode<int>* tree, int info){ TreeNode<int>* t; int cmp = info - *(tree->getInfo()); if( cmp < 0 ){ t = remove(tree->getLeft(), info); tree->setLeft( t ); } else if( cmp > 0 ){ t = remove(tree->getRight(), info); tree->setRight( t ); }

59

C++ code for delete

TreeNode<int>* remove(TreeNode<int>* tree, int info){ TreeNode<int>* t; int cmp = info - *(tree->getInfo()); if( cmp < 0 ){ t = remove(tree->getLeft(), info); tree->setLeft( t ); } else if( cmp > 0 ){ t = remove(tree->getRight(), info); tree->setRight( t ); }

60

C++ code for delete

TreeNode<int>* remove(TreeNode<int>* tree, int info){ TreeNode<int>* t; int cmp = info - *(tree->getInfo()); if( cmp < 0 ){ t = remove(tree->getLeft(), info); tree->setLeft( t ); } else if( cmp > 0 ){ t = remove(tree->getRight(), info); tree->setRight( t ); }

61

C++ code for delete

//two children, replace with inorder successor else if(tree->getLeft() != NULL && tree->getRight() != NULL ){ TreeNode<int>* minNode; minNode = findMin(tree->getRight()); tree->setInfo( minNode->getInfo() ); t = remove(tree->getRight(), *(minNode->getInfo())); tree->setRight( t ); }

62

C++ code for delete

//two children, replace with inorder successor else if(tree->getLeft() != NULL && tree->getRight() != NULL ){ TreeNode<int>* minNode; minNode = findMin(tree->getRight()); tree->setInfo( minNode->getInfo() ); t = remove(tree->getRight(), *(minNode->getInfo())); tree->setRight( t ); }

63

C++ code for delete

//two children, replace with inorder successor else if(tree->getLeft() != NULL && tree->getRight() != NULL ){ TreeNode<int>* minNode; minNode = findMin(tree->getRight()); tree->setInfo( minNode->getInfo() ); t = remove(tree->getRight(), *(minNode->getInfo())); tree->setRight( t ); }

64

C++ code for delete

//two children, replace with inorder successor else if(tree->getLeft() != NULL && tree->getRight() != NULL ){ TreeNode<int>* minNode; minNode = findMin(tree->getRight()); tree->setInfo( minNode->getInfo() ); t = remove(tree->getRight(), *(minNode->getInfo())); tree->setRight( t ); }

65

C++ code for delete

//two children, replace with inorder successor else if(tree->getLeft() != NULL && tree->getRight() != NULL ){ TreeNode<int>* minNode; minNode = findMin(tree->getRight()); tree->setInfo( minNode->getInfo() ); t = remove(tree->getRight(), *(minNode->getInfo())); tree->setRight( t ); }

66

C++ code for delete

else { // case 1 TreeNode<int>* nodeToDelete = tree; if( tree->getLeft() == NULL ) //will handle 0 children tree = tree->getRight(); else if( tree->getRight() == NULL ) tree = tree->getLeft(); else tree = NULL; delete nodeToDelete; } return tree;}

67

C++ code for delete

else { // case 1 TreeNode<int>* nodeToDelete = tree; if( tree->getLeft() == NULL ) //will handle 0 children tree = tree->getRight(); else if( tree->getRight() == NULL ) tree = tree->getLeft(); else tree = NULL; delete nodeToDelete; } return tree;}

68

C++ code for delete

else { // case 1 TreeNode<int>* nodeToDelete = tree; if( tree->getLeft() == NULL ) //will handle 0 children tree = tree->getRight(); else if( tree->getRight() == NULL ) tree = tree->getLeft(); else tree = NULL; delete nodeToDelete; } return tree;}

69

C++ code for delete

TreeNode<int>* findMin(TreeNode<int>* tree){ if( tree == NULL ) return NULL; if( tree->getLeft() == NULL ) return tree; // this is it. return findMin( tree->getLeft() );}

70

C++ code for delete

TreeNode<int>* findMin(TreeNode<int>* tree){ if( tree == NULL ) return NULL; if( tree->getLeft() == NULL ) return tree; // this is it. return findMin( tree->getLeft() );}

71

C++ code for delete

TreeNode<int>* findMin(TreeNode<int>* tree){ if( tree == NULL ) return NULL; if( tree->getLeft() == NULL ) return tree; // this is it. return findMin( tree->getLeft() );}

72

BinarySearchTree.h

Let us design the BinarySearchTree class (factory).

73

BinarySearchTree.h

#ifndef _BINARY_SEARCH_TREE_H_#define _BINARY_SEARCH_TREE_H_#include <iostream.h> // For NULL

// Binary node and forward declarationtemplate <class EType>class BinarySearchTree;

74

BinarySearchTree.h

#ifndef _BINARY_SEARCH_TREE_H_#define _BINARY_SEARCH_TREE_H_#include <iostream.h> // For NULL

// Binary node and forward declarationtemplate <class EType>class BinarySearchTree;

75

BinarySearchTree.h

template <class EType>class BinaryNode{ EType element; BinaryNode *left; BinaryNode *right;

BinaryNode( const EType & theElement, BinaryNode *lt, BinaryNode *rt ) : element( theElement ), left( lt ), right( rt ) { } friend class BinarySearchTree<EType>;};

76

BinarySearchTree.h

template <class EType>class BinaryNode{ EType element; BinaryNode *left; BinaryNode *right;

BinaryNode( const EType & theElement, BinaryNode *lt, BinaryNode *rt ) : element( theElement ), left( lt ), right( rt ) { } friend class BinarySearchTree<EType>;};

77

BinarySearchTree.h

template <class EType>class BinaryNode{ EType element; BinaryNode *left; BinaryNode *right;

BinaryNode( const EType & theElement, BinaryNode *lt, BinaryNode *rt ) : element( theElement ), left( lt ), right( rt ) { } friend class BinarySearchTree<EType>;};

78

BinarySearchTree.h

template <class EType>class BinaryNode{ EType element; BinaryNode *left; BinaryNode *right;

BinaryNode( const EType & theElement, BinaryNode *lt, BinaryNode *rt ) : element( theElement ), left( lt ), right( rt ) { } friend class BinarySearchTree<EType>;};

79

BinarySearchTree.h

template <class EType>class BinarySearchTree{public: BinarySearchTree( const EType& notFound ); BinarySearchTree( const BinarySearchTree& rhs ); ~BinarySearchTree( );

const EType& findMin( ) const; const EType& findMax( ) const; const EType& find( const EType & x ) const; bool isEmpty( ) const; void printInorder( ) const;

80

BinarySearchTree.h

void insert( const EType& x ); void remove( const EType& x );

const BinarySearchTree & operator= ( const BinarySearchTree & rhs );

81

BinarySearchTree.h

private: BinaryNode<EType>* root; // ITEM_NOT_FOUND object used to signal failed finds const EType ITEM_NOT_FOUND;

const EType& elementAt( BinaryNode<EType>* t ); void insert(const EType& x, BinaryNode<EType>* & t); void remove(const EType& x, BinaryNode<EType>* & t); BinaryNode<EType>* findMin(BinaryNode<EType>* t); BinaryNode<EType>* findMax(BinaryNode<EType>* t); BinaryNode<EType>* find(const EType& x, BinaryNode<EType>* t ); void makeEmpty(BinaryNode<EType>* & t); void printInorder(BinaryNode<EType>* t);};

#endif