c++ notes 1995copyright ivor page 1995 1 advanced c programming ivor page

63
C++ Notes 1995 Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

Upload: kathleen-ray

Post on 20-Jan-2018

246 views

Category:

Documents


0 download

DESCRIPTION

C++ Notes 1995Copyright Ivor Page Data Structures: The Data For almost all purposes, data structures are used to store many “records” of data, where the records have something in common. The records have many fields, such as in a personnel records system. The records may be fixed or variable in size. If the size has a “small” bound, it may be that fixed sized records can be used, where every record is allocated space for the largest possible record. Alternatively the data structure must be designed for variable length records. The maximum number of records to be held may be known or unknown.

TRANSCRIPT

Page 1: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

1

Advanced C Programming

Ivor Page

Page 2: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

2

Copyright NoticeThis Microsoft Powerpoint presentation data file is the sole

property of Ivor P. Page. It may only be viewed, or shown to individuals, or exhibited to a class, or broadcast by any other means, with the owner’s written permission. This Powerpoint data file may not be copied without the owner’s written consent. Printed notes may not be made from this data file for any use without the owner’s written consent. All copies of this file MUST BE DESTROYED by October 1st 1996. Copyrighted, Ivor P. Page, 1995, 410 Pleasant Valley Lane, Richardson, TX 75080

Page 3: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

3

Data Structures: The Data

For almost all purposes, data structures are used to store many “records” of data, where the records have something in common. The records have many fields, such as in a personnel records system.

The records may be fixed or variable in size. If the size has a “small” bound, it may be that fixed sized records can be used, where every record is allocated space for the largest possible record. Alternatively the data structure must be designed for variable length records.

The maximum number of records to be held may be known or unknown.

Page 4: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

4

Data Structures: The Data

In most application, there is at least one ordering relationship that can be applied to the data, i.e. names can be alphabetically ordered; personnel can be ordered by personnel-number within each department, and then the departments can be ordered by department code, etc.

It may be necessary to search the data given a key. A key is a value corresponding to one field of the records, such as a name, or a personnel-number. Sometimes we may need to search on more than one field.

Page 5: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

5

Abstract Data Types

It is convenient (and valuable) to design all data structures using the same basic strategy. An Abstract Data Type is simply some data, together with a set of interface functions that manipulate the data.

Encapsulation: The actual data should never be manipulated (nor be seen if possible) by users of the data structure. There may also be some internal functions that directly operate on the data, but do not form part of the interface. These should be hidden if possible from the users.

Page 6: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

6

Abstract Data Types

Abstraction: Every operation that the users need to perform on the data must be provided for by the interface. The interface functions should be very easy to use and to understand (unlike the detailed manipulations of the data itself) and should typically be cast in the syntax of the application to be supported. The users can then ignore the inner workings of the data type and concentrate on the application level.

Page 7: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

7

Here is the structure that we will use for all data structures:

Abstract Data Types Cont’d

Data

Data

hf1

hf2

f1

f2

f3

hidden

Interface

ADT

~

caller

Page 8: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

8

Interface: insert(index,data)delete(index)data = get_data(index)index = search(data)index = find_free_cell()

Table

Index

Page 9: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

9

Queue

Interface: add_to_tail(data) data = remove_from_hd()

tail head

A B C D

Page 10: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

10

Stack

Interface:push(data)data = pop()data = top()bool = empty()

Page 11: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

11

Interface:n2 = parent(n1)n2 = leftmost_child(n1)n2 = right_sibling(n1)data = get_data(n)add_left_child(n,data)add_right_sibling(n,data)

remove_node(n)n = search(data)

Tree

. .

. .. .

Page 12: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

12

Graph

Interface:n = search(data)add_neighbor(n,data)add_link(n1,n2)delete_link(n1,n2)delete_node(n)

Page 13: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

13

All the above data structures can be implemented with arrays, but in most situations, the fixed size of an array makes it unsuitable, particularly when the amount of data to be held is unknown.

Tables:Tables include data dictionaries, for example a name and address table. Here the table may be searched given the name. The search maps the given name into an index corresponding to the entry containing that name.

N

Implementation with Arrays

name address age etc.index

Page 14: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

14

Implementation with Arrays

Linear search: If the entries are unordered, the search takes O(N) time, where each “probe” requires a string comparison. Find_free_cell() also requires O(N) time. Given an index, insert() and delete() take constant time, O(1).

Binary search: For binary search, the entries must be ordered (sorted alphabetically by name if we want to search on the name.) Keeping the table entries ordered implies O(N) time for insertion and deletion. The search proceeds as follows in O(log N) time:

Page 15: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

15

Base_Index = 0;Top_Index = N-1;found = 0; /* false */while (!found){Index = (Base_Index + Top_Index)/2; found = probe_element(Index); /* match? */if(found) break;if(Base_Index = = Top_Index ) break;if (key is beyond Index)Base_Index = Index+1;else Top_Index = Index-1;} /* value of found tells if the search was successful */

Binary Search

Page 16: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

16

Hash Tables

In a closed hash table, there is a mathematical mapping from the key (name) to the initial probe index. For example, the hash function for a table of size N entries, might be:

hash = (sum of characters in name) % NThis function has the disadvantage that names such as Fred, redF, derF, etc, all hash to the same initial probe index. There are much better hash functions available:

hash = sum of (name[i]*prime[i])%NHere we sum the chars multiplied by prime numbers, so

IVOR gives (I*1 + V*2 + O*3 +R*5)%N =892%N.

Page 17: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

17

The search is as follows:

index = hash(name); count = found = 0; while(!found && count < N) { found = probe(index); if(found)

break; index = rehash(name, index); count++; }

Hash Tables

Page 18: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

18

Hash Table Performance

Average TimesInsertion or successful search takes -(1/a)log(1-a)Deletion or unsuccessful search takes 1/(1-a) where a = fraction of cells occupied

Page 19: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

19Queues Using arrays

The circular list, or ring buffer is often used for a queue:

tail is the index of the first free cell

~ ~head

tail

01

N-1

yz

a

~ ~head

tail

01

N-1

ab

yz

b

abyz ~

Page 20: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

20

Queues Using arrays

Insert at tail, if not full: put data in cell tail;tail = (tail+1) % N;

Delete from head, if not empty:remove data from cell head;head = (head+1) % N;

Page 21: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

21

Queues Using arrays

When the queue is either fullor empty, the 2 indices havethe same value, so we cannotdistinguish these two cases.

A better way is to use an indexfor the head, and a count of the number of cells occupied.

tail~ ~

head

01

N-1

Page 22: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

22

Queues Using arraysCode when we use an index for head and a count:

(head+count)%N gives the first free cellInsert at tail, if not full:

put data in cell (head+count)%N;count++;

Delete from head, if not empty:remove data from cell head;head = (head+1) % N;count--;

head

01

N-1

count

~~

Page 23: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

23

We use an array in which the data doesn’t move when we do a push() or a pop():

push if not full: pop if not empty:

insert data at cell top+1; remove data from cell top;top++; top--;

Stacks using arrays

~ ~top

0

1

Page 24: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

24

All trees can be implemented using binary trees. Here is an array structure for a binary tree:

Note that array elementzero is not used.

A node with index i (i>1) has its parent at node i/2. The left child of node with index i is at node 2*i.The right child of node with index i is at node 2*i+1.

Binary Trees using Arrays

a b c d e f g1 2 3 4 5 6 7Array Index =

a

b c

d e f g

1

2 3

4 5 6 7

Page 25: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

25

Structures using pointers are particularly useful when the maximum number of elements that must be stored is not known. This is often the case in practice, especially when writing modules for a software library, where the actual users will have many different needs.

Linked List:

Each node contains some data d (a record), and a pointer p. A pointer head points to the first element of the list. The pointer of the last element of the list contains NULL. The nodes are implemented using structs.

Data Structures using Pointers

d NULLd p d phead ~

Page 26: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

26

Here is the declaration of the class and the head pointer:

class List_node { char * name; int age; ~ List_node * next;};

List_node * head = NULL;

Linked Lists in C

d NULLd p d phead ~

Page 27: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

27

Linked Lists in CHere is a function to add new_node at the head of the list:

void add_to_list(List_node * new_node){ new_node -> next = head; /* step 1 */ head = new_node; /* step 2 */}

head

new_node12

Page 28: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

28

Function to remove the first element from the list and return a pointer to it:List_node * remove_first_element(void){ List_node *first = head; /* step 1 */ if(head!=NULL) head = head -> next; /* step 2 */ return first;}

Linked Lists in C cont’d

head

first 1

2

Page 29: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

29

Function to search a linked list for a certain name and return a pointer to the node if a match is found:

List_node * search_list(char * key){ List_node * ptr = head; while(ptr != NULL) { if(strcmp(key, ptr -> name)= = 0) break; ptr = ptr -> next; } return ptr;}

Linked Lists in C cont’d

Page 30: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

30

In a queue, data is added at one end (the tail) and removed from the other end (the head). A linked list is adequate for this purpose with the addition of a pointer to the tail:

class Queue_node {char * name;int age; ~Queue_node * next;};

class Queue {Queue_node * head;Queue_node * tail;};

Queues using Linked Lists

d p d p d NULL~

tail

head

Queue

Page 31: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

31

Inserting at the queue tailvoid add_to_tail(Queue_node * elem) {

if(q.tail = = NULL) /* queue is empty */ q.head = q.tail = elem; else { q.tail -> next = elem; q.tail = elem; }

d p d p d NULL~

tail

head

Queue

d NULL1

2

elem

Page 32: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

32

Data is added and removed from the same end (the head) of the list. Implementation is trivial using a singly linked list:class Stack_node {int datum;Stack_node * next;};

class Int_stack {List_node * front;};

Int_stack s;

Stacks Using Linked Lists

d p d p d NULL~

front

Int_stack

Page 33: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

33

Stacks Using Linked Lists cont’dHere the interface uses the actual data, not pointers to nodes:

void push(int new_datum){Stack_node *ptr = new Stack_node; ptr -> datum = new_datum; ptr -> next = s.front; /* step 1 */ s.front = ptr; /* step 2 */}

d p d p d NULL~

d p new_datum

1

2

2

front

Int_stack

Page 34: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

34

Stacks Using Linked Lists cont’dpop() must free the space occupied by the top node:int pop(void)

{ Stack_node *ptr = s.front; /* step 1 */ int result; if(s.front!=NULL) { result = s.front -> datum; s.front = s.front -> next; /* step 2 */ free(ptr); return result; /* step 3 */ } return ERROR; /* a special value to indicate

empty stack */ }

Page 35: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

35

Stacks Using Linked Lists cont’d

Pop in action:

~

12

3

d p d p d NULL

ptr

2

front

Int_stack

Page 36: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

36

The basic structure uses two pointers in each node:

class Tree_node {char * name;int age; ~Tree_node * left_child;Tree_node * right_child;};

In some applications it is also necessary to include a pointer to the parent node.

Binary Trees Using Pointers

name age

left_child right_child

~

Page 37: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

37

Trees can be traversed in a number of standard orders:

void preorder(Tree_node *n) pass in pointer to the{ root, it visits all nodes if(n= =NULL) return; print(n); /* access data */ preorder(n -> left_child); preorder(n -> right_child); }

gives order 1, 2, 4, 5, 3, 6, 7

Preorder Traversals

a

b c

d e f g

1

2 3

4 5 6 7

Page 38: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

38

Postorder Traversals

void postorder(Tree_node * n){ if(n= = NULL) return; postorder(n -> left_child); postorder(n -> right_child); print(n);}

gives order 4, 5, 2, 6, 7, 3, 1

a

b c

d e f g

1

2 3

4 5 6 7

Page 39: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

39

void inorder(Tree_node * n){ We can tell if *n if(n is a leaf node) print(n); is a leaf node by else { testing to see if inorder(n -> left_child); both its child print(n); pointers are NULL inorder(n -> right_child); }

}

gives order 4, 2, 5, 1, 6, 3, 7

Inorder Traversal

a

b c

d e f g

1

2 3

4 5 6 7

Page 40: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

40

Binary Search TreesIn order to enable fast searches, the elements of the left

and right sub-trees of any node n, must have key values that are related to the key value in that node. This relationship must apply to all interior nodes, including the root node.

In the binary search tree, the following relationship holds:

keys in left sub-tree of n < key of n < keys in right sub-tree of n 7

4 9

2 6 8 11

<x >x

key x

left sub-tree of n right sub-tree of n

node n

Page 41: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

41

Binary Search Trees

Search, insert, and delete, can all be done in average time log n. If the tree remains balanced, these operations take O(log n).

Here is the class:class Tree_node {int key; ~Tree_node * left_child, * right_child;};

Page 42: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

42

Tree_node * search(int skey, Tree_node * n){ if(n = = NULL) return NULL; if(skey = = n -> key) return ptr; if(skey < n -> key) return(search(skey, n -> left_child)); else return(search(skey, n -> right_child));}

Binary Search Tree: Search

7

4 9

2 6 8 11

Page 43: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

43

void insert(Tree_node * new_node, Tree_node ** n){ if(*n = = NULL) { /* we have reached a leaf */ *n = new_node; /* n now pts to new_node */ new_node -> left_child = NULL; new_node -> right_child = NULL; } else if(new_node -> key < (*n) -> key) insert(new_node, &((*n) -> left_child)); else if(new_node -> key > (*n) -> key) insert(new_node, &((*n) -> right_child));}

Binary Search Tree: Insertion

Page 44: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

44

Insertion exampleAssume ~ means NULL

The insertion begins with a search for the key value to be inserted. When this position is located, n contains the address of the left-child/right-child pointer of the parent node. This pointer value is changed to point to the new node.

10

root

2 ~ 40 ~

~ 1 ~ ~ 6 ~ 45

The insertionchanges the pointer right_child

n

Page 45: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

45

We will use value semantics this time. This function deletes the node with the smallest key and returns its value:

int delete_min(Tree_node **n){ int result; if((*n) -> left_child = = NULL) {

result = (*n) -> key; *n = (*n) -> right_child; free(*n); return result;

} else return delete_min(&((*n)->left_child));}

Binary Search Trees, Delete_min

7

4 9

6 8 11

Page 46: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

46

delete() removes the node holding a given key:void delete(int value; Tree_node **n) {

if((*n) != NULL) { if(value > (*n) -> key) delete(value, (*n) -> left_child); if(value < (*n) -> key) delete(value, (*n) -> right_child); if((*n) -> left_child = = NULL) if((*n) -> right_child = = NULL) *n = NULL; else *n = (*n) -> right_child; else if((*n) -> right_child = = NULL) *n = left_child; else (*n) -> key = delete_min((*n) -> right_child)

}}

Binary Search Trees, Deletion

Page 47: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

47

Completely Balanced Binary TreesKeeping a binary tree completely balanced implies O(n)

time for insertion (actually rebalancing after insertion):

Insert 1

RebalanceThe rebalance operation here

required a change to every node, taking O(n) time. For this reasonwe use “almost balanced binarytrees,” such as AVL and 2-3 trees.

5

7

6

3

2 4

5

7

6

3

2 4

1

4

6

5

2

1 3 7

Page 48: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

48

AVL TreesFirst we define the height of a binary tree to be the length of the

longest path from the root to a leaf node. The AVL property: if N is a node in a binary tree, node N has

the AVL property if the heights of its left and right sub-trees differ by no more than 1. If all nodes, including the root, have the AVL property, then the tree is an AVL tree.

It is possible to do insert, delete, and search in O(log n) time in an AVL tree.

AVL trees

Page 49: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

49

2-3 Trees

A 2-3 tree has the following properties:• Each interior node has 2 or 3 children• Each path from the root to a leaf node has the same length.smallest descendent smallest descendentof 2nd child of 3rd child, or -

In this version, all data are recorded in leaf nodes

7 16

19 -

16 19

5 -

2 5

8 12

7 8 12

Page 50: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

50

Searching a 2-3 Tree

Assume that the search has reached the y/z node belowand we are searching for the key x. If x<y, goto the leftchild next, if y<=x and x<z or there is no third child, goto the 2nd child next, and if x>z, goto the third child next.

y z

x<y y<=x<z z<x

y -

x<y x>=y

Page 51: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

51

Insertion into 2-3 Trees

Say we wish to insert new_node with key x. We first search for x and stop at an interior node N, just above the leaf nodes where the node containing x would be if it existed.

If N has only 2 children, new_node becomes a new child of N, placed in the proper order:

+4 = +6 =5 -

2 5

4 5

2 54

5 -

2 5

5 6

2 65

Page 52: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

52

Insertion into 2-3 Trees cont’d

A node has to be split if it already has 3 children:

+3 =

4 -

3 - 5 -

2 3 4 5

4 5

2 54

Page 53: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

53

Insertion into 2-3 Trees cont’d

A special case occurs when the root has to be split:

+4 =

3 7

2 733 -

2 3

7 -

4 7

4 -

This only occurs when there are exactly 3 data elements in the tree before the insertion.

Page 54: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

54

Deletion

When a leaf node is deleted, its parent P may be left with only one child. If P has a neighboring sibling Q with 3 leaves. The leaves of P and Q can be shared, 2 each between them:

2 44 7

3 - 6 7

4 -

P Q

6

-3 =4 - 7 -

6 -

P Q

2 3 6 7

This processdoes not leadto further recursion upthe tree.

Page 55: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

55

DeletionIf P does not have a neighboring sibling with 3 children,

then it must have a neighboring sibling Q with 2 children. We combine P and Q, giving all three leaves to the combined node PQ:

-3 =

As we can see, this process mayleave the parentof PQ with 1 child,so the process must continue upthe tree recursively

3 -

2 3

7 -

4 7

4 -

P Q

- -

4 7

2 4 7

PQ

Page 56: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

56

Deletion

When the root node has only one child, it may be deleted, its single child becomes the new root node:

- -

4 7

2 4 7

PQ 4 7

2 4 7

PQ

old root

new root

We may reach the root, leaving it in this condition, by recursion up the tree.

Page 57: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

57

Struct for 2-3 treestypedef struct two_three_node { Could use a int kind; // 0=leaf, 1=interior union of the

int low_of_second, low_of_third; 2 node typesint key; ~two_three_node * left_child;two_three_node * right_child;};

two_three_node * root; // pointer to root node

We shall not pursue the details of the coding of the algorithms.

Page 58: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

58

Rotations in AVL TreesRotations are used to reestablish the AVL property after

an insertion:

Single Rotation to the right

Single Rotation to the left

B

A

T1 T2

T3

A

B

T3T2

T1

A

B

T3T2

T1

B

A

T1 T2

T3

Page 59: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

59

Double Rotations in AVL Trees

Double Rotation to Right

DoubleRotation to Left

C

T4

B

T2 T3

A

T1

A

T1

B

T3T2

C

T4

A

T1 T2

C

T3 T4

B

A

T1 T2

C

T3 T4

B

Page 60: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

60

Example of building an AVL TreeSay we have the keys 19, 10, 3, 5, 20, 13, 17, 15, 1, 8, 6 to

be inserted in that order:

19 19

10

19

10

3

10

3 19

SRR

10

3 19

2013

17

5

+10= +3=

+5,20,13,17=

Page 61: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

61

Example of building an AVL Tree

The addition of 15 causes an unbalance at node 13, so a double left rotation is req’d:

15

13

17

15

1713

DRL

10

19

2015

17

3

5

8

1

13

+1,8=

Page 62: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

62

AVL Tree Example cont’dThe addition of 6 causes an

imbalanceat node 5. A double left rotation isneeded to fix it.

This gives the final AVL Tree:

10

19

2015

17

3

5

8

1

13

5

8

6

6

85

DRL

10

19

2015

17

3

6

8

1

135

Page 63: C++ Notes 1995Copyright Ivor Page 1995 1 Advanced C Programming Ivor Page

C++ Notes 1995 Copyright Ivor Page 1995

63

The only addition to the nodes is a balance factor, which gives the difference between the heights of the left and right sub-trees, and should be +1, 0, or -1, in an AVL tree.

typedef struct AVL_node {int balance_factor;int key; ~AVL_node * left_child;AVL_node * right_child;};

We shall not pursue the details of the coding of the algorithms.

AVL Tree Implementation