1 Trees A Quick Introduction to Graphs Definition of Trees Rooted Trees Binary Trees Binary Search...

Post on 17-Jan-2016

223 views 0 download

Transcript of 1 Trees A Quick Introduction to Graphs Definition of Trees Rooted Trees Binary Trees Binary Search...

1

Trees

• A Quick Introduction to Graphs

• Definition of Trees

• Rooted Trees

• Binary Trees

• Binary Search Trees

2

Introduction to Graphs

• A graph is a finite set of nodes with edges between nodes

• Formally, a graph G is a structure (V,E) consisting of – a finite set V called the set of nodes, and– a set E that is a subset of VxV. That is, E is a set

of pairs of the form (x,y) where x and y are nodes in V

3

Examples of Graphs

• V={1,2,3,4,5}

• E={(1,2), (2,3), (2,4), (4,2), (3,3), (5,4)}

12

5

3

4

When (x,y) is an edge,we say that x is adjacent to y. 1 is adjacent to 2.2 is not adjacent to 1.4 is not adjacent to 3.

4

A “Real-life” Example of a Graph

• V=set of 6 people: John, Mary, Joe, Helen, Tom, and Paul, of ages 12, 15, 12, 15, 13, and 13, respectively.

• E ={(x,y) | if x is younger than y}

John Joe

Mary Helen

Tom Paul

5

Intuition Behind Graphs

• The nodes represent entities (such as people, cities, computers, words, etc.)

• Edges (x,y) represent relationships between entities x and y, such as:– “x loves y”

– “x hates y”

– “x is as smart as y”

– “x is a sibling of y”

– “x is bigger than y”

– ‘x is faster than y”, …

6

Directed vs. Undirected Graphs

• If the directions of the edges matter, then we show the edge directions, and the graph is called a directed graph (or a digraph)

• The previous two examples are digraphs• If the relationships represented by the edges

are symmetric (such as (x,y) is edge if and only if x is a sibling of y), then we don’t show the directions of the edges, and the graph is called an undirected graph.

7

Examples of Undirected Graphs

• V=set of 6 people: John, Mary, Joe, Helen, Tom, and Paul, where the first 4 are siblings, and the last two are siblings

• E ={(x,y) | x and y are siblings}

John Joe

Mary Helen

Tom Paul

8

Definition of Some Graph Related Concepts (Paths)

• A path in a graph G is a sequence of nodes x1, x2, …,xk, such that there is an edge from each node the next one in the sequence

• For example, in the first example graph, the sequence 4, 1, 2, 3 is a path, but the sequence 1, 4, 5 is not a path because (1,4) is not an edge

• In the “sibling-of” graph, the sequence John, Mary, Joe, Helen is a path, but the sequence Helen, Tom, Paul is not a path

9

Definition of Some Graph Related Concepts (Cycles)

• A cycle in a graph G is a path where the last node is the same as the first node.

• In the “sibling-of” graph, the sequence John, Mary, Joe, Helen, John is a cycle, but the sequence Helen, Tom, Paul, Helen is not a cycle

10

Graph Connectivity

• An undirected graph is said to be connected if there is a path between every pair of nodes. Otherwise, the graph is disconnected

• Informally, an undirected graph is connected if it hangs in one piece

Disconnected Connected

11

Graph Cyclicity

• An undirected graph is cyclic if it has at least one cycle. Otherwise, it is acyclic

Disconnected and acyclic Connected and acyclic

Disconnected and cyclic Connected and cyclic

12

Trees

• A tree is a connected acyclic undirected graph. The following are three trees:

1

2

53 11

12

10

98

7

64

13

Rooted Trees

• A rooted tree is a tree where one of the nodes is designated as the root node. (Only one root in a tree)

• A rooted tree has a hierarchical structure: the root on top, followed by the nodes adjacent to it right below, followed by the nodes adjacent to those next, and so on.

14

Example of a Rooted Tree

1

2

53 11

12

10

98

7

64

1

23

10

11

98

4 6

5

7

12Un-rooted tree

Tree rooted with root 1

15

Tree-Related Concepts

• The nodes adjacent to x and below x are called the children of x,and x is called their parents

• A node that has no children is called a leaf

• The descendents of a node are: itself, its children, their children, all the way down

• The ancestors of a node are: itself, its parent, its grandparent, all the way to the root

1

23

10

11

98

4 6

5

7

12

16

Tree-Related Concepts (Contd.)

• The depth of a node is the number of edges from the root to that node.

• The depth (or height) of

a rooted tree is the depth

of the lowest leaf

• Depth of node 10: 3

• Depth of this tree: 4

1

23

10

11

98

4 6

5

7

12

17

Binary Trees

• A tree is a binary tree if every node has at most two children

1

23

10

11

98

4 6

5

7

12

1

3

10

11

98

4 6

5

7

12

Non-binary tree Binary tree

18

Binary-Tree Related Definitions

• The children of any node in a binary tree are ordered into a left child and a right child

• A node can have a left anda right child, a left childonly, a right child only,or no children

• The tree made up of a leftchild (of a node x) and all itsdescendents is called the left subtree of x

• Right subtrees are defined similarly

10

1

3

11

98

4 6

5

7

12

19

Graphical View Binary-tree Nodes

data

left right

In practice, a TreeNode will be shown as a circle where the data is put inside, and the node label(if any) is put outside.

Graphically, a TreeNode is:

5.8 2data label

• A binary-tree node consists of 3 parts:

-Data-Pointer to left child-Pointer to right child

20

A Binary-tree Node Classclass TreeNode { public: typedef int datatype; TreeNode(datatype x=0, TreeNode *left=NULL,

TreeNode *right=NULL){data=x; this->left=left; this->right=right; };

datatype getData( ) {return data;};

TreeNode *getLeft( ) {return left;};

TreeNode *getRight( ) {return right;};void setData(datatype x) {data=x;};void setLeft(TreeNode *ptr) {left=ptr;};void setRight(TreeNode *ptr) {right=ptr;};

private:datatype data; // different data type for other appsTreeNode *left; // the pointer to left childTreeNode *right; // the pointer to right child

};

21

Binary Tree Class

class Tree { public: typedef int datatype; Tree(TreeNode *rootPtr=NULL){this->rootPtr=rootPtr;}; TreeNode *search(datatype x); bool insert(datatype x); TreeNode * remove(datatype x); TreeNode *getRoot(){return rootPtr;}; Tree *getLeftSubtree(); Tree *getRightSubtree(); bool isEmpty(){return rootPtr == NULL;}; private: TreeNode *rootPtr;};

22

Binary Search Trees

• A binary search tree (BST) is a binary tree where– Every node holds a data value (called key)– For any node x, all the keys in the left subtree

of x are ≤ the key of x– For any node x, all the keys in the right subtree

of x are > the key of x

23

Example of a BST

6

15

8

2

3 7

11

10

14

12

20

27

22 30

24

Searching in a BST

To search for a number b:

1. Compare b with the root;– If b=root, return

– If b<root, go left

– If b>root, go right

2. Repeat step 1, comparing b with the new node we are at.

3. Repeat until either the node is found or we reach a non-existing node

Try it with b=12, and also with b=17

6

158

2

3 7

11

10

14

12

20

27

22 30

25

Code for Search in BST

// returns a pointer to the TreeNode that contains x,// if one is found. Otherwise, it returns NULLTreeNode * Tree::search(datatype x){ if (isEmpty()) {return NULL;} TreeNode *p=rootPtr; while (p != NULL){ datatype a = p->getData(); if (a == x) return p; else if (x<a) p=p->getLeft(); else p=p->getRight(); } return NULL;};

26

Insertion into a BST

Insert(datatype b, Tree T):

1. Search for the position of b as if it were in the tree. The position is the left or right child of some node x.

2. Create a new node, and assign its address to the appropriate pointer field in x

3. Assign b to the data field of the new node

27

Illustration of Insert

6

158

2

3 7

11

10

14

12

20

27

22 30

Before inserting 25

6

158

2

3 7

11

10

14

12

20

27

22 30

25

After inserting 25

28

Code for Insert in BST

bool Tree::insert(datatype x){ if (isEmpty()) {rootPtr = new TreeNode(x);return true; } TreeNode *p=rootPtr; while (p != NULL){ datatype a = p->getData(); if (a == x) return false; // data is already there else if (x<a){ if (p->getLeft() == NULL){ // place to insert TreeNode *newNodePtr= new TreeNode(x); p->setLeft(newNodePtr); return true;} else p=p->getLeft(); }else { // a>a if (p->getRight() == NULL){ // place to insert TreeNode *newNodePtr= new TreeNode(x); p->setRight(newNodePtr); return true;} else p=p->getRight();} } };

29

Deletion from a BST (pseudocode)

Delete (datatype b, Tree T)1. Search for b in tree T. If not found, return.2. Call x the first node found to contain b3. If x is a leaf, remove x and set the

appropriate pointer in the parent of x to NULL

4. If x has only one child y, remove x, and the parent of x become a direct parent of y

(More on the next slide)

30

Deletion (contd.)

5. If x has two children, go to the left subtree, and find there in largest node, and call it y. The node y can be found by tracing the rightmost path until the end. Note that y is either a leaf or has no right child

6. Copy the data field of y onto the data field of x

7. Now delete node y in a manner similar to step 4.

31

Tree Traversal Techniques; Heaps

• Tree Traversal Concept• Tree Traversal Techniques: Preorder,

In-order, Post-order• Full Trees • Almost Complete Trees• Heaps

32

Binary-Tree Related Definitions

• The children of any node in a binary tree are ordered into a left child and a right child

• A node can have a left anda right child, a left childonly, a right child only,or no children

• The tree made up of a leftchild (of a node x) and all itsdescendents is called the left subtree of x

• Right subtrees are defined similarly

10

1

3

11

98

4 6

5

7

12

33

A Binary-tree Node Classclass TreeNode { public: typedef int datatype; TreeNode(datatype x=0, TreeNode *left=NULL,

TreeNode *right=NULL){data=x; this->left=left; this->right=right; };

datatype getData( ) {return data;};

TreeNode *getLeft( ) {return left;};

TreeNode *getRight( ) {return right;};void setData(datatype x) {data=x;};void setLeft(TreeNode *ptr) {left=ptr;};void setRight(TreeNode *ptr) {right=ptr;};

private:datatype data; // different data type for other appsTreeNode *left; // the pointer to left childTreeNode *right; // the pointer to right child

};

34

Binary Tree Class

class Tree { public: typedef int datatype; Tree(TreeNode *rootPtr=NULL){this->rootPtr=rootPtr;}; TreeNode *search(datatype x); bool insert(datatype x); TreeNode * remove(datatype x); TreeNode *getRoot(){return rootPtr;}; Tree *getLeftSubtree(); Tree *getRightSubtree(); bool isEmpty(){return rootPtr == NULL;}; private: TreeNode *rootPtr;};

35

Binary Tree Traversal

• Traversal is the process of visiting every node once

• Visiting a node entails doing some processing at that node, but when describing a traversal strategy, we need not concern ourselves with what that processing is

36

Binary Tree Traversal Techniques

• Three recursive techniques for binary tree traversal

• In each technique, the left subtree is traversed recursively, the right subtree is traversed recursively, and the root is visited

• What distinguishes the techniques from one another is the order of those 3 tasks

37

Preoder, Inorder, Postorder

• In Preorder, the root

is visited before (pre)

the subtrees traversals• In Inorder, the root is

visited in-between left

and right subtree traversal• In Preorder, the root

is visited after (pre)

the subtrees traversals

Preorder Traversal:1. Visit the root2. Traverse left subtree3. Traverse right subtree

Inorder Traversal:1. Traverse left subtree2. Visit the root3. Traverse right subtree

Postorder Traversal:1. Traverse left subtree2. Traverse right subtree3. Visit the root

38

Illustrations for Traversals

• Assume: visiting a node is printing its label

• Preorder: 1 3 5 4 6 7 8 9 10 11 12

• Inorder:4 5 6 3 1 8 7 9 11 10 12

• Postorder:4 6 5 3 8 11 12 10 9 7 1

1

3

11

98

4 6

5

7

12

10

39

Illustrations for Traversals (Contd.)

• Assume: visiting a node is printing its data

• Preorder: 15 8 2 6 3 711 10 12 14 20 27 22 30

• Inorder: 2 3 6 7 8 10 1112 14 15 20 22 27 30

• Postorder: 3 7 6 2 10 1412 11 8 22 30 27 20 15

6

158

2

3 7

11

10

14

12

20

27

22 30

40

Code for the Traversal Techniques• The code for visit

is up to you to

provide, depending

on the application

• A typical example

for visit(…) is to

print out the data

part of its input

node

void inOrder(Tree *tree){ if (tree->isEmpty( )) return; inOrder(tree->getLeftSubtree( )); visit(tree->getRoot( )); inOrder(tree->getRightSubtree( ));}

void preOrder(Tree *tree){ if (tree->isEmpty( )) return; visit(tree->getRoot( )); preOrder(tree->getLeftSubtree()); preOrder(tree->getRightSubtree());}

void postOrder(Tree *tree){ if (tree->isEmpty( )) return; postOrder(tree->getLeftSubtree( )); postOrder(tree->getRightSubtree( )); visit(tree->getRoot( ));}

41

Application of Traversal Sorting a BST

• Observe the output of the in-order traversal of the BST example two slides earlier

• It is sorted

• This is no coincidence

• As a general rule, if you output the keys (data) of the nodes of a BST using inorder traversal, the data comes out sorted in increasing order

42

Other Kinds of Binary Trees(Full Binary Trees)

• Full Binary Tree: A full binary tree is a binary tree where all the leaves are on the same level and every non-leaf has two children

• The first four full binary trees are:

43

Examples of Non-Full Binary Trees

• These trees are NOT full binary trees: (do you know why?)

44

Canonical Labeling ofFull Binary Trees

• Label the nodes from 1 to n from the top to the bottom, left to right

1 1

2 3

12 3

4 5 6 71

2 3

4 5 6 7

8 9 10 111213 14 15

Relationships between labelsof children and parent:

2i 2i+1i

45

Other Kinds of Binary Trees(Almost Complete Binary trees)

• Almost Complete Binary Tree: An almost complete binary tree of n nodes, for any arbitrary nonnegative integer n, is the binary tree made up of the first n nodes of a canonically labeled full binary

1 1

21

2 3

4 5 6 7

1

2

1

2 3

4 5 6

1

2 3

4

1

2 3

4 5

46

Depth/Height of Full Trees and Almost Complete Trees

• The height (or depth ) h of such trees is O(log n)• Proof: In the case of full trees,

– The number of nodes n is: n=1+2+22+23+…+2h=2h+1-1

– Therefore, 2h+1 = n+1, and thus, h=log(n+1)-1

– Hence, h=O(log n)

• For almost complete trees, the proof is left as an exercise.

47

Canonical Labeling ofAlmost Complete Binary Trees

• Same labeling inherited from full binary trees

• Same relationship holding between the labels of children and parents:

Relationships between labelsof children and parent:

2i 2i+1i

48

Array Representation of Full Trees and Almost Complete Trees

• A canonically label-able tree, like full binary trees and almost complete binary trees, can be represented by an array A of the same length as the number of nodes

• A[k] is identified with node of label k• That is, A[k] holds the data of node k• Advantage:

– no need to store left and right pointers in the nodes save memory

– Direct access to nodes: to get to node k, access A[k]

49

Illustration of Array Representation

• Notice: Left child of A[5] (of data 11) is A[2*5]=A[10] (of data 18),

and its right child is A[2*5+1]=A[11] (of data 12). • Parent of A[4] is A[4/2]=A[2], and parent of A[5]=A[5/2]=A[2]

6

158

2 11

18 12

20

27

13

30

15 8 20 2 11 30 27 13 6 10 121 2 3 4 5 6 7 8 9 10 11

50

Adjustment of Indexes

• Notice that in the previous slides, the node labels start from 1, and so would the corresponding arrays

• But in C/C++, array indices start from 0• The best way to handle the mismatch is to adjust the

canonical labeling of full and almost complete trees.• Start the node labeling from 0 (rather than 1).• The children of node k are now nodes (2k+1) and

(2k+2), and the parent of node k is (k-1)/2, integer division.

51

Application of Almost Complete Binary Trees: Heaps

• A heap (or min-heap to be precise) is an almost complete binary tree where– Every node holds a data value (or key)– The key of every node is ≤ the keys of the

children

Note:A max-heap has the same definition except that the Key of every node is >= the keys of the children

52

Example of a Min-heap

16

5

8

15 11

18 12

20

27

33

30

53

Operations on Heaps

• Delete the minimum value and return it. This operation is called delete-Min.

• Insert a new data value

Applications of Heaps:• A heap implements a priority queue, which is a queue that orders entities not a on first-come first-serve basis, but on a priority basis: the item of highest priority is at the head, and the item of the lowest priority is at the tail

• Another application: sorting, which will be seen later

54

Delete-Min in Min-heaps

• The minimum value in a min-heap is at the root!• To delete the min, you can’t just remove the data

value of the root, because every node must hold a key

• Instead, take the last node from the heap, move its key to the root, and delete that last node

• But now, the tree is no longer a heap (still almost complete, but the root key value may no longer be ≤ the keys of its children

55

Illustration of First Stage of delete-min

16

5

8

15 11

18 12

20

27

33

30

16

8

15 11

18 12

20

27

33

30

16

8

15 11

18

1220

27

33

30

16

8

15 11

18

1220

27

33

30

56

Restore Heap

• To bring the structure back to its “heapness”, we restore the heap

• Swap the new root key with the smaller child.

• Now the potential bug is at the one level down. If it is not already ≤ the keys of its children, swap it with its smaller child

• Keep repeating the last step until the “bug” key becomes ≤ its children, or the it becomes a leaf

57

Illustration of Restore-Heap

16

8

15 11

18

1220

27

33

30

16

12

15 11

18

820

27

33

30

16

11

15 12

18

820

27

33

30

Now it is a correct heap

58

Time complexity of insertand delete-min

• Both operations takes time proportional to the height of the tree– When restoring the heap, the bug moves from level to

level until, in the worst case, it becomes a leaf (in delete-min) or the root (in insert)

– Each move to a new level takes constant time– Therefore, the time is proportional to the number of

levels, which is the height of the tree.

• But the height is O(log n)• Therefore, both insert and delete-min take O(log

n) time, which is very fast.

59

Inserting into a min-heap

• Suppose you want to insert a new value x into the heap

• Create a new node at the “end” of the heap (or put x at the end of the array)

• If x is >= its parent, done• Otherwise, we have to restore the heap:

– Repeatedly swap x with its parent until either x reaches the root of x becomes >= its parent

60

The Min-heap Class in C++

class Minheap{ //the heap is implemented with a dynamic array public: typedef int datatype; Minheap(int cap = 10){capacity=cap; length=0; ptr = new datatype[cap];}; datatype deleteMin( ); void insert(datatype x); bool isEmpty( ) {return length==0;}; int size( ) {return length;}; private: datatype *ptr; // points to the array int capacity; int length; void doubleCapacity(); //doubles the capacity when needed};

61

Code for delete-min

Minheap::datatype Minheap::deleteMin( ){ assert(length>0); datatype returnValue = ptr[0]; length--; ptr[0]=ptr[length]; // move last value to root element int i=0; while ((2*i+1<length && ptr[i]>ptr[2*i+1]) || (2*i+2<length && (ptr[i]>ptr[2*i+1] || ptr[i]>ptr[2*i+2]))){ // “bug” still > at least one child if (ptr[2*i+1] <= ptr[2*i+2]){ // left child is the smaller child datatype tmp= ptr[i]; ptr[i]=ptr[2*i+1]; ptr[2*i+1]=tmp; //swap i=2*i+1; } else{ // right child if the smaller child. Swap bug with right child. datatype tmp= ptr[i]; ptr[i]=ptr[2*i+2]; ptr[2*i+2]=tmp; // swap i=2*i+2; } } return returnValue; };

62

Code for Insert

void Minheap::insert(datatype x){ if (length==capacity) doubleCapacity(); ptr[length]=x; int i=length; length++; while (i>0 && ptr[i] < ptr[i/2]){ datatype tmp= ptr[i]; ptr[i]=ptr[(i-1)/2]; ptr[(i-1)/2]=tmp; i=(i-1)/2; }};

63

Code for doubleCapacity

void Minheap::doubleCapacity(){ capacity = 2*capacity; datatype *newptr = new datatype[capacity]; for (int i=0;i<length;i++) newptr[i]=ptr[i]; delete [] ptr; ptr = newptr;};

64

End of Lecture