Upload
uma-sanford
View
59
Download
6
Embed Size (px)
DESCRIPTION
CHAPTER 4 Lists. 4.1 The List ADT:. Objects : ( item 0 , item 1 , , item N 1 ). Operations : Finding the length , N , of a list. Printing all the items in a list. Making an empty list. Finding X item from a list, 0 k < N . - PowerPoint PPT Presentation
Citation preview
Objects: ( item0, item1, , itemN1 )
Operations: Finding the length, N, of a list.
Printing all the items in a list.
Making an empty list.
Finding X item from a list, 0 k < N.
Inserting a new item after the k-th item of a list, 0 k < N.
Deleting an item from a list.
Finding next of the current item from a list.
Finding previous of the current item from a list.
4.1 The List ADT:
CHAPTER 4
Lists
Simple Array implementation of Lists
array[ i ] = itemi
MaxSize has to be estimated.
Address Content
array+i itemi
array+i+1 itemi+1
…… ……
…… ……
Sequential mapping
Finding takes O(n) time.
Insertion and Deletion not
only take O(N) time, but also involve a lot of data movements which takes time.
4.2 Singly Linked Lists• Linked list
– an ordered sequence of nodes with links represented as arrows
ptrbat cat sat vat null
– Delete mat from list :
– Insert mat after cat :ptr
bat cat sat vat null
mat
ptrbat cat sat vat nullmat
The capabilities to make linked representation:
• Define a node's structure ---- self-referential structures
• Create a new node ---- malloc function• Remove nodes ---- free function
〖 example 〗 list of words ending in atdefine a node typedef struct listNode *listPointer;structure typedef struct listNode {
char data [ 4 ]; listPointer link;
};create a new list listPointer ptr = NULL; ( #define IS_EMPTY(ptr) ( ! ( ptr )) )create new nodes ptr = (listPointer) malloc ( sizeof (listNode ));place a word into the list strcpy ( ptr ->data, "bat");
ptr -> link = null;Free point free(ptr);
〖 example 〗 list of words ending in atdefine a node typedef struct listNode *listPointer;structure typedef struct listNode {
char data [ 4 ]; listPointer link;
};create a new list listPointer ptr = NULL; ( #define IS_EMPTY(ptr) ( ! ( ptr )) )create new nodes ptr = (listPointer) malloc ( sizeof (listNode ));place a word into the list strcpy ( ptr ->data, "bat");
ptr -> link = null;Free point free(ptr);
address offirst node ptr->data ptr->link
ptr
b a t \0
address offirst node ptr->data ptr->link
ptr
b a t \0
〖 example 〗 List insertion
a1
first
NULLai ai+1 an... ...
b
temp
temp->link = x-> link
x-> link = temp
Question: What will happen if the order of the two steps is reversed?
Read Program 4.2 on p.153 and answer the question:Why is first passed as a pointer to listPointer?
x
〖 example 〗 List insertion#define IS_FULL (ptr ) ( ! (ptr ))void insert(listPointer *first, listPointer x){ /* insert a new node with data = 50 into the list ptr after node */
list_pointer temp;temp = (listPointer)malloc(sizeof(listNode));if ( IS_FULL(temp) ) {
fprintf(stderr, "The memory is full\n');exit(1);
}temp->data = 50;if ( *first) {
temp->link = x->link;x->link = temp;
}else {
temp->link = NULL;*first= temp;
}}
#define IS_FULL (ptr ) ( ! (ptr ))void insert(listPointer *first, listPointer x){ /* insert a new node with data = 50 into the list ptr after node */
list_pointer temp;temp = (listPointer)malloc(sizeof(listNode));if ( IS_FULL(temp) ) {
fprintf(stderr, "The memory is full\n');exit(1);
}temp->data = 50;if ( *first) {
temp->link = x->link;x->link = temp;
}else {
temp->link = NULL;*first= temp;
}}
ptr
10 20 null
50temp
node
ptr
10 20 null
50temp
node
〖 example 〗 list deletion
a1
first
NULLai ai+1 an... ...
b
trail
x
trail-> link = x-> link
free ( node )b
node
Question: How can wedelete the first node from a list?
Read Program 4.3 on p.155 and find the answer.
〖 example 〗 list deletion void delete(listPointer *first, listPointer trail, listPointer x){ /* delete node from the list, trail is the preceding node ptr is the head of the list */
if ( trail )trail->link = x->link;
else*first= (*first)->link;
free(x);}
ptr
10 20 null50
node
ptr
50 20 null
trail = NULL
before deletion after deletion
ptr
10 20 null50
node
ptr
50 20 null
trail = NULL
before deletion after deletion
List after the function call delete(&ptr, NULL, ptr)List after the function call delete(&ptr, NULL, ptr)
ptr
10 20 null50
trail
ptr
10 20 null
before deletion after deletion
nodeptr
10 20 null50
trail
ptr
10 20 null
before deletion after deletion
nodeList after the function call delete(&ptr, ptr, prt->link)List after the function call delete(&ptr, ptr, prt->link)
〖 example 〗 Printing out a list
void print_list(listPointer first){
printf("The list contains: ");for ( ; first; first= first->link )
printf("%4d”,first->data);printf("\n");
}
void print_list(listPointer first){
printf("The list contains: ");for ( ; first; first= first->link )
printf("%4d”,first->data);printf("\n");
}
4.3 Dynamically Linked Stacks and Queues• Linked Stacks top
null
element link
....
top
null
element link
....
STACK
NULLitem
item
item top
Push:
item top
temp
temp->link = top
top = temp
Rea
d P
rog
ram
4.5
an
d P
rog
ram
4.6
on
p.1
58ab
ou
t im
ple
men
tati
on
of
pu
sh a
nd
po
p
Pop: temp = top
top = top->link
top item = temp->item
free ( temp ) item
return item
Question: How to represent n stacks?
Answer:stackPointer top [ n ] ;
Program : Add to a linked stack
void push(int i, element item){
/* add an element to the top of the stack */stackPointer temp = (stackPointer)malloc(sizeof(stack));if ( IS_FULL(temp) ) {
fprintf( stderr, "The memory is full\n");exit(1);
}temp->item = item;temp->link = top[i];top[i] = temp;
}
void push(int i, element item){
/* add an element to the top of the stack */stackPointer temp = (stackPointer)malloc(sizeof(stack));if ( IS_FULL(temp) ) {
fprintf( stderr, "The memory is full\n");exit(1);
}temp->item = item;temp->link = top[i];top[i] = temp;
}
#define MAX_STACKS 10 /*maximum number od stacks */typedef struct { int key ; /* other fields */ } element;typedef struct stack *stackPointer;typedef struct stack { element item; stackPointer link; };stackPointer top [ MAX_STACKS ];
#define MAX_STACKS 10 /*maximum number od stacks */typedef struct { int key ; /* other fields */ } element;typedef struct stack *stackPointer;typedef struct stack { element item; stackPointer link; };stackPointer top [ MAX_STACKS ];
Program : Delete from a linked stackelement pop(int i) {
/* delete an element from the stack */stackPointer temp = top[i];element item;if ( IS_EMPTY(temp) ) {
fprintf(stderr, "The stack is empty\n");exit(1);
}item = temp->item;top[i] = temp->link;free(temp);return item;
}
element pop(int i) {
/* delete an element from the stack */stackPointer temp = top[i];element item;if ( IS_EMPTY(temp) ) {
fprintf(stderr, "The stack is empty\n");exit(1);
}item = temp->item;top[i] = temp->link;free(temp);return item;
}
the boudary condition for the stacks:top [ i ] = NULL, iff the i th stack is empty 0 <= i < MAX_STACKSIS_FULL ( temp) iff the memory is full
the boudary condition for the stacks:top [ i ] = NULL, iff the i th stack is empty 0 <= i < MAX_STACKSIS_FULL ( temp) iff the memory is full
Linked QueuesQUEUE
NULLitem
item
item front
rear
addq:
itemtemp rear->link= temp
temp-> link = NULL
NULL
rear = temp
rear
deleteq: temp = front
temp
front = temp-> link
front item = temp->item
item
free ( temp )
return item
Rea
d P
rog
ram
4.7
an
d P
rog
ram
4.8
on
p.1
59-1
60ab
ou
t im
ple
men
tati
on
of
add
q a
nd
del
eteq
Question: How to represent n queues?Answer:queuePointer front[n], rear[n];
front
null
element link
....
rearfront
null
element link
....
rear
Program: Add to the rear of a linked queue
void addq(int i, element item){ /* add an element to the rear of the queue */
queuePointer temp = (queuePointer)malloc(sizeof(queue));if ( IS_FULL(temp) ) {
fprintf(stderr, "The memory is full\n");exit(1);
}temp->item = item;temp->link = NULL;if ( front[i] ) rear[i]->link = temp;else front[i] = temp;rear[i] = temp;
}
void addq(int i, element item){ /* add an element to the rear of the queue */
queuePointer temp = (queuePointer)malloc(sizeof(queue));if ( IS_FULL(temp) ) {
fprintf(stderr, "The memory is full\n");exit(1);
}temp->item = item;temp->link = NULL;if ( front[i] ) rear[i]->link = temp;else front[i] = temp;rear[i] = temp;
}
#define MAX_QUEUES 10 /*maximum number of queues */typedef struct queue *queuePointer;typedef struct queue { element item; queuePointer link: };queuePointer front [MAX_QUEUES], rear [MAX_QUEUES ];
#define MAX_QUEUES 10 /*maximum number of queues */typedef struct queue *queuePointer;typedef struct queue { element item; queuePointer link: };queuePointer front [MAX_QUEUES], rear [MAX_QUEUES ];
Program: Delete from the front of a linked queue
element deleteq(int i){/* delete an element from the queue */
queuePointer temp = front[i];element item;if ( IS_EMPTY(front[i]) ) {
fprintf(stderr, "The queue is empty\n");exit(1);
}item = temp->item;front[i] = temp->link;free(temp);return item;
}
element deleteq(int i){/* delete an element from the queue */
queuePointer temp = front[i];element item;if ( IS_EMPTY(front[i]) ) {
fprintf(stderr, "The queue is empty\n");exit(1);
}item = temp->item;front[i] = temp->link;free(temp);return item;
}
the boudary condition for the queues:front [ i ] = NULL, iff the i th queue is empty 0 <= i < MAX_QUEUESIS_FULL ( temp) iff the memory is full
the boudary condition for the queues:front [ i ] = NULL, iff the i th queue is empty 0 <= i < MAX_QUEUESIS_FULL ( temp) iff the memory is full
4.5 Additional List Operations
1. operations for chains– a) Inverting a singly linked list– b) Concatenating singly linked lists
2. operations for circularly linked lists– a) Inserting at the front of a list– b) Finding the length of a circular list
a) Inverting a singly linked list
listPointer invert (listPointer lead ){ /* invert the list pointed to by lead */ listPointer middle, trail ; middle = NULL ; trail=NULL; /* middle is head of the inverted chain */ while ( lead ) { middle = lead ; lead = lead->link; middle->link= trail ; trail = middle ; } /* end while-loop */ return middle ;}
1
2
3
lead
NULL
middle
NULLtrail2
3
lead
NULL
1
middle
NULLtrail
2
3
lead
NULL1
middle
NULLtrail
Tinvert = O( length of lead )
b) Concatenating singly linked lists
listPointer concatenate listPointer ptr1, listPointer ptr2){/* produce a new list hat contains the list ptr1 followed by the list ptr2. The list pointed to by ptr1 is changed permanently */
listPointer temp;if ( IS_EMPTY(ptr1) ) return ptr2;else {
if ( !IS_EMPTY(ptr2) ) {for ( temp = ptr1; temp->link; temp = temp->link )
;temp->link = ptr2;
}return ptr1;
}}
listPointer concatenate listPointer ptr1, listPointer ptr2){/* produce a new list hat contains the list ptr1 followed by the list ptr2. The list pointed to by ptr1 is changed permanently */
listPointer temp;if ( IS_EMPTY(ptr1) ) return ptr2;else {
if ( !IS_EMPTY(ptr2) ) {for ( temp = ptr1; temp->link; temp = temp->link )
;temp->link = ptr2;
}return ptr1;
}} Tconcatenate = O( length of ptr1 )
a) Inserting at the front of a circularly linked list
void insertFront listPointer *last, listPointer node)/* insert node at the front of the circular list last, where last is the last node in the list */{ if ( IS_EMPTY(*last) ) {
/* list is empty, change ptr to point to new entry */*last= node;node->link = node;
}else { /* list is not empty, add new entry at front */
node->link = (*last)->link;(*last)->link = node;
}}
void insertFront listPointer *last, listPointer node)/* insert node at the front of the circular list last, where last is the last node in the list */{ if ( IS_EMPTY(*last) ) {
/* list is empty, change ptr to point to new entry */*last= node;node->link = node;
}else { /* list is not empty, add new entry at front */
node->link = (*last)->link;(*last)->link = node;
}}
x1 x3x2 a x1 x3x2 a
x1 x3x2 a
x1 x3x2 a
b) Finding the length of a circular list
int length(listPointer last){ /* find the length of the circular list last */
list_pointer temp;int count = 0;if (last) {
temp = last;do {
count ++;temp = temp->link;
} while ( temp != last);}return count;
}
int length(listPointer last){ /* find the length of the circular list last */
list_pointer temp;int count = 0;if (last) {
temp = last;do {
count ++;temp = temp->link;
} while ( temp != last);}return count;
}
Don’t we have enough headache already?
Why do we need the doubly linked lists?
Suppose you have a list 1->2->3->…->m.Now how would youget the m-th node?
I’ll go from the 1st nodeto the m-th node.
Then you are asked to find its previous node m 1?
Uhhh ... Then I’ll have to go from the 1st node again.
But hey, why do I wantta find the previous node?
Why do you ask me? :-)Maybe you wantta delete
the m-th node?
typedef struct node *nodePointer;typedef struct node {
nodePointer llink;element item; nodePointer rlink;
};
item llink rlink
ptr = ptr->llink->rlink
= ptr->rlink->llink
A doubly linked circular list with head node:
item1 item2 item3 H
An empty list : H
4.8 Doubly Linked lists
Program : Insertion into a doubly linked circular list
void dinsert(nodePointer node, nodePointer newnode) { /* insert newnode to the right of node */
newnode->llink = node;newnode->rlink = node->rlink;node->rlink->llink = newnode;node->rlink = newnode;
}
void dinsert(nodePointer node, nodePointer newnode) { /* insert newnode to the right of node */
newnode->llink = node;newnode->rlink = node->rlink;node->rlink->llink = newnode;node->rlink = newnode;
}
new node
node node
Program: Deletion from a doubly linked circular list
void ddelete(nodePointer node, nodePointer deleted){ /* delete from the doubly linked list */
if ( node == deleted )printf("Deletion of head node not permitted.\n");
else { deleted->llink->rlink = deleted->rlink;
deleted->rlink->llink = deleted->llink; free(deleted);
}}
void ddelete(nodePointer node, nodePointer deleted){ /* delete from the doubly linked list */
if ( node == deleted )printf("Deletion of head node not permitted.\n");
else { deleted->llink->rlink = deleted->rlink;
deleted->rlink->llink = deleted->llink; free(deleted);
}}
nodenode
deleted
Homework-21. P112, #42. P142, #13. P154, #24. P154, #65. P172, #1补充:6. 如果单链表带头结点,请完成 CreateList, Insert, Delete函数操作 , 可修改 Program4.2 和 Program4.3完成。并请给出相关的数据结构定义。
CreateList:创建带一个头结点的单链表 ;Insert:在单链表 first 的 X结点后插入元素 Item;Delete:删除单链表 First 中 Tail结点后的 X结点,并返回其值。