Download 57:017, Computers in Engineering Dynamic Data Structures

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Quadtree wikipedia , lookup

Linked list wikipedia , lookup

Red–black tree wikipedia , lookup

B-tree wikipedia , lookup

Lattice model (finance) wikipedia , lookup

Interval tree wikipedia , lookup

Binary tree wikipedia , lookup

Binary search tree wikipedia , lookup

Transcript
57:017, Computers in
Engineering
Dynamic Data Structures
Introduction
z
Dynamic data structures
z
Data structures that grow and shrink during
execution
z
Linked lists
ƒ
z
ƒ
z
Allow insertions and removals only at top of stack
Queues
ƒ
z
Allow insertions and removals anywhere
St k
Stacks
Allow insertions at the back and removals from the front
Binary trees
ƒ
High-speed searching and sorting of data and efficient
elimination of duplicate data items
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
Self-Referential Structures
z
Self-referential structures
z
z
Structure that contains a field that is a pointer to a
structure of the same type
Can be linked together to form useful data structures
such as lists, queues, stacks and trees
struct node {
t data;
int
struct node *nextPtr;
}
z
nextPtr
z
Points to an object of type node
z
Referred to as a link
z Ties one node to another node
z
Terminated with a NULL pointer
Linked Lists
z
Linked list
z
z
z
z
z
z
Linear collection of self-referential structures, called
nodes
Connected by pointer links
Accessed via a pointer to the first node of the list
Subsequent
q
nodes are accessed via the link-pointer
p
member of the current node
Link pointer in the last node is set to NULL to mark the
list’s end
Dynamic Memory Allocation
Two self-referential structures linked together:
15
sPtr
10
What is going on in the computer memory?
struct node {
int data;
struct node *nextPtr;
}
sPtr ÅÆ
Address
Value
4000
6000
…..
…..
sPtr->data ÅÆ
6000
15
sPtr->nextPtr ÅÆ
6004
7000
…..
sPtr->nextPtr->data ÅÆ
sPtr->nextPtr->nextPtr ÅÆ
…..
7000
10
7004
NULL
Linked Lists
struct listNode{
char data;
struct listNode *nextPtr;
};
typedef struct listNode ListNode;
typedef ListNode * ListNodePtr;
struct listNode * startPtr;
ListNode * startPtr;
ListNodePtr startPtr;;
All 3 definitions are equivalent
Pick y
your favorite
Use a linked list instead of an array when
z
z
z
You have an unpredictable number of data elements
Your list needs to be sorted quickly
You need to do insertions and deletions within the list
1
Linked Lists
/* Fig. 12.3: fig12_03.c
1
Address
startPtr ÅÆ
Value
3000
17
3004
6500
…..
6000
3
#include <stdio.h>
4
#include <stdlib.h>
fig12_03.c
(Part 1 of 8)
5
What is going on in the computer memory?
(*startPtr).data, startPtr->data ÅÆ
(*startPtr).nextPtr, startPtr->nextPtr ÅÆ
Operating and maintaining a list */
2
struct listNode{
char data;
struct listNode *nextPtr;
};
struct listNode * startPtr;
…..
3000
…..
…..
startptr->nextPtr->data ÅÆ
6500
29
startptr->nextPtr->nextPtr ÅÆ
6012
5500
6
/* self-referential structure */
7
struct listNode {
8
char data;
9
struct listNode *nextPtr; /* listNode pointer */
/* define data as char */
10 }; /* end structure listNode */
11
12 typedef struct listNode ListNode;
13 typedef ListNode *ListNodePtr;
14
15 /* prototypes */
16 void insert( ListNodePtr *sPtr, char value );
17 char delete( ListNodePtr *sPtr, char value );
18 int isEmpty( ListNodePtr sPtr );
19 void printList( ListNodePtr currentPtr );
20 void instructions( void );
21
22 int main()
23 {
startPtr is an address of a struct listNode
*startPtr is a struct listNode
…..
…..
8020
93
8024
NULL
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
24
ListNodePtr startPtr = NULL; /* initialize startPtr */
51
/* if character is found */
25
int choice;
/* user's choice */
52
if ( delete( &startPtr, item ) ) {
26
char item;
/* char entered by user */
53
27
28
instructions(); /* display the menu */
29
printf( "? " );
30
scanf( "%d", &choice );
fig12_03.c
(Part 2 of 8)
31
/* loop while user does not choose 3 */
33
while ( choice != 3 ) {
} /* end if */
56
else {
fig12_03.c
(Part 3 of 8)
printf( "%c not found.\n\n", item );
57
} /* end else */
59
34
switch ( choice ) {
60
} /* end if */
61
else {
62
36
37
printList( startPtr );
55
58
32
35
printf( "%c deleted.\n", item );
54
63
case 1:
printf( "List is empty.\n\n" );
} /* end else */
64
38
printf( "Enter a character: " );
39
scanf( "\n%c", &item );
40
insert( &startPtr, item );
41
printList( startPtr );
67
42
break;
68
65
b
break;
k
66
default:
printf( "Invalid choice.\n\n" );
43
69
instructions();
44
70
break;
case 2:
71
45
46
/* if list is not empty */
72
47
if ( !isEmpty( startPtr ) ) {
73
48
printf( "Enter character to be deleted: " );
49
scanf( "\n%c", &item );
} /* end switch */
50
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
74
75
76
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
printf( "? " );
100
scanf( "%d", &choice );
101
} /* end while */
102
77
78
printf( "End of run.\n" );
79
80
return 0; /* indicates successful termination */
fig12_03.c
(Part 4 of 8)
newPtr = malloc( sizeof( ListNode ) );
if ( newPtr != NULL ) {
103
newPtr->data = value;
104
newPtr->nextPtr = NULL;
/* is space available */
fig12_03.c
(Part 5 of 8)
105
106
previousPtr = NULL;
currentPtr = *sPtr;
81
107
82 } /* end main */
108
83
109
/* loop to find the correct location in the list */
84 /* display program instructions to user */
110
while ( currentPtr != NULL && value > currentPtr->data ) {
85 void instructions( void )
111
86 {
112
87
printf( "Enter your choice:\n"
113
previousPtr = currentPtr;
/* walk to ...
currentPtr = currentPtr->nextPtr;
/* ... next node */
*/
} /* end while */
88
"
1 to insert an element into the list.\n"
114
89
"
2 to delete an element from the list.\n"
115
/* insert newPtr at beginning of list */
90
"
3 to end.\n" );
116
if ( previousPtr == NULL ) {
newPtr->nextPtr = *sPtr;
91 } /* end function instructions */
117
92
118
93 /* Insert a new value into the list in sorted order */
119
} /* end if */
94 void insert( ListNodePtr *sPtr, char value )
120
else { /* insert newPtr between previousPtr and currentPtr */
95 {
121
96
ListNodePtr newPtr;
97
ListNodePtr previousPtr; /* pointer to previous node in list */
/* pointer to new node */
123
98
ListNodePtr currentPtr;
124
/* pointer to current node in list */
122
*sPtr = newPtr;
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
} /* end else */
99
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
2
125
} /* end if */
150
/* loop to find the correct location in the list */
126
else {
151
while ( currentPtr != NULL && currentPtr->data != value ) {
127
128
printf( "%c not inserted. No memory available.\n", value );
152
} /* end else */
153
fig12_03.c
(Part 6 of 8)
129
130 } /* end function insert */
previousPtr = currentPtr;
/* walk to ...
currentPtr = currentPtr->nextPtr;
/* ... next node */
155
156
/* delete node at currentPtr */
132 /* Delete a list element */
157
if ( currentPtr != NULL ) {
133 char delete( ListNodePtr *sPtr, char value )
158
tempPtr = currentPtr;
134 {
159
131
ListNodePtr previousPtr; /* pointer to previous node in list */
160
free( tempPtr );
136
ListNodePtr currentPtr;
/* pointer to current node in list */
161
return value;
137
ListNodePtr tempPtr;
/* temporary node pointer */
162
} /* end if */
163
139
/* delete first node */
164
140
if ( value == ( *sPtr )->data ) {
165
141
tempPtr = *sPtr;
} /* end else */
return '\0';
166
*sPtr = ( *sPtr )->nextPtr;
/* de-thread the node */
167
143
free( tempPtr );
/* free the de-threaded node */
168 } /* end function delete */
144
return value;
142
fig12_03.c
(Part 7 of 8)
previousPtr->nextPtr = currentPtr->nextPtr;
135
138
*/
} /* end while */
154
169
145
} /* end if */
170 /* Return 1 if the list is empty, 0 otherwise */
146
else {
171 int isEmpty( ListNodePtr sPtr )
147
previousPtr = *sPtr;
172 {
148
currentPtr = ( *sPtr )->nextPtr;
173
149
return sPtr == NULL;
174
175 } /* end function isEmpty */
176
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
177 /* Print the list */
178 void printList( ListNodePtr currentPtr )
179 {
180
181
/* if list is empty */
182
if ( currentPtr == NULL ) {
183
} /* end if */
185
else {
? 1
Enter a character: C
The list is:
A -->
> B -->
> C -->
> NULL
printf( "The list is:\n" );
187
188
/* while not the end of the list */
/
/
189
while ( currentPtr != NULL ) {
190
printf( "%c --> ", currentPtr->data );
191
currentPtr = currentPtr->nextPtr;
192
? 2
Enter character to be deleted: D
D not found.
} /* end while */
? 2
Enter character to be deleted: B
B deleted.
The list is:
A --> C --> NULL
193
194
195
Program Output
(Part 1 of 3)
? 1
Enter a character: A
The list is:
A --> B --> NULL
printf( "List is empty.\n\n" );
184
186
fig12_03.c
(Part 8 of 8)
Enter your choice:
1 to insert an element into the list.
2 to delete an element from the list.
3 to end.
? 1
Enter a character: B
The list is:
B --> NULL
printf( "NULL\n\n" );
} /* end else */
196
197 } /* end function printList */
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
? 2
Enter character to be deleted: C
C deleted.
The list is:
A --> NULL
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
Program Output
(Part 2 of 3)
Program Output
(Part 3 of 3)
? 2
Enter character to be deleted: A
A deleted.
List is empty.
? 4
Invalid choice.
Enter your choice:
1 to insert an element into the list.
2 to delete an element from the list.
list
3 to end.
? 3
End of run.
? 4
Invalid choice.
Enter your choice:
1 to insert an element into the list.
2 to delete an element from the list.
3 to end.
? 3
End of run.
? 2
Enter character to be deleted: C
C deleted.
The list is:
A --> NULL
? 2
Enter character to be deleted: A
A deleted.
List is empty.
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
3
Important Note about the
insert and delete functions
z
Note that the actual type of the first parameter passed to
these functions (the list anchor pointer) is:
listNode **sPtr (i.e. sPrtr is a pointer to
pointer to listNode)
sPtr
z
*sPtr
Since the insert and delete functions must change the
value of the list anchor pointer in some cases—i.e
deleting the first element of the list or inserting at the
beginning of the list, the list anchor pointer must be
passed by reference—i.e. as a pointer to the list anchor
pointer
Linked List—insertion of a new
element
Important Note (con’t)
function call in main program,
insert(&startPtr, ‘w’);
call-by-reference, pass memory
address of startPtr so value of
startPtr can be changed in function
void insert(listNode **sPtr, char value){
function
definition
......};
struct listNode{
char data;
struct listNode *nextPtr;
};
struct listNode *startPtr;
startPtr;
z
sPtr
*sPtr
startPtr
Read from right to left:
sPtr is an address of an address
of a listNode
*sPtr is an address of a listNode
**sPtr is a listNode
Address
Value
sPtr ÅÆ 5000
6000
…..
…..
startPtr, *sPtr ÅÆ 6000
6016
…..
…..
(**sPtr).data, (*sPtr)->data ÅÆ 6016
6017-6019
‘z’
unused
(**sPtr).nextPtr, (*sPtr)->nextPtr ÅÆ 6020
NULL
Pseudocode for Insert() function
1
Attempt to malloc a new node and set newPtr to
point at this node.
2. If malloc is successful (i.e. newPtr != NULL)
2.1 Assign value to data field of new node and initialize
its nextPtr field to NULL
2.2 Search for proper insertion point of new node in list
2.3 Reassign pointers to link the new cell into the list at
proper insertion point.
Else
2.4 print error message
3. Return
Refinement of step 2.2
2.2.1
initialize previousPtr to NULL and currentPtr to point at first
list element
While the list has not been exhausted and the data field of
node pointed to by currentPtr is less than the new data
2.2.2.1 Advance PreviousPtr and CurrentPtr by one node.
2.2.2
Note: There are two possible conditions for exiting the loop:
a) A node whose data field is greater than the new value has
been encountered (currentPtr points at this node)
or
b) The entire list has been traversed without finding a node whose
data portion is greater than the new value. (In this case the new
node goes at the end of the list, or becomes the only element in
the list if the list was previously empty.
void insert( ListNodePtr *sPtr, char value ) {
ListNodePtr newPtr;
/* pointer to new node */
ListNodePtr previousPtr; /* pointer to previous node in list */
ListNodePtr currentPtr; /* pointer to current node in list */
newPtr = malloc( sizeof( ListNode ) ); /* create node */
if ( newPtr != NULL ) { /* is space available */
newPtr->data = value; /* place value in node */
newPtr->nextPtr = NULL; /* node does not link to another node */
previousPtr = NULL;
currentPtr = *sPtr;
/* loop to find the correct location in the list */
while ( currentPtr != NULL && value > currentPtr->data ) {
previousPtr = currentPtr;
/* walk to ...
*/
currentPtr = currentPtr->nextPtr; /* ... next node */
} /* end while */
/ insert new node at beginning of list */
/*
/
if ( previousPtr == NULL ) {
newPtr->nextPtr = *sPtr;
*sPtr = newPtr;
} /* end if */
else { /* insert new node between previousPtr and currentPtr */
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
} /* end else */
} /* end if */
else {
printf( "%c not inserted. No memory available.\n", value );
} /* end else */
} /* end function insert */
4
Deletion from a linked list
Pseudocode for delete()
function
1. If the node to be deleted is the first node in the list
1.1 Reassign the list’s anchor pointer (sPtr) to point at second list node ( or set
it to NULL if there is not a second list node)
1.2 Free the first list node
1.3 Return value
Else
1.4 Search the list until either the node with matching data value is found or end
off list
li t iis encountered
t d
1.5 If node to be deleted is found
1.5.1 Reassign the nextPtr field of preceding node to point to following
node in list (or to null if the node to be deleted is the last element in
the list)
1.5.2 Free the deleted node
1.5.3 Return value
else
1.5.4 No matching node exists in the list—no deletion is
preformed
1.5.5 Return null charactter
/* Delete a list element */
char delete( ListNodePtr *sPtr, char value ) {
ListNodePtr previousPtr; /* pointer to previous node in list */
ListNodePtr currentPtr; /* pointer to current node in list */
ListNodePtr tempPtr;
/* temporary node pointer */
/* delete first node */
if ( value == ( *sPtr )->data ) {
tempPtr = *sPtr; /* hold onto node being removed */
*sPtr = ( *sPtr )->nextPtr; /* de-thread the node */
free( tempPtr ); /* free the de-threaded node */
return value;
} /* end if */
else {
previousPtr = *sPtr;
currentPtr = ( *sPtr
sPtr )->nextPtr;
) >nextPtr;
/* loop to find the correct location in the list */
while ( currentPtr != NULL && currentPtr->data != value ) {
previousPtr = currentPtr;
/* walk to ...
*/
currentPtr = currentPtr->nextPtr; /* ... next node */
} /* end while */
/* delete node at currentPtr */
if ( currentPtr != NULL ) {
tempPtr = currentPtr;
previousPtr->nextPtr = currentPtr->nextPtr;
free( tempPtr );
return value;
} /* end if */
} /* end else */
return '\0';
} /* end function delete */
The printList() function
/* Print the list */
void printList( ListNodePtr currentPtr ) {
/* if list is empty */
if ( currentPtr == NULL ) {
printf( "List is empty.\n\n" );
} /* end if */
else {
printf( "The list is:\n" );
/* while not the end of the list */
while ( currentPtr != NULL ) {
printf( "%c --> ", currentPtr->data );
currentPtr = currentPtr->nextPtr;
} /* end while */
The isEmpty() function
/* Return 1 if the list is empty, 0 otherwise */
int isEmpty( ListNodePtr sPtr ) {
return sPtr == NULL;
} /* end function isEmpty */
Note: (sPtr == NULL) is a logical expression that evaluates to 1(TRUE) if
sPtr is null and to 0 (false) otherwise
Stacks
z
Stack
z
z
z
z
z
z
push
z
printf( "NULL\n\n" );
} /* end else */
} /* end function printList */
z
New nodes can be added and removed only at the top
Similar to a pile of dishes
Last-in, first-out (LIFO)
Bottom of stack indicated by a link member to NULL
Constrained version of a linked list
Adds a new node to the top of the stack
pop
z
z
z
Removes a node from the top
Stores the popped value
Returns true if pop was successful
5
Stacks
Stacks
/* Fig. 12.8: fig12_08.c
1
dynamic stack program */
2
Stacks
3
#include <stdio.h>
4
#include <stdlib.h>
fig12_08.c
(Part 1 of 6)
5
6
/* self-referential structure */
7
struct stackNode {
8
int data;
9
struct stackNode *nextPtr; /* stackNode pointer */
/* define data as an int */
10 }; /* end structure stackNode */
11
12 typedef struct stackNode StackNode;
13 typedef StackNode *StackNodePtr;
14
15 /* prototypes */
16 void push( StackNodePtr *topPtr, int info );
17 int pop( StackNodePtr *topPtr );
18 int isEmpty( StackNodePtr topPtr );
19 void printStack( StackNodePtr currentPtr );
20 void instructions( void );
21
22 /* function main begins program execution */
23 int main()
24 {
25
StackNodePtr stackPtr = NULL;
/* points to stack top */
26
int choice;
/* user's menu choice */
27
int value;
/* int input by user */
28
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
29
instructions(); /* display the menu */
54
printStack( stackPtr );
30
printf( "? " );
55
break;
31
scanf( "%d", &choice );
56
57
32
33
/* while user does not enter 3 */
34
while ( choice != 3 ) {
35
36
switch ( choice ) {
fig12_08.c
(Part 2 of 6)
58
instructions();
break;
/* push value onto stack */
63
39
case 1:
64
40
printf( "Enter an integer: " );
65
41
scanf( "%d", &value );
66
push( &stackPtr, value );
67
43
printStack( stackPtr );
68
44
break;
69
70
45
} /* end switch */
printf( "? " );
scanf( "%d", &choice );
} /* end while */
printf( "End of run.\n" );
return 0; /* indicates successful termination */
46
/* pop value off stack */
71
47
case 2:
72 } /* end main */
73
48
49
/* if stack is not empty */
74 /* display program instructions to user */
50
if ( !isEmpty( stackPtr ) ) {
75 void instructions( void )
51
52
fig12_08.c
(Part 3 of 6)
61
38
42
printf( "Invalid choice.\n\n" );
60
62
37
default:
59
printf( "The popped value is %d.\n", pop( &stackPtr ) );
} /* end if */
53
76 {
77
printf( "Enter choice:\n"
78
"1 to push a value on the stack\n"
79
"2 to pop a value off the stack\n"
80
"3 to end program\n" );
81 } /* end function instructions */
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
82
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
6
83 /* Insert a node at the stack top */
108
tempPtr = *topPtr;
84 void push( StackNodePtr *topPtr, int info )
109
popValue = ( *topPtr )->data;
85 {
110
*topPtr = ( *topPtr )->nextPtr;
fig12_08.c
(Part 4 of 6)
StackNodePtr newPtr; /* pointer to new node */
86
87
newPtr = malloc( sizeof( StackNode ) );
88
111
free( tempPtr );
112
113
return popValue;
fig12_08.c
(Part 5 of 6)
114
89
90
/* insert the node at stack top */
115 } /* end function pop */
91
if ( newPtr != NULL ) {
116
92
newPtr->data = info;
117 /* Print the stack */
93
newPtr->nextPtr = *topPtr;
118 void printStack( StackNodePtr currentPtr )
94
*topPtr = newPtr;
119 {
95
} /* end if */
120
96
else { /* no space
p
available */
121
/* if stack is empty
p y */
122
if ( currentPtr == NULL ) {
printf( "%d not inserted. No memory available.\n", info );
97
} /* end else */
98
123
printf( "The stack is empty.\n\n" );
99
124
} /* end if */
100 } /* end function push */
125
else {
101
126
102 /* Remove a node from the stack top */
127
103 int pop( StackNodePtr *topPtr )
128
/* while not the end of the stack */
104 {
129
while ( currentPtr != NULL ) {
105
StackNodePtr tempPtr; /* temporary node pointer */
130
106
int popValue;
131
/* node value */
132
107
printf( "The stack is:\n" );
printf( "%d --> ", currentPtr->data );
currentPtr = currentPtr->nextPtr;
} /* end while */
133
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
printf( "NULL\n\n" );
134
} /* end else */
135
136
137 } /* end function printList */
138
fig12_08.c (Part 6
of 6)
139 /* Return 1 if the stack is empty, 0 otherwise */
? 2
The popped value is 4.
The stack is:
6 --> 5 --> NULL
140 int isEmpty( StackNodePtr topPtr )
141 {
142
? 1
Enter an integer: 4
The stack is:
4 --> 6 --> 5 --> NULL
return topPtr == NULL;
143
Program Output
(Part 2 of 2)
? 2
The popped value is 6.
The stack is:
5 --> NULL
144 } /* end function isEmpty */
? 2
The p
popped
pp
value is 5.
The stack is empty.
Enter choice:
1 to push a value on the stack
2 to pop a value off the stack
3 to end program
? 1
Enter an integer: 5
The stack is:
5 --> NULL
? 1
Enter an integer: 6
The stack is:
6 --> 5 --> NULL
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
Queues
z
? 4
Invalid choice.
Program Output
(Part 1 of 2)
Enter choice:
1 to push a value on the stack
2 to pop a value off the stack
3 to end program
? 3
End of run.
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
Queues
Queue
z
z
z
z
z
? 2
The stack is empty.
Similar to a supermarket checkout line
First-in, first-out (FIFO)
Nodes are removed only from the head
Nodes are inserted only at the tail
Insert and remove operations
z
Enqueue (insert) and dequeue (remove)
7
Queues
Queues
/* Fig. 12.13: fig12_13.c
1
3
4
#include <stdio.h>
5
#include <stdlib.h>
fig12_13.c
(Part 1 of 7)
6
7
/* self-referential structure */
8
struct queueNode {
28
QueueNodePtr tailPtr = NULL; /* initialize tailPtr */
29
int choice;
/* user's menu choice */
30
char item;
/* char input by user */
31
32
instructions(); /* display the menu */
33
printf( "? " );
char data;
/* define data as a char */
10
struct queueNode *nextPtr; /* queueNode pointer */
35
11 }; /* end structure queueNode */
12
36
/* while user does not enter 3 */
37
while ( choice != 3 ) {
38
13 typedef struct queueNode QueueNode;
40
15
16 /* function prototypes */
17 void printQueue( QueueNodePtr currentPtr );
18 int isEmpty( QueueNodePtr headPtr );
19 char dequeue( QueueNodePtr *headPtr, QueueNodePtr *tailPtr );
41
/* enqueue value */
42
case 1:
43
printf( "Enter a character: " );
44
scanf( "\n%c", &item );
enqueue( &headPtr, &tailPtr, item );
45
20 void enqueue( QueueNodePtr *headPtr, QueueNodePtr *tailPtr,
char value );
21
switch( choice ) {
39
14 typedef QueueNode *QueueNodePtr;
22 void instructions( void );
46
printQueue( headPtr );
47
break;
48
23
24 /* function main begins program execution */
25 int main()
49
/* dequeue value */
50
case 2:
51
26 {
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
52
/* if queue is not empty */
53
if ( !isEmpty( headPtr ) ) {
54
item = dequeue( &headPtr, &tailPtr );
55
printf( "%c has been dequeued.\n", item );
} /* end if */
57
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
78 /* display program instructions to user */
79 void instructions( void )
80 {
fig12_13.c
(Part 3 of 7)
81
printf ( "Enter your choice:\n"
82
"
1 to add an item to the queue\n"
83
"
2 to remove an item from the queue\n"
"
3 to end\n" );
58
printQueue( headPtr );
84
59
break;
85 } /* end function instructions */
60
61
default:
87 /* insert a node a queue tail */
printf( "Invalid choice.\n\n" );
88 void enqueue( QueueNodePtr *headPtr, QueueNodePtr *tailPtr,
63
instructions();
89
64
break;
90 {
65
91
} /* end switch */
67
93
printf( "? " );
94
69
scanf( "%d", &choice );
95
} /* end while */
71
72
73
74
96
97
printf( "End of run.\n" );
return 0; /* indicates successful termination */
char value )
QueueNodePtr newPtr; /* pointer to new node */
92
68
70
fig12_13.c
(Part 4 of 7)
86
62
66
fig12_13.c
(Part 2 of 7)
scanf( "%d", &choice );
34
9
56
QueueNodePtr headPtr = NULL; /* initialize headPtr */
27
Operating and maintaining a queue */
2
newPtr = malloc( sizeof( QueueNode ) );
if ( newPtr != NULL ) { /* is space available */
newPtr->data = value;
newPtr->nextPtr = NULL;
98
99
/* if empty, insert node at head */
100
if ( isEmpty( *headPtr ) ) {
75
101
76 } /* end main */
102
*headPtr = newPtr;
} /* end if */
77
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
8
else {
103
130
( *tailPtr )->nextPtr = newPtr;
104
fig12_13.c
(Part 5 of 7)
106
*tailPtr = newPtr;
107
free( tempPtr );
131
} /* end else */
105
132
return value;
133
134 } /* end function dequeue */
108
} /* end if */
135
109
else {
136 /* Return 1 if the list is empty, 0 otherwise */
printf( "%c not inserted. No memory available.\n", value );
110
111
137 int isEmpty( QueueNodePtr headPtr )
} /* end else */
138 {
112
139
113 } /* end function enqueue */
140
114
141 } /* end function isEmpty */
115 /* remove node from queue head */
142
116 char
h
d
dequeue(
( QueueNodePtr
Q
N d Pt *headPtr,
*h dPt
QueueNodePtr
Q
N d Pt *tailPtr
*t ilPt )
143 /* Print
P i t the
th queue */
117 {
144 void printQueue( QueueNodePtr currentPtr )
118
char value;
119
QueueNodePtr tempPtr; /* temporary node pointer */
/* node value */
return headPtr == NULL;
145 {
146
147
/* if queue is empty */
121
value = ( *headPtr )->data;
148
if ( currentPtr == NULL ) {
122
tempPtr = *headPtr;
149
123
*headPtr = ( *headPtr )->nextPtr;
150
} /* end if */
151
else {
120
124
125
/* if queue is empty */
152
126
if ( *headPtr == NULL ) {
153
printf( "The queue is:\n" );
} /* end if */
129
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
154
/* while not end of queue */
155
while ( currentPtr != NULL ) {
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
printf( "%c --> ", currentPtr->data );
156
currentPtr = currentPtr->nextPtr;
157
fig12_13.c
(Part 7 of 7)
} /* end while */
158
159
printf( "NULL\n\n" );
160
161
printf( "Queue is empty.\n\n" );
*tailPtr = NULL;
127
128
fig12_13.c
(Part 6 of 7)
163 } /* end function printQueue */
? 2
C has been dequeued.
Queue is empty.
Enter your choice:
1 to add an item to the queue
2 to remove an item from the queue
3 to end
? 1
Enter a character: A
The queue is:
A --> NULL
? 2
Q
Queue
i
is empty.
t
? 4
Invalid choice.
Enter your choice:
1 to add an item to the queue
2 to remove an item from the queue
3 to end
? 3
End of run.
? 1
Enter a character: B
The queue is:
A --> B --> NULL
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
Program
Output (Part 1
of 2)
Trees
z
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
Trees
Tree nodes contain two or more links
z
z
Program Output
(Part 2 of 2)
? 2
B has been dequeued.
The queue is:
C --> NULL
} /* end else */
162
? 1
Enter a character: C
The queue is:
A --> B --> C --> NULL
? 2
A has been dequeued.
The queue is:
B --> C --> NULL
All other data structures we have discussed only
contain one
Binary trees
z
All nodes contain two links
z
The root node is the first node in a tree.
Each link in the root node refers to a child
A node with no children is called a leaf node
z
z
z
None, one, or both of which may be NULL
9
Trees
z
Binary Search Trees
Binary search tree
z
z
z
z
Values in left subtree less than parent
Values in right subtree greater than parent
Facilitates duplicate elimination
2
Fast searches - for a balanced tree, maximum
of
log n comparisons
Creating A Binary Search Tree
z
27 13 6 17 48 42 33
27
z
13
6
A Quick Aside: Recursion and
Recursive Functions
48
17
int nFact(int N) {
if (N ==0) {
return 1;
}
else {
return N*nFact(N-1);
}
}
42
33
Recursion
z
Recursive function
z
z
Calls itself directly or indirectly through another function
to solve a problem.
Tree Traversal—A Recursive
Algorithm
z
z
Attributes of a “recursive” problem
z
z
z
z
z
Has a “base
base case
case”, or simplest part of problem to solve.
solve
If the function is called with base case, then it simply
returns a result.
Otherwise, function divides problem into the base case
and the part it does not know how to solve.
The unsolved part must resemble the original problem
and be a smaller part of the original problem.
The unsolved part is solved by calling the function with
this smaller problem.
In Mathematics, it is common to define functions recursively:
e.g. Consider the definition of N! (N-factorial):
0! = 1
N! = N(N-1)! for N>0
Can also define C functions recursively:
z
Consider the problem of printing the values of a
binary search tree in ascending order.
The algorithm to do this is extremely difficult to
express in non-recursive terms.
However it’s
However,
it s very simple to express recursively
recursively, as
follows:
If the tree is null, print nothing
Otherwise:
Print the left subtree of the root node in ascending order
Print the value of the root node
Print the right subtree of the root node in ascending order
10
Tree Traversal
z
z
z
z
Tree Traversal (continued)
Since the tree is defined recursively, it is
most convenient and easiest to code using
recursive functions to operate on it
The base case can be either the NULL tree
or a tree with just one node (leaf)
The recursive step operates on the two
subtrees of the current node
Since subtrees are smaller than the original
tree, algorithms are guaranteed to converge
z
z
Unlike a list, there are several ways we can
traverse and print out the elements of a tree
Inorder traversal
z
z
z
z
Print root, left subtree, right subtree
Postorder traversal
z
z
Print left subtree, root, right subtree
Preorder traversal
Print left subtree, right subtree, root
All are defined recursively
Trees
Trees
z
Tree traversals:
z
z
Inorder traversal – prints the node values in ascending
order
1. Traverse the left subtree with an inorder traversal
2. Process the value in the node (i.e., print the node
value)
3. Traverse the right subtree with an inorder traversal
Preorder traversal
1. Process the value in the node
2. Traverse the left subtree with a preorder traversal
3. Traverse the right subtree with a preorder traversal
InOrder Traversal
z
Tree traversals—continued
z
Postorder traversal
1. Traverse the left subtree with a postorder traversal
2. Traverse the right subtree with a postorder traversal
3. Process the value in the node
PreOrder Traversal
typedef struct NODE {
int value;
struct NODE *left_p;
struct NODE *right_p;
} node_t;
typedef struct NODE {
int value;
struct NODE *left_p;
struct NODE *right_p;
} node_t;
void InOrder(node_t *tree_p) {
if (tree_p != NULL) {
InOrder(tree_p->left_p);
printf("%d ",tree_p->value);
InOrder(tree_p->right_p);
}
}
void PreOrder(node_t *tree_p) {
if (tree_p != NULL) {
printf("%d ",tree_p->value);
PreOrder(tree_p->left_p);
PreOrder(tree_p->right_p);
}
}
Note: The tree in this example is not a Binary Search Tree
11
PostOrder Traversal
PostOrder Traversal
typedef struct NODE {
int value;
struct NODE *left_p;
struct NODE *right_p;
} node_t;
typedef struct NODE {
int value;
struct NODE *left_p;
struct NODE *right_p;
} node_t;
void PostOrder(node_t *tree_p) {
if (tree_p != NULL) {
PostOrder(tree_p->left_p);
PostOrder(tree_p->right_p);
printf("%d ",tree_p->value);
}
}
void PostOrder(node_t *tree_p) {
if (tree_p != NULL) {
PostOrder(tree_p->left_p);
PostOrder(tree_p->right_p);
printf("%d ",tree_p->value);
}
}
Displaying a Tree
Printout of Tree Structure
Can use modified inorder traversal to print the tree in a
structured format.
Output of PrintTree
void PrintTree(node_t *tree_p, int indent){
int i;
if (tree_p != NULL){
PrintTree(tree_p->right_p, indent+5);
for(i=1, i<=indent, i++){
printf(“ “);
}
printf(“%d\n”,tree_p->value);
printTree(tree_p->left_p, indent+5);
}
}
1
3
8
4
6
5
2
/* Fig. 12.19: fig12_19.c
2
Create a binary tree and traverse it
3
preorder, inorder, and postorder */
4
#include <stdio.h>
5
#include <stdlib.h>
6
#include <time.h>
fig12_19.c
(Part 1 of 6)
27
int i;
/* counter */
28
int item;
/* variable to hold random values */
29
TreeNodePtr rootPtr = NULL; /* initialize rootPtr */
30
31
srand( time( NULL ) );
32
printf( "The numbers being placed in the tree are:\n" );
fig12_19.c
(Part 2 of 6)
33
7
8
/* self-referential structure */
34
/* insert random values between 1 and 15 in the tree */
9
struct treeNode {
35
for ( i = 1; i <= 10; i++ ) {
10
struct treeNode *leftPtr;
/* treeNode pointer */
36
11
int data;
/* define data as an int */
37
12
struct treeNode *rightPtr; /* treeNode pointer */
38
item = rand() % 15;
printf( "%3d", item );
insertNode( &rootPtr, item );
} /* end for */
13 }; /* end structure treeNode */
39
14
40
15 typedef struct treeNode TreeNode;
41
/* traverse the tree preOrder */
16 typedef TreeNode *TreeNodePtr;
42
printf( "\n\nThe preOrder traversal is:\n" );
17
43
18 /* prototypes */
44
19 void insertNode( TreeNodePtr *treePtr, int value );
45
/* traverse the tree inOrder */
20 void inOrder( TreeNodePtr treePtr );
46
printf( "\n\nThe inOrder traversal is:\n" );
21 void preOrder( TreeNodePtr treePtr );
47
22 void postOrder( TreeNodePtr treePtr );
48
23
49
/* traverse the tree postOrder */
24 /* function main begins program execution */
50
printf( "\n\nThe postOrder traversal is:\n" );
25 int main()
51
postOrder( rootPtr );
26 {
52
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
preOrder( rootPtr );
inOrder( rootPtr );
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
12
else { /* tree is not empty */
76
return 0; /* indicates successful termination */
53
77
54
55 } /* end main */
56
57 /* insert node into tree */
fig12_19.c
(Part 3 of 6)
58 void insertNode( TreeNodePtr *treePtr, int value )
78
/* data to insert is less than data in current node */
79
if ( value < ( *treePtr )->data ) {
insertNode( &( ( *treePtr )->leftPtr ), value );
80
} /* end if */
81
82
59 {
60
83
/* data to insert is greater than data in current node */
84
else if ( value > ( *treePtr )->data ) {
61
/* if tree is empty */
85
62
if ( *treePtr == NULL ) {
86
} /* end else if */
87
else { /* duplicate data value ignored */
*treePtr = malloc( sizeof( TreeNode ) );
63
64
insertNode( &( ( *treePtr )->rightPtr ), value );
printf( "dup" );
88
65
/* if memory was allocated then assign data */
89
66
if ( *treePtr != NULL ) {
90
} /* end else */
67
( *treePtr )->data = value;
91
68
( *treePtr )->leftPtr = NULL;
92
69
( *treePtr )->rightPtr = NULL;
93 } /* end function insertNode */
} /* end else */
70
} /* end if */
94
71
else {
95 /* begin inorder traversal of tree */
96 void inOrder( TreeNodePtr treePtr )
printf( "%d not inserted. No memory available.\n", value );
72
97 {
} /* end else */
73
fig12_19.c
(Part 4 of 6)
98
74
} /* end if */
75
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
121 /* begin postorder traversal of tree */
99
/* if tree is not empty then traverse */
100
if ( treePtr != NULL ) {
101
inOrder( treePtr->leftPtr );
102
printf( "%3d", treePtr->data );
103
104
inOrder( treePtr->rightPtr );
122 void postOrder( TreeNodePtr treePtr )
123 {
fig12_19.c
(Part 5 of 6)
} /* end if */
124
125
/* if tree is not empty then traverse */
126
if ( treePtr != NULL ) {
127
105
128
106 } /* end function inOrder */
107
108 /* begin preorder traversal of tree */
109 void preOrder( TreeNodePtr treePtr )
110 {
129
130
fig12_19.c
(Part 6 of 6)
postOrder( treePtr->leftPtr );
postOrder( treePtr->rightPtr );
printf( "%3d", treePtr->data );
} /* end if */
131
132 } /* end function postOrder */
111
112
/* if tree is not empty then traverse */
113
if ( treePtr != NULL ) {
114
printf( "%3d", treePtr->data );
115
preOrder( treePtr->leftPtr );
116
117
preOrder( treePtr->rightPtr );
} /* end if */
The numbers being placed in the tree are:
6 7 4 12 7dup 2 2dup 5 7dup 11
The preOrder traversal is:
6 4 2 5 7 12 11
The inOrder traversal is:
2 4 5 6 7 11 12
118
119 } /* end function preOrder */
The postOrder traversal is:
2 5 4 11 12 7 6
120
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
An iterative (non-recursive) version of
the insertNode() function:
void insertNode( TreeNodePtr *treePtr, int value ){
TreeNode *insertionPtr;
TreeNode *newPtr;
int insertionPointFound;
newPtr = (TreeNode *) malloc(sizeof(TreeNode));
if(newPtr == NULL) {
printf( "%d not inserted. No memory available.\n", value );
return;
}
else {
newPtr->data = value;
newPtr->leftPtr = NULL;
newPtr->rightPtr = NULL;
}
if ( *treePtr == NULL ) {
/* if tree is empty */
*treePtr = newPtr;
}
Continued on next slide
Program
Output
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved.
Iterative InsertNode() (continued)
else { /* tree is not empty */
insertionPointFound = FALSE;
insertionPtr = *treePtr;
while (!insertionPointFound) {
if (value < (insertionPtr->data)) {
/* data to insert is less than data in current node */
if ((insertionPtr->leftPtr) == NULL) {
insertionPointFound = TRUE;
insertionPtr->leftPtr = newPtr;
}
else {
insertionPtr = insertionPtr->leftPtr;
}
}
else {
if (value > (insertionPtr->data)) {
/ data to insert is greater than data in current node */
/*
/
if ((insertionPtr->rightPtr) == NULL) {
insertionPointFound = TRUE;
insertionPtr->rightPtr = newPtr;
}
else {
insertionPtr = insertionPtr->rightPtr;
}
}
else { /* duplicate data value ignored */
insertionPointFound = TRUE;
printf( "dup" );
free(newPtr); /* new node not needed */
}
}
} /* end while */
} /* end else */
} /* end function insertNode */
13
A Recursive Version of the
TreeSearch Function
Searching a Binary Search Tree
/* The function TreeSearch searches a binary search tree rooted
by rootPtr for a node with data matching the searchArg.
If a match is found, a pointer to the matching node is returned.
Otherwise a NULL pointer is returned */
/* The function TreeSearchRec recursively searches a binary search tree
for a node with data matching the searchArg. If a match is found, a
pointer to the matching node is returned. Otherwise a NULL pointer is
returned */
TreeNodePtr TreeSearch(TreeNodePtr rootPtr, int searchArg) {
TreeNodePtr currentNode;
int MatchFound;
TreeNodePtr TreeSearchRec(TreeNodePtr rootPtr, int searchArg) {
if(rootPtr ==NULL) {
return NULL;
}
else {
if(searchArg == rootPtr->data) {
return rootPtr;
}
else {
if (searchArg < rootPtr->data) {
return TreeSearchRec(rootPtr->leftPtr, searchArg);
}
else {
/* (searchArg > rootPtr->data) */
return TreeSearchRec(rootPtr->rightPtr, searchArg);
}
}
}
} /* end of function TreeSearchRec() */
currentNode = rootPtr;
MatchFound = FALSE;
while((currentNode != NULL) && !MatchFound) {
if (currentNode->data == searchArg) {
MatchFound=TRUE;
}
else {
if (searchArg < currentNode->data) {
currentNode = currentNode->leftPtr;
}
else {
currentNode = currentNode->rightPtr;
}
}
}
return currentNode;
}
A Caveat about Binary Search
Trees
z
BST Balance
z
A BST is efficient for searching and other
operations, only if it is “balanced”.
z
2
5
z
3
3
2
8
4
6
4
9
z
5
z
6
7
A balanced BST
For a BST constructed from a randomly ordered
data stream, the degree of tree balance will be a
random function of the original data order
E.g. for the trees on the previous slide:
An
Unbalanced
BST
7
8
a data order of 5 3 8 2 4 6 7 9 yyields the balanced tree on
the left
a data order of 2 3 4 5 6 7 8 9 yields the unbalanced tree
on the right.
There are a number of sophisticated techniques for
creating balanced BSTs and maintaining balance in
the presence of insertions and deletions.
9
14