Download Linked List

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

Lattice model (finance) wikipedia , lookup

Quadtree wikipedia , lookup

Red–black tree wikipedia , lookup

Interval tree wikipedia , lookup

Binary tree wikipedia , lookup

B-tree wikipedia , lookup

Linked list wikipedia , lookup

Binary search tree wikipedia , lookup

Transcript
Chapter 14
Dynamic Data
Structures
Instructor:
Alkar & Demirer
Dynamic Data Structure
• Dynamic data structure is a structure that can
expand and contract as a program executes.
• The creation and manipulation of dynamic data
structures requires use of pointers.
– A pointer is a variable which stores the memory
address of a data value.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
2
Comparison of Pointer and
Nonpointer Variables
• The actual data value of a pointer variable is
accessed indirectly.
• The actual data value of a nonpointer variable
can be accessed directly.
Pointer variable
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
Nonpointer variable
3
Pointer Review
• A call to a function with pointer parameters may
need to use the & operator.
– e.g., if we have an int variable value1 and
f1(int *value), f1(&value1) is a legal call.
• A pointer can be used to represent an array.
– e.g., char n[] is equal to char *n.
• A pointer can also represent a structure.
– e.g., File * is a pointer to a File structure.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
4
Memory Allocation (1/3)
• C provides a memory allocation function called
malloc, which resides in the stdlib library.
– This function requires an argument which indicates
the amount of memory space needed.
– The returned data type is (void *) and should be
always cast to the specific type.
• E.g.,
Declaration:
int *nump; char *letp; planet_t
*planetp;
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
5
Memory Allocation (2/3)
• Allocation:
nump = (int *) malloc (sizeof
(int));
letp = (char *) malloc (sizeof
(char));
planetp = (planet_t *) malloc
(sizeof (planet_t));
• Assignment:
*nump = 307;
*letp = ‘Q’;
*planetp = blank_planet;
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
6
Memory Allocation (3/3)
Memory space after
allocation
Pointers
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
Memory space after
assignment
Pointers
7
Heap and Stack
• Heap is the region of memory where function
malloc dynamically allocates space for
variables.
• Stack is the region of memory where function
data areas are allocated and reclaimed.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
8
Dynamic Array Allocation
• C provides a function calloc which creates an
array of elements of any type and initializes the
array elements to zero.
– Function calloc takes two arguments: the number
of array elements and the size of one element.
• E.g.,
int *array_of_nums;
array_of_nums = (int *)
calloc(10, sizeof(int));
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
9
Free Memory
• The allocated memory space can be released by
the function free.
– E.g., free(letp) returns the allocated memory
space for the pointer variable letp.
• Once the memory space is released, we can not
access the space again. Otherwise, it is
considered as an illegal memory access.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
10
Multiple Pointers to a Cell
• double *xp, xcopyp;
xp=(double *)malloc(sizeof(double));
*xp=49.5; xcopyp=xp;
• Be careful when releasing memory since the other
pointer may still access the memory space.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
11
Overview
•
•
•
•
•
•
Linked list basics
List Searching
Insertion
Deletion
Stack
Queue
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
12
Linked List
• A linked list is a sequence of nodes in which
each node is linked to the node following it.
• In C, each node can be represented by a struct:
typedef struct node_s{
char current[3];
int volts;
struct node_s *linkp;
}node_t;
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
13
Linked List basics
• A linked list is a sequence of nodes in which each node but the
last contains the address of the next node.
typedef struct list_node_s {
int digit;
struct list_node_s *restp;
} list_node_t;
list_node_t *n1_p, *n2_p;
n1_p = (list_node_t *) malloc (sizeof(list_node_t));
n2_p = (list_node_t *) malloc (sizeof(list_node_t));
n1_p -> digit = 5;
digit
n1_p
n2_p -> digit = 7;
5
n1_p -> restp = n2_p;
n2_p -> restp = NULL;
digit
n2_p
7
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
restp
restp
X
14
Creating Basic Nodes (1/2)
• node_t *n1_p, *n2_p, *n3_p;
n1_p = (node_t *) malloc
(sizeof(node_t));
strcpy(n1_p->current, “AC”);
n1_p->volts = 115;
n2_p = (node_t *) malloc
(sizeof(node_t));
strcpy(n2_p->current, “DC”);
n2_p->volts = 12;
n3_p = n2_p;
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
15
Creating Basic Nodes (2/2)
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
16
Linking Two Nodes
• n1_p->linkp = n2_p;
• “n2_p->volts” is equal to “n1_p->
linkp->volts”
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
17
Three-Node Linked List
• n2_p->linkp = (node_t
*)malloc(sizeof(node_t));
strcpy(n2_p->linkp->current, “AC”);
n2_p->linkp->volts = 220;
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
18
Three-Element Linked List
• The end of a linked list is usually terminated with a null
pointer.
– n2_p->linkp->linkp = NULL;
– The following graph shows a complete linked list whose
length is three.
– The pointer variable n1_p points to the list head.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
19
Linked List After an Insertion
• We can easily insert or delete a node to or from a linked
list.
– The following graph shows an insertion of a new node
containing “DC 9” between the second and last nodes.
– Redirects the linkp of the new node to the last node.
– Redirects the linkp of the second node to the new node.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
20
Traversing a Linked List Recursively
or Iteratively
• We can print each element in a linked list
recursively or iteratively.
Recursive solution
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
Iterative solution
21
Link List Operation (Searching)
Find First occurrence of target in the list.
1. What if I put cur_nodep++ instead of cur_nodep -> restp?
Could that work? When?
2. What if the order of the following tests are reversed?
(cur_nodep != NULL) && (cur_nodep -> digit != target)
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
22
Link List Operation (Insertion at Head)
• Insert at list’s head (i.e. at the front of the list)
list_node_t * insertH (list_node_t *pHead, int v) {
list_node_t *newp;
newp = (list_node_t *) malloc(sizeof(list_node_t));
newp->digit = v;
newp->restp = pHead;
return newp; /* return pointer to the new head of the list */
}
int main(void){
list_node_t * pHead = NULL;
pHead = insertH(pHead, 3);
pHead = insertH(pHead, 5);
pHead = insertH(pHead, 7);
pHead = insertH(pHead, 9);
}
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
typedef struct list_node_s {
int digit;
struct list_node_s *restp;
} list_node_t;
23
Link List Operation (Deletion at Head)
• After the insertion at last slide, your list now looks like
pHead
digit
restp
9
digit
restp
digit
7
restp
digit
restp
3
X
5
list_node_t * deleteH (list_node_t * pHead){
list_node_t *newp = pHead -> restp;
/* newp is now pointing to the 2nd element of the list */
free(pHead);
return newp;
/* return pointer to the new head of the list */
}
After the following call
pHead = deleteH (pHead);
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
pHead
digit
7
restp
digit
5
restp
digit
restp
3
24
Lists are arrays
• Quite often the lists are treated as arrays, that
can change their size dynamically.
Index
a
b
data
data
data
data
*next
*next
*next
NULL
1
2
3
0
c
d
• Assumptions
– Indexing of list starts at 0 (as in arrays).
– Every index value is unique.
– Indices are in growing order (incremented by 1).
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
25
Link List Operation (Deletion at Index)
• Delete element at some index of the list
list_node_t * deleteIndex (list_node_t * pHead, int index) {
int i;
list_node_t * newp, *p, * tmpp;
if (index == 0) {
// deleting head
newp = pHead -> restp;
free(pHead);
return newp;
}
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
26
Link List Operation (Deletion at Index)
else {
}
}
// deleting element other than the head
for (p = pHead, i = 1; (i < index) && (p -> restp != NULL); i++)
/* searching for the element that has a pointer to the one to be
deleted */
p = p -> restp;
tmpp = p -> restp;
/* tmpp now points at the element to be deleted */
if(tmpp != NULL)
p -> restp = tmpp -> restp;
/* p now points at the element after the one to be deleted */
else
/* we are dealing with the last element of the list */
p -> restp = NULL;
free(tmpp);
return pHead;
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
27
Representing a stack with a linked list
•
•
•
•
Like a push down stack of books.
Push (insert) at top (pointed by Head)
Pop (remove) from the top (pointed by Head)
Last in first out (LIFO) architecture.
Head
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
Push
7
restp
restp
5
restp
restp
3
restp
X
Pop
28
Push on Stack
typedef struct list_node_s {
int digit;
struct list_node_s *restp;
} list_node_t;
Return pointer to the
new head of the stack
Pointer to the current
head of the stack
• Push on top of the stack
list_node_t * push (list_node_t * sHead, int v) {
list_node_t * p = (list_node_t *)
malloc(sizeof(list_node_t));
int main(void) {
list_node_t * sHead = NULL;
p -> digit = v;
/* Function call for push*/
p -> restp = sHead;
sHead = push(sHead, 3);
sHead = push(sHead, 5);
return p;
return 0;
}
Return the new node as
the head of the stack
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
}
29
Pop from Stack
Return pointer to the
new head of the stack
Pointer to the current
head of the stack
• Pop from the top of the stack
Popped digit as
output parameter
list_node_t * pop (list_node_t * sHead, int * v) {
list_node_t * p;
int main(void) {
list_node_t * sHead = NULL;
*v = sHead ->digit;
int val;
p = sHead -> restp;
sHead = push(sHead, 3);
free (sHead);
sHead = push(sHead, 5);
/* Function call for pop */
return p;
sHead = pop (sHead, &val);
}
Return the new node as
printf(“Popped : %d”, val);
the head of the stack
}
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
return 0;
30
Stack (Summary)
• In stack only top element can be accessed.
• You could make a stack with an array.
– Linked list is just one way.
• Common design for function invocation.
• Both push and pop are constant time operations
on stack.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
31
Representing a Queue with a linked list
•
•
•
•
Like a queue of people waiting
Push at the Head (i.e at the end of the list).
Pop from the Bottom (i.e from the front of the list)
First In First Out (FIFO)
Head
Push
End
Front
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
7
restp
restp
5
restp
restp
3
restp
X
Pop
32
Push on Queue
typedef struct list_node_s {
int digit;
struct list_node_s *restp;
} list_node_t;
Return pointer to the
new head of the queue
• Push is same as stack (at Head)
Pointer to the current
head of the queue
list_node_t * push (list_node_t * qHead, int v) {
list_node_t * p = (list_node_t *)
malloc(sizeof(list_node_t));
int main(void) {
list_node_t * qHead = NULL;
p -> digit = v;
/* Function call for push*/
p -> restp = qHead;
qHead = push(qHead, 3);
qHead = push(qHead, 5);
return p;
return 0;
}
Return the new node as
the head of the queue
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
}
33
Pop from Queue (from the bottom)
list_node_t * pop (list_node_t * qHead, int * v) {
list_node_t * qEnd, * qFront = NULL;
if (qHead -> restp = NULL) { // Queue has only one element
*v = qHead ->digit;
free (qHead);
return NULL;
}
for (qEnd = qHead; qEnd ->restp != NULL; qEnd = qEnd -> restp)
qFront = qEnd;
*v = qEnd -> digit;
qFront -> restp = NULL;
free(qEnd);
Can we write this more efficiently?
return qHead;
}
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
34
Queue (Summary)
• You could implement a queue as an array too.
• You could make a hybrid of stack/queue to access at
either end.
• Common design for process scheduling, event
processing, buffering, input/output etc.
• In our design push is constant time, but pop is O(n)
linear time (where n is the number of elements in the
queue).
• If we record two pointers (front and end) instead of
only one pointer pointing to the head of the list – both
push and pop would have constant time.
– See the implementation in your textbook.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
35
Circular and double linked list
• Circular linked list
pHead -> restp -> restp -> restp -> restp = pHead;
pHead
digit
restp
9
digit
restp
7
digit
restp
digit
5
restp
3
• Double linked list
struct dblLink {
int digit;
struct dblLink * pNext, pPrev;
}
pHead
digit pNext pPrev
9
X
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
digit pNext pPrev
7
digit pNext pPrev
5
X
36
Binary Tree
• We can extend the concept of linked list to binary trees
which contains two pointer fields.
– Leaf node: a node with no successors
– Root node: the first node in a binary tree.
– Left/right subtree: the subtree pointed by the left/right pointer.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
37
Binary Search Tree
• A binary search tree is either empty or has the
property that the item in its root has
– a larger key than each item in the left subtree, and
– a smaller key than each item in its right subtree.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
38
Searching a Binary Search Tree
• If the tree is empty
– The target key is not in the tree
• else if the target key is the root’s key
– The target key is found
• else if the target key is smaller than root’s key
– Search the left subtree
• else
– Search the right subtree
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
39
Searching a Binary Search Tree
Assume
the target
key is 42.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
40
Building a Binary Search Tree
• If the tree is empty
– Insert the new key in the root node
• else if the root’s key matches the new key
– Skip insertion
• else if the new key is smaller than root’s key
– Insert the new key in the left subtree
• else
– Insert the new key in the right subtree
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
41
Building a Binary Search Tree
Assume 40, 20, 10, 50, 65, 45, 30 are inserted
in order.
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
42
Building a Binary Search Tree
The above algorithm implies a recursive
implementation.
Recursive step
Recursive step
Copyright ©2004 Pearson Addison-Wesley. All rights reserved.
43