+ All Categories
Home > Documents > Chapter 10: Trees

Chapter 10: Trees

Date post: 05-Jan-2016
Category:
Upload: nevan
View: 28 times
Download: 3 times
Share this document with a friend
Description:
Chapter 10: Trees. Applications. Implementations. Traversals. Balancing. CS 240. 182. Sample Tree. Tree Abstract Data Type. Root. The tree abstract data type provides a hierarchical structure to the representation of certain types of relationships. Leaf. Node. Leaf. - PowerPoint PPT Presentation
Popular Tags:
40
Chapter 10: Trees APPLICATIONS IMPLEMENTATIONS CS 240 1 TRAVERSALS BALANCING
Transcript
Page 1: Chapter 10: Trees

Chapter 10: Trees

APPLICATIONS

IMPLEMENTATIONS

CS 240 1

TRAVERSALS

BALANCING

Page 2: Chapter 10: Trees

CS 240 2

Tree Abstract Data Type

Sample Tree

Sample Tree

In addition to constructors and a destructor, the tree ADT needs the following functions:• isEmpty - to determine whether

the tree contains any entries• insert - to insert a new entry at

the appropriate location within the tree

• traverse - some mechanism to explore the tree

The tree abstract data type provides a hierarchical structure to the representation of certain types of relationships.

Root

Leaf Node

Node Node

Leaf

Node LeafLeaf Node

LeafLeaf NodeNode Leaf

Leaf LeafNode

Leaf Leaf

Page 3: Chapter 10: Trees

CS 240 3

Binary Tree ADTThe binary tree abstract data type is a structure in which entries are configured to have at most two offspring.The binary aspect of this structure makes it particularly useful in applications where individual choices are needed, making it possible to recursively proceed to the right offspring or to the left offspring of the current node.For example, video games frequently present a player with two options, using a game tree to keep track of the alternatives selected by the player.

Sample Binary TreeSample Binary TreeRoot

Leaf Node

Node

Node Leaf

LeafNodeNode

LeafLeafNode

Leaf Leaf

Node

Node

Page 4: Chapter 10: Trees

CS 240 4

Basic Binary Tree Terminology

value

value value

value value value value

value

value value

value

value

value

value

value valueleaf nodesleaf nodes

sibling nodessibling nodes

parent nodeparent node

child nodechild node

Page 5: Chapter 10: Trees

CS 240 5

Application: Heap

1000

875 650

325 700 575

400

25

250

350

425 150

275

75

100

By keeping the data in each node greater than or equal to the data in both of its subtrees, the nodes with the highest values are closer to the root and, consequently, more accessible.

Page 6: Chapter 10: Trees

CS 240 6

Application: Binary Search Tree

This structure keeps the data in each node's left subtree less than or equal to the node's data, and the data in the node's right subtree greater than or equal to the node's data.

When the data is well distributed, this significantly reduces data search time.

72

41 90

23 50 74

8214

97

79 98

67

31

9938

Page 7: Chapter 10: Trees

CS 240 7

Application: Binary Expression TreeThis structure strategically places the binary operators in the upper nodes, and the primitive operands in the leaf nodes, facilitating the quick evaluation of the overall expression.

Example: (A+B)/C+D*((E+F)%(G-H))

+

/ *

+ C D

+A

%

E GF H

-B

Page 8: Chapter 10: Trees

CS 240 8

Binary Tree: Array Implementation· Place root in slot 0· Place left child of slot k's node in slot 2

* k + 1· Place right child of slot k's node in slot

2 * k + 2· Locate parent of slot k's node in slot (k

- 1) / 2

00

11

22

33

44

55

66

77

88

99

1010

1111

1212

1313

1414

1515

1616

1717

1818

1919

2020

2121

2222

2323

2424

2525

2626

2727

2828

2929

3030

3131

3232

3333

3434

3535

3636

3737

3838

3939

4040

4141

4242

4343

4444

4545

4646

4747

4848

4949

5050

5151

5252

5353

5454

5555

5656

5757

5858

5959

6060

6161

6262

6363

6464

6565

6666

6767

6868

6969

7070

7171

7272

7373

7474

7575

7676

7777

7878

7979

8080

8181

8282

8383

8484

8585

8686

8787

8888

8989

9090

9191

9292

9393

9494

9595

9696

9797

9898

9999

100100

101101

102102

103103

104104

105105

106106

107107

108108

109109

110110

111111

112112

113113

114114

115115

116116

117117

118118

119119

120120

121121

122122

123123

124124

125125

126126

127127

128128

129129

130130

131131

132132

133133

134134

135135

136136

137137

138138

139139

140140

141141

142142

143143

144144

145145

146146

147147

148148

149149

150150

151151

152152

153153

154154

155155

156156

157157

158158

159159

160160

161161

162162

163163

164164

165165

166166

167167

168168

169169

170170

171171

172172

173173

174174

175175

176176

177177

178178

179179

180180

181181

182182

183183

184184

185185

186186

187187

188188

189189

190190

191191

192192

193193

194194

195195

196196

197197

198198

199199

200200

201201

202202

203203

204204

205205

206206

207207

208208

209209

210210

211211

212212

213213

214214

215215

216216

217217

218218

219219

220220

221221

222222

223223

Page 9: Chapter 10: Trees

CS 240 9

Binary Tree: Array Implementation// Class declaration file: BinTree.h

/////////////////////////////////////////////////////////////////////////// This file contains the array implementation of the binary tree ADT. ///////////////////////////////////////////////////////////////////////////

#include <assert.h>#include <iostream>#include <iomanip>

using namespace std;

#ifndef BIN_TREE_H

////////////////////////////////////////////////////////////// DECLARATION SECTION FOR THE BINARY TREE CLASS TEMPLATE //////////////////////////////////////////////////////////////

const int MAX_TREE_NODES = 15;

template <class E> class binary_tree{ public: // Class constructors binary_tree(); binary_tree(const binary_tree<E> &bt);

// Member functions bool isEmpty(); void insert(const E &item); void preorder_traverse(int location); void inorder_traverse(int location); void postorder_traverse(int location); binary_tree<E>& operator = (const binary_tree<E> &bt); void display_array();

Page 10: Chapter 10: Trees

CS 240 10

protected: // Data members struct node // The node structure is { // set up so that if the bool vacant; // vacant field is FALSE, E data; // then the data field is }; // irrelevant.

node tree[MAX_TREE_NODES]; // Array of nodes int number_nodes; // Number of nodes in tree

// Member function void insertStartingHere(const E &item, int location);};

///////////////////////////////////////////////////////////////// IMPLEMENTATION SECTION FOR THE BINARY TREE CLASS TEMPLATE /////////////////////////////////////////////////////////////////

// Default constructor. //template <class E>binary_tree<E>::binary_tree(){ number_nodes = 0; for (int i = 0; i < MAX_TREE_NODES; i++) tree[i].vacant = true;}

// Copy constructor. //template <class E>binary_tree<E>::binary_tree(const binary_tree<E> &bt){ number_nodes = bt.number_nodes; for (int i = 0; i < MAX_TREE_NODES; i++) if (bt.tree[i].vacant) tree[i].vacant = true; else tree[i] = bt.tree[i];}

Page 11: Chapter 10: Trees

CS 240 11

// Assignment operator. //template <class E>binary_tree<E>& binary_tree<E>::operator = (const binary_tree<E> &bt){ number_nodes = bt.number_nodes; for (int i = 0; i < MAX_TREE_NODES; i++) if (bt.tree[i].vacant) tree[i].vacant = true; else tree[i] = bt.tree[i]; return *this;}

// Empty function. //template <class E>bool binary_tree<E>::isEmpty(){ return (number_nodes == 0);}

// Insert function; inserts via insertStartingHere function. //template <class E>void binary_tree<E>::insert(const E &item){ assert(number_nodes < MAX_TREE_NODES); // Room in tree? insertStartingHere(item, 0); number_nodes++;}

Page 12: Chapter 10: Trees

CS 240 12

// Preorder_traverse function; prints tree contents in preorder. //template <class E>void binary_tree<E>::preorder_traverse(int location){ if ((location < MAX_TREE_NODES) && (!tree[location].vacant)) { cout << tree[location].data << '\t'; preorder_traverse(2 * location + 1); preorder_traverse(2 * location + 2); } return;}

// Inorder_traverse function; prints tree contents in inorder. //template <class E>void binary_tree<E>::inorder_traverse(int location){ if ((location < MAX_TREE_NODES) && (!tree[location].vacant)) { inorder_traverse(2 * location + 1); cout << tree[location].data << '\t'; inorder_traverse(2 * location + 2); } return;}

// Postorder_traverse function; prints tree contents in postorder. //template <class E>void binary_tree<E>::postorder_traverse(int location){ if ((location < MAX_TREE_NODES) && (!tree[location].vacant)) { postorder_traverse(2 * location + 1); postorder_traverse(2 * location + 2); cout << tree[location].data << '\t'; } return;}

Page 13: Chapter 10: Trees

CS 240 13

// Display_array function; prints tree contents as an //// array, printing the word vacant if a node is vacant. //template <class E>void binary_tree<E>::display_array(){ int index; for (int i = 0; i < MAX_TREE_NODES/5; i++) { for (int j = 0; j < 5; j++) { index = (MAX_TREE_NODES / 5) * j + i; cout << setw(2) << index << " = "; if (tree[index].vacant) cout << setw(6) << "vacant" << setw(3) << ""; else cout << setw(6) << tree[index].data << setw(3) << ""; } cout << endl; }}

// InsertStartingHere function; inserts item into tree using ordering (i.e., //// inserting smaller values to the left and larger values to the right). //template <class E>void binary_tree<E>::insertStartingHere(const E &item, int location){ assert(location < MAX_TREE_NODES); // Must be legitimate array index if (tree[location].vacant) { tree[location].data = item; tree[location].vacant = false; } else if (item < tree[location].data) insertStartingHere(item, 2 * location + 1); else insertStartingHere(item, 2 * location + 2);}

#define BIN_TREE_H#endif

Page 14: Chapter 10: Trees

CS 240 14

Sample Driver For Array Implementation// Program file: TreeDriver.cpp

//////////////////////////////////// This program illustrates the //// creation of a binary tree. ////////////////////////////////////

#include <iostream>#include "BinTree.h"

using namespace std;

void print_tree(binary_tree<int> &tree);

// The main function queries the //// user for new tree elements. //void main(){ binary_tree<int> tree; int number;

cout << "Enter a number: "; cin >> number; while (number > 0) { tree.insert(number); tree.display_array(); cout << "Enter a number: "; cin >> number; }

print_tree(tree);}

// The print_tree function outputs the final //// contents of the tree, first by displaying //// the entire array, then by printing out //// the non-vacant tree elements in inorder, //// preorder, and postorder. //void print_tree(binary_tree<int> &tree){ cout << "Array contents:" << endl; tree.display_array(); cout << endl << "Inorder traversal: " << endl; tree.inorder_traverse(0); cout << endl; cout << "Preorder traversal: " << endl; tree.preorder_traverse(0); cout << endl; cout << "Postorder traversal: " << endl; tree.postorder_traverse(0); cout << endl << endl;}

Page 15: Chapter 10: Trees

CS 240 15

Page 16: Chapter 10: Trees

CS 240 16

Application For Array Implementation: Heaps// Class declaration file: heap.h //// This file contains the array //// implementation of the heap ADT. //#include "BinTree.h"#include <assert.h>#include <iostream>

#ifndef HEAP_H

// DECLARATION SECTION FOR // THE HEAP CLASS TEMPLATE

template <class E>class heap: public binary_tree<E>{ public: // Class constructors heap(); heap(const heap<E> &h);

// Member functions void insert(const E &item); heap<E>& operator = (const heap<E> &h);};

// IMPLEMENTATION SECTION FOR // THE HEAP CLASS TEMPLATE

// Default constructor. //template <class E>heap<E>::heap(): binary_tree<E>(){}

// Copy constructor. //template <class E>heap<E>::heap(const heap<E> &h){ number_nodes = h.number_nodes; for (int i=0; i<MAX_TREE_NODES; ++i) if (h.tree[i].vacant) tree[i].vacant = true; else tree[i] = h.tree[i];}

// Assignment operator. //template <class E>heap<E>& heap<E>::operator = (const heap<E> &h){ number_nodes = h.number_nodes; for (int i=0; i<MAX_TREE_NODES; ++i) if (h.tree[i].vacant) tree[i].vacant = true; else tree[i] = h.tree[i];return *this;}

Page 17: Chapter 10: Trees

CS 240 17

// Insert function; inserts into the heap to retain the heap structure //// and to ensure non-fragmentation of the array structure, moving low //// elements down when a high element is inserted. //template <class E>void heap<E>::insert(const E &item){ int location, parent; assert(number_nodes < MAX_TREE_NODES);

// Now walk the new item up the tree, starting at location location = number_nodes; parent = (location-1) / 2; while ((location > 0) && (tree[parent].data < item)) { tree[location] = tree[parent]; location = parent; parent = (location-1) / 2; } tree[location].data = item; tree[location].vacant = false; number_nodes++;}

#define HEAP_H#endif

Page 18: Chapter 10: Trees

CS 240 18

Example Driver For The Heap Application

// Program file: heapdriv.cpp //// This program illustrates //// the creation of a heap. //#include <iostream>#include "heap.h"

void print_heap(heap<int> &tree);

// The main function queries the //// user for new heap elements. //void main(){ heap<int> tree; int number;

cout << "Enter a number: "; cin >> number; while (number > 0) { tree.insert(number); tree.display_array(); cout << "Enter a number: "; cin >> number; } print_heap(tree);}

// The print_heap function outputs //// the final contents of the heap, //// first by displaying the entire //// array, then by printing out the //// non-vacant heap elements in in- //// order, preorder, and postorder. //void print_heap(heap<int> &tree){ cout << "Array contents: \n"; tree.display_array(); cout << "\nInorder traversal: \n"; tree.inorder_traverse(0); cout << "\nPreorder traversal: \n"; tree.preorder_traverse(0); cout << "\nPostorder traversal: \n"; tree.postorder_traverse(0); cout << endl << endl;}

Page 19: Chapter 10: Trees

CS 240 19

Page 20: Chapter 10: Trees

CS 240 20

Binary Tree: Linked List Implementation// Class declaration file: bintree.h

// This file contains the array implementation of the binary tree ADT. //#ifndef BIN_TREE_H#include <stdlib.h>#include <assert.h>#include <fstream>#include <iomanip>

// DECLARATION SECTION FOR LINKED VERSION OF BINARY TREE

template <class E> class binary_tree{ public: // Class constructors and destructor binary_tree(); binary_tree(const binary_tree<E> &bt); ~binary_tree();

// Member functions bool isEmpty() const; void insert(const E &item); void preorderTraverse(ofstream &os) const; void inorderTraverse(ofstream &os) const; void postorderTraverse(ofstream &os) const; binary_tree<E>& operator = (const binary_tree<E> &bt);

Page 21: Chapter 10: Trees

CS 240 21

protected: // Data members struct node; typedef node *node_ptr; struct node { E data; node_ptr left; node_ptr right; };

node_ptr root;

// Member functions node_ptr get_node(const E &data);

void insertIntoTree(node_ptr &treeRoot, const E &data); void copyTree(node_ptr treeRoot) const; void destroyTree(node_ptr treeRoot);

void preorderOutput(node_ptr treeRoot, ofstream &os) const; void inorderOutput(node_ptr treeRoot, ofstream &os) const; void postorderOutput(node_ptr treeRoot, ofstream &os) const;};

// IMPLEMENTATION SECTION FOR LINKED VERSION OF BINARY TREE

// Default constructor. //template <class E>binary_tree<E>::binary_tree(){ root = NULL;}

Page 22: Chapter 10: Trees

CS 240 22

// Copy constructor. //template <class E>binary_tree<E>::binary_tree(const binary_tree<E> &bt){ root = NULL; copyTree(bt.root)}

// Assignment operator. //template <class E>binary_tree<E>& binary_tree<E>::operator = (const binary_tree<E> &bt){ root = NULL; copyTree(bt.root); return *this;}

// Function copyTree: Starting at the node pointed to by //// parameter treeRoot, this function recursively copies the //// elements of an existing tree into the *this tree. By //// proceeding in a preorder fashion, this function ensures //// that the elements of *this will correspond exactly (in //// value and position) to the elements of the existing tree. //template <class E>void binary_tree<E>::copyTree(node_ptr treeRoot) const{ if (treeRoot != NULL) { insert(treeRoot->data); copyTree(treeRoot->left); copyTree(treeRoot->right); }}

Page 23: Chapter 10: Trees

CS 240 23

// Destructor. //template <class E>binary_tree<E>::~binary_tree(){ destroyTree(root); root = NULL;}

// Function destroyTree: returns all memory associated with //// the tree to the system heap, by recursively destroying //// the two subtrees and then deleting the root. //template <class E>void binary_tree<E>::destroyTree(node_ptr treeRoot){ if (treeRoot != NULL) { destroyTree(treeRoot->left); destroyTree(treeRoot->right); delete treeRoot; }}

// Empty function. //template <class E>bool binary_tree<E>::isEmpty() const{ return root == NULL;}

Page 24: Chapter 10: Trees

CS 240 24

// Insert function. //template <class E>void binary_tree<E>::insert(const E &item){ insertIntoTree(root, item);}

// Function insertIntoTree: recursively inserts parameter //// item into tree using binary search tree assumption. //template <class E>void binary_tree<E>::insertIntoTree(node_ptr &treeRoot, const E &item){ if (treeRoot == NULL) treeRoot = get_node(item); else if (item < treeRoot->data) insertIntoTree(treeRoot->left, item); else insertIntoTree(treeRoot->right, item);}

Page 25: Chapter 10: Trees

CS 240 25

// Function preorderTraverse. //template <class E>void binary_tree<E>::preorderTraverse(ofstream &os) const{ preorderOutput(root, os);}

// Function preorderOutput: Outputs contents of //// the tree into parameterized file by recursively //// traversing the tree in preorder. //template <class E>void binary_tree<E>::preorderOutput(node_ptr treeRoot, ofstream &os) const{ if (treeRoot != NULL) { os << treeRoot->data << endl; preorderOutput(treeRoot->left, os); preorderOutput(treeRoot->right, os); }}

Page 26: Chapter 10: Trees

CS 240 26

// Function inorderTraverse. //template <class E>void binary_tree<E>::inorderTraverse(ofstream &os) const{ inorderOutput(root, os);}

// Function inorderOutput: Outputs contents of //// the tree into parameterized file by recursively //// traversing the tree in inorder. //template <class E>void binary_tree<E>::inorderOutput(node_ptr treeRoot, ofstream &os) const{ if (treeRoot != NULL) { inorderOutput(treeRoot->left, os); os << treeRoot->data << endl; inorderOutput(treeRoot->right, os); }}

Page 27: Chapter 10: Trees

CS 240 27

// Function postorderTraverse. //template <class E>void binary_tree<E>::postorderTraverse(ofstream &os) const{ postorderOutput(root, os);}

// Function postorderOutput: Outputs contents of //// the tree into parameterized file by recursively //// traversing the tree in postorder. //template <class E>void binary_tree<E>::postorderOutput(node_ptr treeRoot, ofstream &os) const{ if (treeRoot != NULL) { postorderOutput(treeRoot->left, os); postorderOutput(treeRoot->right, os); os << treeRoot->data << endl; }}

Page 28: Chapter 10: Trees

CS 240 28

// Function get_node: Dynamically allocates space for a new //// tree node, placing the parameter item's value into the //// new node, and initializing both of its pointers to NULL. //template <class E>typename binary_tree<E>::node_ptr binary_tree<E>::get_node(const E &item){ node_ptr temp = new node;

assert(temp != NULL); temp->data = item; temp->left = NULL; temp->right = NULL; return temp;}

#define BIN_TREE_H#endif

Page 29: Chapter 10: Trees

CS 240 29

Example Driver For The Linked List Implementation// Program file: testtree.cpp

// This program illustrates working // with a binary tree. The input // consists of an unordered list of // integers from a file. The // output consists of three files // containing the preorder, inorder, // and postorder traversals of the // binary search tree that is con-// structed from the input integers.

#include <iostream>#include <fstream>#include "BinTree.h"

void main(){ int number; ifstream input_file; ofstream pre_file; ofstream in_file; ofstream post_file; binary_tree<int> tree;

input_file.open("numbers.txt"); pre_file.open("preordered.txt"); in_file.open("inordered.txt"); post_file.open("postordered.txt");

input_file >> number; while (!input_file.eof()) { tree.insert(number); input_file >> number; } input_file.close();

tree.preorderTraverse(pre_file); tree.inorderTraverse(in_file); tree.postorderTraverse(post_file);

pre_file.close(); in_file.close(); post_file.close();

return;}

Page 30: Chapter 10: Trees

CS 240 30

File Contents

numbers.txt79

54474313497823247842763174294779146896

preordered.txt

7954474313231424423129494778767468787996

inordered.txt

1314232429314243474749546874767878797996

postordered.txt

1429314224231343474947687476787854967979

79

79

96

54

78

7876

74

68

47

49

4713

23

14 24

42

31

29

43

Page 31: Chapter 10: Trees

CS 240 31

Additional Tree Traversal Member Function #1// Public function to “spell out” the values from the root to the tree’s //

// leaf nodes, with the results output on a separate line for each leaf. //template <class E>void BinaryTree<E>::spellFromTop(ofstream &os){ continueSpelling(root, os, "");}

// Protected function to concatenate the char value of the current subtree’s //// root to the str param. until a leaf is reached, whereupon str is output. //template <class E>void BinaryTree<E>::continueSpelling(nodePtr treeRoot, ofstream &os, string str){ if (treeRoot == NULL) return; else { str += char(treeRoot->data); if ((treeRoot->left == NULL) && (treeRoot->right == NULL)) os << str << endl; else { continueSpelling(treeRoot->left, os, str); continueSpelling(treeRoot->right, os, str); } }}

Page 32: Chapter 10: Trees

CS 240 32

Applying spellFromTop To A Sample Tree

str: “M”

str: “MI”

str: “MIL”

str: “MICE”

output “MICE”

str: “MIC”

str: “MILL”

output “MILL”

str: “MILK”

output “MILK”

str: “MO”

str: “MOP”

output “MOM”

str: “MOM”

str: “MOPS”

output “MOPS”

M

I

C

E

L

K L

O

M P

S

Page 33: Chapter 10: Trees

CS 240 33

Additional Tree Traversal Member Function #2// Public function to output the sequence of left and right offspring that //

// comprise the longest path from the tree’s root to one of its leaf nodes. //template <class E>void BinaryTree<E>::outputLongestPath(ofstream &os){ os << longestPath(root);}

// Protected function to recursively generate a string indicating which //// offspring (left or right) yield the longest path from the root to a leaf. //template <class E>string BinaryTree<E>::longestPath(nodePtr treeRoot){ if (treeRoot == NULL) return ""; else { string leftStr = longestPath(treeRoot->left); string rightStr = longestPath(treeRoot->right); if (leftStr.size() > rightStr.size()) { leftStr.insert(0, 'L'); return leftStr; } else { rightStr.insert(0, 'R'); return rightStr; } }}

Page 34: Chapter 10: Trees

CS 240 34

Applying outputLongest To A Sample Tree

leftStr: “”rightStr: “”

leftStr: “”rightStr: “”

leftStr: “L”rightStr: “R”

leftStr: “”rightStr:

“RR”

leftStr: “LRR”rightStr:

“”

leftStr: “”rightStr:

“”

leftStr: “”rightStr:

“”

leftStr: “L”rightStr:

“”

leftStr: “L”rightStr:

“”

leftStr: “LL”rightStr: “RL”

leftStr: “LLRR”rightStr: “RRL”

“”“” “”“”

“R”“R”

“RR”“RR”

“LRR”“LRR”

“”“” “”“”

“L”“L” “L”“L”

“RL”“RL”

Final result: “LLRR”Final result: “LLRR”

Page 35: Chapter 10: Trees

CS 240 35

AVL TreesAlthough an average search in an n-node binary search tree is O(logn), the worst case could be as bad as O(n).

So when a new element’s insertion causes an imbalance, “rotate” the tree to restore the balance.

k1

k2

X

ZY

k2

k1

Z

YXAn AVL (Adelson-Velskii and Landis) tree places a balance condition on a binary search tree by requiring the left and right subtrees of each node to have heights differing by at most one.During insertion, this is accomplished by means of single and double rotations.Single rotations: Note that in each of the trees illustrated at right: (any element of X) k1

(any element of Y) k2

(any element of Z)

Page 36: Chapter 10: Trees

CS 240 36

Single Rotation Examples

27

14

31

12

30

45

27

14

31

12

30

45

5

27

12

31

5 30

45

14

INSERT 5INSERT 5 ROTATEROTATE

84

75

93

92

98

84

75

93

92

98

99

93

84

98

75

99

92

INSERT 99INSERT 99 ROTATEROTATE

Page 37: Chapter 10: Trees

CS 240 37

Double RotationsIf a single rotation doesn’t restore balance, a double rotation will.

k3

k2

DCB

k1

A

k3

k2

DCB

k1

A

H

k3

k2

HGF

k1

E

k3

k2

GF

k1

E

Also note that in the two trees illustrated at right: (any value in E) k1 (any value in F) k2 (any value in G) k3 (any value in H)If a single rotation fails to restore balance after a new insertion, a double rotation may be tried.

Note that in the two trees illustrated at right: (any value in A) k1 (any value in B) k2 (any value in C) k3 (any value in D)

Page 38: Chapter 10: Trees

CS 240 38

Double Rotation Example

INSERT 47

INSERT 47

SINGLE ROTATIO

N

SINGLE ROTATIO

N

25

16

49

9 36

64

19

31

41

25

16

49

9 36

64

19

31

41

47

25

16

36

9 31

49

19

41

64

47

STILL UNBALANCED

25

16

49

9 36

64

19

31

41

INSERT 47

INSERT 47

25

16

49

9 36

64

19

31

41

47

DOUBLE ROTATIO

N

DOUBLE ROTATIO

N

25

16

41

9 36

49

19

47

64

31

BALANCED!

Page 39: Chapter 10: Trees

CS 240 39

General Trees

26

873

451

826

473

51

826

753

41

826

753

41

82

736

451

826

731

45

86

723

451

86

723

451

There are occasions when non-binary trees are needed

Application Example: Game Trees

86

723

451

826

73

451

826

753

41

826

73

451

826

73

451

Page 40: Chapter 10: Trees

CS 240 40

Binary Implementation Of General TreesA common approach for implementing general trees is to use binary trees, with offspring and sibling pointers

A

D

F I NMLK

E

J

B C

HG

A

D

F

I

N

M

L

K

EJ

B

C

H

G

Actual tree

Binary representation, withleft pointers for “first

offspring”and right pointers for “next

sibling”


Recommended