Chap 3
Chap 3
5 6
1. Array 1. Array
• Access elements via indices • Access elements via indices
• Elements are allocated continuously in memory • Elements are allocated continuously in memory
• Insertions and removals need to consolidate elements • Insertions and removals need to consolidate elements
1 5 2 6 3 7 4 8 Column-major
NGUYỄN KHÁNH PHƯƠNG Column 0 Column 1 Column 2 Column 3 storage
CS - SOICT-HUST
Row-Major Order (e.g. C/C++, Python by default, Pascal) Column-Major Order (e.g. Matlab, Fortran)
Row- major order is a method of representing multi-dimensional array in sequential memory. In In this method, elements of an array are arranged sequentially column by
this method, elements of an array are arranged sequentially row by row. Thus, elements of the first
row occupies the first set of memory locations reserved for the array, elements of the second row
column. Thus, elements of the first column occupies the first set of memory
occupies the next set of memory and so on. locations reserved for the array, elements of the second column occupies the
Elements of Elements of Elements of
….
Elements of
……..
next set of memory and so on.
Row 0 Row 1 Row 2 Row i
Where
• start_address: the address of the first element (x[0][0]) in the array Memory Location(a[i][j]) = start_address + W*[(i*cols) + j]
• W: is the size of each element 1 2 3 4 5 6 7 8 9 10 11 12
• c: number of columns in the array
• r: number of rows in the array NGUYỄN KHÁNH PHƯƠNG Location(a[1][2]) = ?
CS - SOICT-HUST start_address=6487488
Locating Element x[i][j]: column-major order Example 1: Row- and Column-Major Orders
Assume x: …..
r Elements r Elements r Elements
…. …….
r Elements 2D array: a[0][0] = 1 a[0][1]=2 a[0][2]=3 a[0][3]=4
of column 0 of column 1 of column 2 of columns i
has r rows and c columns (thus, each column has r elements) int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; a[1][0] = 5 a[1][1]=6 a[1][2]=7 a[1][3]=8
Where
start_address=6487488 Location(a[1][2]) = ?
• start_address: the address of the first element in the array
• W: is the size of each element Memory: column-major order
• c: number of columns in the array Location(a[i][j]) = start_address + W*[(j*rows) + i]
• r: number of rows in the array
1 5 9 2 6 10 3 7 11 4 8 12
Example: array : int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
Location(a[1][2]) = ?
Determine the address of the element a[1][2] if start_address = 6487488 start_address=6487488
Example 2: Row- and Column-Major Orders Example
2D array: r rows, c columns We have stored the two-dimensional array students in memory. The array
Example: int a[3][6]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};
is 100 × 4 (100 rows and 4 columns). Show the address of the element
a[0][0]=0 a[0][1]=1 a[0][2]=2 a[0][3]=3 a[0][4]=4 a[0][5]=5
a[1][0]=6 a[1][1]=7 a[1][2]=8 a[1][3]=9 a[1][4]=10 a[1][5]=11
students[5][3] assuming that the element student[0][0] is stored in the
a[2][0]=12 a[2][1]=13 a[2][2]=14 a[2][3]=15 a[2][4]=16 a[2][5]=17 memory location with address 1000 and each element occupies only two
bytes memory location. The computer uses row-major storage.
Memory: row-major order start_address = 1000 Location(a[1][4]) = ? Solution:
c elements of c elements of c elements of c Elements of
…. ……..
Row 0 Row 1 Row 2 Row r
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
0 6 2 1 7 13 2 8 14 3 9 15 4 10 16 5 11 17
1 3 3 7 8 12 14 17 19 22
1 3 3 7 12 14 17 19 22 30
1 3 3 7 12 14 17 19 22 ?
• We can do it by shifting to the right one cell for all the elements after the mark
– It thus need to remove 30 from the array • Delete operation is a slow operation.
• Regular implementation of this operation is undesirable.
• Delete operation makes the last element free
1 3 3 7 8 12 14 17 19 22
– How we could mark the last element of the array being free?
• Moving all elements of the array is a slow operation (requires linear time O(n) • We need variable to store the size of the array
where n is the size of array) Example: variable size is used to store the size of the array. Before
deletion, size = 10. After deletion, we need to update the value of size:
size = 10 – 1 = 9
NGUYỄN KHÁNH PHƯƠNG NGUYỄN KHÁNH PHƯƠNG
CS - SOICT-HUST CS - SOICT-HUST
head
10 8 20
head
• Keeping track of a singly linked list:
• Circular linked list – Must know the pointer to the first element of the list (called start, head, etc.)
– If head is NULL, the singly linked list is empty
head
10 8 20 10 8 20
head
NGUYỄN KHÁNH PHƯƠNG
CS - SOICT-HUST
..
• Before further discussion of singly linked lists, we need to explain the notation we • List of integer numbers:
use in the figures. We show the connection between two nodes using a line. One end
of the line has an arrowhead, the other end has a solid circle. 7 17 4 24
• List of students with data: student’s ID, grade of math and physics
head
5 9 3 ... 6 4
39
NGUYỄN KHÁNH PHƯƠNG NGUYỄN KHÁNH PHƯƠNG
CS - SOICT-HUST CS - SOICT-HUST
Traversing a singly linked list: 2nd way Exercise 1
void printList(Node* head) • A sequence of integers is stored by a singly linked list.
{
typedef struct Node{
Node* cur = head;
int data;
for (cur = head; cur != NULL; cur = cur->next) printf(“%d “,cur->data);
struct Node *next;
}
}Node;
Node *head;
1 2 3
NULL
NGUYỄN KHÁNH PHƯƠNG 41 NGUYỄN KHÁNH PHƯƠNG 42
CS - SOICT-HUST CS - SOICT-HUST
1 2 3
NULL
cur
Data = 1
Data = 2
Data = 3
…
cur
//return the pointer pointed to the first node in the list:
head Node *Insert_ToHead(Node *head, int X)
{
… Node *new_node = makenode(X);
new_node new_node->next = head;
head = new_node;
return head;
}
NGUYỄN KHÁNH PHƯƠNG NGUYỄN KHÁNH PHƯƠNG 46
CS - SOICT-HUST CS - SOICT-HUST
cur
head
cur
head …
…
Operations on singly linked list: Insertion Operations on singly linked list: Insertion
• Insert a new node after the node pointed by the pointer cur: • Insert a new node after the node pointed by the pointer cur:
<create a new node new_node>; <create a new node new_node>; ?? Empty list
new_node ->next = cur->next; new_node ->next = cur->next;
cur->next = new_node; cur->next = new_node;
// wrong implementation:
Write a function to insert a node with data = X (having the type int after the cur->next = new_node;
node pointed by the pointer cur. The function returns the address of the new node: new_node ->next = cur->next;
cur
Node *Insert_After(Node *cur, int X) head
{
Node *new_node = makenode(X); //(1) …
new_node->next = cur->next; //(2)
cur->next = new_node; //(3)
return new_node;
}
Operations on singly linked list: Insertion Operations on singly linked list: Insertion
Insert a new node before the node pointed by the pointer cur Insert a new node before the node pointed by the pointer cur
<create a new node new_node>; ?? List does not have any node yet <create a new node new_node>; ?? List does not have any node yet
<Determine pointer prev pointed <Determine pointer prev pointed
to the predecessor of cur>; to the predecessor of cur>;
prev->next = new_node; ?? cur is the first node in the list prev->next = new_node; ?? cur is the first node in the list
new_node->next = cur; new_node->next = cur;
Insert a new node: NGUYỄN KHÁNH PHƯƠNG 55 Node *Insert_Before(Node *head, Node *cur, int X) 56
CS - SOICT-HUST
Operations on singly linked list: Insertion Operations on singly linked list: Insertion
Insert a new node before the node pointed by the pointer cur Insert a new node before the node pointed by the pointer cur
<create a new node new_node>; Node *Insert_Before(Node *head, Node *cur, int X)
<Determine pointer prev pointed to the predecessor of cur>;
prev->next = new_node; {
new_node->next = cur; Node *new_node = makenode(X);
if (head == NULL) /* list does not have any node yet */
head = new_node;
node *prev = head; else if (cur == head) { //cur is the first node in the list
while (prev->next != cur) prev = prev->next; head = new_node;
new_node->next = cur;
prev cur }
head else {
Node *prev = head;
… while (prev->next != cur) prev = prev->next;
prev->next = new_node;
new_node->next = cur;
}
return new_node;
Node *Insert_Before(Node *head, Node *cur, int X)
} NGUYỄN KHÁNH PHƯƠNG
57 KHMT – SOICT - ĐHBK HN
Operations on singly linked list: Insertion Operations on singly linked list: Insertion
Insert a new node: head Node *Insert_ToLast(Node *head, int X)
• At the beginning {
else {
• At the end of the list
<create a new node new_node>; Node *last = head;
if (head == NULL) { /* list does not have any node yet*/ while (last->next != NULL) last = last->next; //move to the last node
head = new_node;
} last->next = new_node;
else {
//move the pointer to the end of the list: }
node *last =head; return head;
while (last->next != NULL) last = last->next;
//Change the pointer next of the last node: }
last->next = new_node;
} Node *Insert_ToLast(Node *head, int X) void Insert_ToLast(Node **head_ref, int X)
{ {
else { else {
} }
return head; }
59 NGUYỄN KHÁNH PHƯƠNG
} KHMT – SOICT - ĐHBK HN
Operations on singly linked Lists Operations on singly linked lists: Deletion
• Traverse the singly linked list • Delete a node
• Insert a node into the singly linked list • Delete all nodes of the list
• Delete a node from the singly linked list
• Search data in the singly linked list
Operations on singly linked lists: Deletion Delete the first node of the list
Delete a node: • Delete the node del that is currently the first node of the list:
• The first node of the list head = del->next;
free(del);
head
≡del
del
Delete a node pointed by the pointer del Operations on singly linked lists: Deletion
Write the function node *Delete_Node(node *head, node *del)
• Delete a node
to delete a node pointed by the pointer “del” of the list with the first node pointed by the pointer “head”.
The function returns the address of the first node in the list after deletion:
• Delete all nodes of the list
Traverse elements one by one from the head till the end
head head
1 2 3 2 3
del del
NGUYỄN KHÁNH PHƯƠNG 69 NGUYỄN KHÁNH PHƯƠNG 70
CS - SOICT-HUST CS - SOICT-HUST
head head
2 3 3 NULL
del del
NGUYỄN KHÁNH PHƯƠNG 71 NGUYỄN KHÁNH PHƯƠNG 72
CS - SOICT-HUST CS - SOICT-HUST
Freeing all nodes of a list Check whether the singly linked list is empty or not
Write the function Node* deleteList(Node* head) Write the function int IsEmpty(Node *head)
to delete all the node in the list having the first node pointed by the pointer head to check whether the singly linked list is empty or not (the pointer head pointed to the
The function returns the pointer head after deletion first node of the list).
Node* deleteList(Node* head) The function returns 1 if the list is empty; 0 otherwise
{
Node *del = head ; int IsEmpty(Node *head) {
if (head == NULL)
while (del != NULL) return 1;
{ else return 0;
head = head->next; }
free(del);
del = head;
}
return head;
}
10 8 20 tail
head
typedef struct{
typdedef struct dllist { char id[15];
int number; float math, physics;
}student;
struct dllist *next;
typedef struct dllist{
struct dllist *prev; student data;
} dllist; struct ddlist* next;
struct ddlist* prev;
dllist *head, *tail; }dllist;
dllist *head, *tail;
NGUYỄN KHÁNH PHƯƠNG NGUYỄN KHÁNH PHƯƠNG
CS - SOICT-HUST CS - SOICT-HUST
Doubly linked list – Example (C proramming) Doubly linked list – Example (C proramming)
typedef struct dllist { typedef struct dllist {
char data; char data;
struct dllist *prev; struct dllist *prev;
struct dllist *next; struct dllist *next;
}dllist; }dllist;
dllist *node1, *node2, *node3; dllist *node1, *node2, *node3;
node1 = (dllist*)malloc(sizeof(dllist)); node1 = (dllist*)malloc(sizeof(dllist));
node2 = (dllist*)malloc(sizeof(dllist)); node2 = (dllist*)malloc(sizeof(dllist));
node3 = (dllist*)malloc(sizeof(dllist)); node3 = (dllist*)malloc(sizeof(dllist));
node1->data='a'; node1->data='a';
node2->data='b'; node2->data='b';
node3->data='c’; node3->data='c’;
node1->prev=NULL; node1->prev=NULL; a b c
node1->next=node2; node1->next=node2;
node2->prev=node1; node1 node2
node2->prev=node1; node1 node2
node3 node3
node2->next=node3; node2->next=node3;
node3->prev=node2; node3->prev=node2;
node3->next=NULL; node3->next=NULL;
dllist *temp; dllist *temp;
for (temp = node1; temp != NULL; temp = temp->next) for (temp = node1; temp != NULL; temp = temp->next)
printf(“%d ”,temp->data); printf(“%d ”,temp->data);
83 84
Doubly linked list – Example (C proramming) Doubly linked list – Example (C proramming)
typedef struct dllist { typedef struct dllist {
char data; char data;
struct dllist *prev; struct dllist *prev;
struct dllist *next; struct dllist *next;
}dllist; }dllist;
dllist *node1, *node2, *node3; dllist *node1, *node2, *node3;
node1 = (dllist*)malloc(sizeof(dllist)); node1 = (dllist*)malloc(sizeof(dllist));
node2 = (dllist*)malloc(sizeof(dllist)); node2 = (dllist*)malloc(sizeof(dllist));
node3 = (dllist*)malloc(sizeof(dllist)); node3 = (dllist*)malloc(sizeof(dllist));
node1->data='a'; node1->data='a';
node2->data='b'; node2->data='b';
node3->data='c’; node3->data='c’;
node1->prev=NULL; NULL a b c node1->prev=NULL; NULL a b c
node1->next=node2; node1->next=node2;
node2->prev=node1; node1 node2
node2->prev=node1; node1 node2
node3 node3
node2->next=node3; node2->next=node3;
node3->prev=node2; node3->prev=node2;
node3->next=NULL; node3->next=NULL;
dllist *temp; dllist *temp;
for (temp = node1; temp != NULL; temp = temp->next) for (temp = node1; temp != NULL; temp = temp->next)
printf(“%d ”,temp->data); printf(“%d ”,temp->data);
85 86
Doubly linked list – Example (C proramming) Doubly linked list – Example (C++)
typedef struct dllist {
char data;
typedef struct dllist {
struct dllist *prev;
struct dllist *next;
char data;
}dllist; struct dllist *prev;
dllist *node1, *node2, *node3; struct dllist *next;
node1 = (dllist*)malloc(sizeof(dllist)); }dllist;
node2 = (dllist*)malloc(sizeof(dllist)); dllist node1, node2, node3;
node3 = (dllist*)malloc(sizeof(dllist));
node1.data=‘a’;
node1->data='a';
node2.data=‘b’;
node2->data='b';
node3->data='c’;
node3.data=‘c’; NULL a b c NULL
a c node1.prev=NULL;
node1->prev=NULL; NULL b NULL
node1->next=node2; node1.next=node2;
node2->prev=node1; node1 node2
node2.prev=node1;
node3
node2->next=node3; node2.next=node3;
node3->prev=node2; node3.prev=node2;
node3->next=NULL; node3.next=NULL;
dllist *temp;
dblist *temp;
for (temp = node1; temp != NULL; temp = temp->next)
printf(“%d ”,temp->data);
for (temp = node1; temp != NULL; temp = temp->next)
cout<<temp->data<<endl;
87 88
Delete a node pointed by the pointer p Delete a node pointed by the pointer p
void Delete_Node (dllist *p){ void Delete_Node (dllist *p){
if (head == NULL) printf(”Empty list”); if (head == NULL) printf(”Empty list”);
else { else {
if (p==head) head = head->next; //Delete first element if (p==head) head = head->next; //Delete first element
else p->prev->next = p->next; else p->prev->next = p->next;
if (p->next!=NULL) p->next->prev = p->prev; if (p->next!=NULL) p->next->prev = p->prev;
else tail = p->prev; else tail = p->prev;
free(p); free(p);
} }
} }
8 5 12 5 8 5 12 5
p p
head tail head tail
89 90
Delete a node pointed by the pointer p Insert a node after the node pointed by pointer p
void Delete_Node (dllist *p){ void Insert_Node (int X, dllist *p){
if (head == NULL){ // List is empty
if (head == NULL) printf(”Empty list”); head =(ddlist*)malloc(sizeof(ddlist));
else { head->data = X;
head->prev =NULL;
if (p==head) head = head->next; //Delete first element head->next =NULL;
else p->prev->next = p->next; }
else{
if (p->next!=NULL) p->next->prev = p->prev; dllist *newNode;
else tail = p->prev; newNode=(dllist*)malloc(sizeof(dllist));
newNode->data = X;
free(p); newNode->next = NULL;
}
newNode->next = p->next;
} newNode->prev=p;
if (p->next!=NULL) 12
8 5 12 5 p->next->prev=newNode;
p->next = newNode;
}
}
p 8 5 5
head tail 92
91
p
Exercise 2: Create a double linked list store integer numbers
#include <stdio.h> /* Insert a new node p at the end of the list */
#include <stdlib.h> void append_node(dllist *p) {
#include <conio.h> if(head == NULL)
{
typedef struct dllist{ head = p;
int number; p->prev = NULL;
struct dllist *next; }
struct dllist *prev; else {
} dllist; tail->next = p;
dllist *head, *tail; p->prev = tail;
}
/* Insert a new node p at the end of the list */ tail = p;
void append_node(dllist *p); p->next = NULL;
/* Insert a new node p after a node pointed by the pointer after */ }
void insert_node(dllist *p, dllist *after);
/* Delete a node pointed by the pointer p */
void delete_node(dllist *p);
93
/* Insert a new node p after a node pointed by the pointer after */ int main( ) {
void insert_node(dllist *p, dllist *after) { dllist *tempnode; int i;
p->next = after->next; /* add some numbers to the double linked list */
p->prev = after; for(i = 1; i <= 5; i++) {
if(after->next != NULL) tempnode = (dllist *)malloc(sizeof(dllist));
tempnode->number = i;
after->next->prev = p;
append_node(tempnode);
else
}
tail = p;
/* print the dll list forward */
after->next = p;
printf(" Traverse the dll list forward \n");
} for(tempnode = head; tempnode != NULL; tempnode = tempnode->next)
/* Delete a node pointed by the pointer p */ printf("%d\n", tempnode->number);
void delete_node(dllist *p) {
if(p->prev == NULL) /* print the dll list backward */
head = p->next; printf(" Traverse the dll list backward \n");
else p->prev->next = p->next; for(tempnode = tail; tempnode != NULL; tempnode = tempnode->prev)
if(p->next == NULL) printf("%d\n", tempnode->number);
tail = p->prev; /* destroy the dll list */
else p->next->prev = p->prev; while(head != NULL) delete_node(head);
} return 0;
}
Several variants of linked lists Circular linked list
• Some common variants of linked list: head
– Circular Linked Lists
– Circular Doubly Linked Lists
– Linked Lists of Lists 8 5 12 5
• Basic operations on these variants are built similarly to the singly linked list
and the doubly linked list that we consider above.
8 5 12 5
Data1 Data2 Data3
Poly1
… 2 … 0 1 0 0 0 A
… 0 … 1 10 3 0 1 B
2 1000 1 3 NULL
1000 … 4 3 2 1 0
1 4 10 3 3 2 4 0 NULL
}
ptr2 = ptr2->next; //update ptr list 2
illustration }
ptr2 = ptr2->next; //update ptr list 2
illustration
node = (Polynom *) malloc (sizeof(Polynom)); node = (Polynom *) malloc (sizeof(Polynom));
ptr->next = node; //update ptr listResult ptr->next = node; //update ptr listResult
} //end of while } //end of while
Polynom *PolySum, *node,*ptr,*ptr1,*ptr2; Polynom *PolySum, *node,*ptr,*ptr1,*ptr2;
node = (Polynom *) malloc (sizeof(Polynom)); node = (Polynom *) malloc (sizeof(Polynom));
PolySum = node; PolySum = node;
ptr1 = Poly1; ptr2 = Poly2; Ptr1 ptr1 = Poly1; ptr2 = Poly2; Ptr1
while (ptr1!=NULL && ptr2!=NULL){ while (ptr1!=NULL && ptr2!=NULL){
ptr = node; ptr = node;
if (ptr1->exp < ptr2->exp ) { if (ptr1->exp < ptr2->exp ) {
node->coef = ptr2->coef; node->coef = ptr2->coef;
node->exp = ptr2->exp; Ptr2 node->exp = ptr2->exp; Ptr2
ptr2 = ptr2->next; //update ptr list 2 ptr2 = ptr2->next; //update ptr list 2
} }
else if ( ptr1->exp > ptr2->exp ) 2 1000 else if ( ptr1->exp > ptr2->exp ) 2 1000
{ node->coef = ptr1->coef; { node->coef = ptr1->coef;
node->exp = ptr1->exp; ptr node->exp = ptr1->exp; ptr
ptr1 = ptr1->next; //update ptr list 1 ptr1 = ptr1->next; //update ptr list 1
} }
else else
{ node->coef = ptr2->coef + ptr1->coef; { node->coef = ptr2->coef + ptr1->coef;
node->exp = ptr2->exp; node->exp = ptr2->exp;
ptr1 = ptr1->next; //update ptr list 1 ptr1 = ptr1->next; //update ptr list 1
}
ptr2 = ptr2->next; //update ptr list 2
illustration }
ptr2 = ptr2->next; //update ptr list 2
illustration
node = (Polynom *) malloc (sizeof(Polynom)); node = (Polynom *) malloc (sizeof(Polynom));
ptr->next = node; //update ptr listResult ptr->next = node; //update ptr listResult
} //end of while } //end of while
}
ptr2 = ptr2->next; //update ptr list 2
illustration }
ptr2 = ptr2->next; //update ptr list 2
illustration
node = (Polynom *) malloc (sizeof(Polynom)); node = (Polynom *) malloc (sizeof(Polynom));
ptr->next = node; //update ptr listResult ptr->next = node; //update ptr listResult
} //end of while } //end of while
Polynom *PolySum, *node,*ptr,*ptr1,*ptr2; Polynom *PolySum, *node,*ptr,*ptr1,*ptr2;
node = (Polynom *) malloc (sizeof(Polynom)); node = (Polynom *) malloc (sizeof(Polynom));
PolySum = node; PolySum = node;
ptr1 = Poly1; ptr2 = Poly2; Ptr1 ptr1 = Poly1; ptr2 = Poly2; Ptr1
while (ptr1!=NULL && ptr2!=NULL){ while (ptr1!=NULL && ptr2!=NULL){
ptr = node; ptr = node;
if (ptr1->exp < ptr2->exp ) { if (ptr1->exp < ptr2->exp ) {
node->coef = ptr2->coef; node->coef = ptr2->coef;
node->exp = ptr2->exp; Ptr2 node->exp = ptr2->exp; Ptr2
ptr2 = ptr2->next; //update ptr list 2 ptr2 = ptr2->next; //update ptr list 2
} }
else if ( ptr1->exp > ptr2->exp ) 2 1000 1 4 else if ( ptr1->exp > ptr2->exp ) 2 1000 1 4 11 3
{ node->coef = ptr1->coef; { node->coef = ptr1->coef;
node->exp = ptr1->exp; ptr node->exp = ptr1->exp; ptr
ptr1 = ptr1->next; //update ptr list 1 ptr1 = ptr1->next; //update ptr list 1
} }
else else
{ node->coef = ptr2->coef + ptr1->coef; { node->coef = ptr2->coef + ptr1->coef;
node->exp = ptr2->exp; node->exp = ptr2->exp;
ptr1 = ptr1->next; //update ptr list 1 ptr1 = ptr1->next; //update ptr list 1
}
ptr2 = ptr2->next; //update ptr list 2
illustration }
ptr2 = ptr2->next; //update ptr list 2
illustration
node = (Polynom *) malloc (sizeof(Polynom)); node = (Polynom *) malloc (sizeof(Polynom));
ptr->next = node; //update ptr listResult ptr->next = node; //update ptr listResult
} //end of while } //end of while
}
ptr2 = ptr2->next; //update ptr list 2
illustration }
ptr2 = ptr2->next; //update ptr list 2
illustration
node = (Polynom *) malloc (sizeof(Polynom)); node = (Polynom *) malloc (sizeof(Polynom));
ptr->next = node; //update ptr listResult ptr->next = node; //update ptr listResult
} //end of while } //end of while
if (ptr1 == NULL) //end of list 1 if (ptr1 == NULL) //end of list 1
{ while(ptr2!= NULL) //copy the remaining of list2 to listResult { while(ptr2!= NULL) //copy the remaining of list2 to listResult
Ptr1 Ptr1
{ node->coef = ptr2->coef; { node->coef = ptr2->coef;
node->exp = ptr2->exp; node->exp = ptr2->exp;
ptr2 = ptr2->next; //update ptr list 2 ptr2 = ptr2->next; //update ptr list 2
ptr = node; ptr = node;
node = (Polynom *) malloc (sizeof(Polynom)); node = (Polynom *) malloc (sizeof(Polynom));
Ptr2 Ptr2
ptr->next = node; //update ptr listResult ptr->next = node; //update ptr listResult
} }
} 2 1000 1 4 11 3 } 2 1000 1 4 11 3
else if (ptr2==NULL) //end of list 2 else if (ptr2==NULL) //end of list 2
{ ptr { ptr
while(ptr1 != NULL) //copy the remaining of list1 to the listResult while(ptr1 != NULL) //copy the remaining of list1 to the listResult
{ node->coef = ptr1->coef; 3 2 { node->coef = ptr1->coef; 3 2
node->exp = ptr1->exp; node->exp = ptr1->exp;
ptr1 = ptr1->next; //update ptr list 2 ptr1 = ptr1->next; //update ptr list 2
ptr = node; ptr = node;
node = (Polynom *)malloc (sizeof(Polynom)); node = (Polynom *)malloc (sizeof(Polynom));
ptr->next = node; //update ptr listResult ptr->next = node; //update ptr listResult
}
}
illustration }
}
illustration
ptr->next = NULL; ptr->next = NULL;
} }
}
}
illustration }
}
}
ptr->next = node; //update ptr listResult
Ptr2
2. Linked List
} 2 1000 1 4 11 3
else if (ptr2==NULL)
{
//end of list 2
3. Stack
while(ptr1 != NULL) //copy the remaining of list1 to the listResult
{ node->coef = ptr1->coef;
node->exp = ptr1->exp;
3 2
4. Queue
ptr1 = ptr1->next; //update ptr list 2
ptr = node;
4 0
node = (Polynom *)malloc (sizeof(Polynom));
ptr->next = node; //update ptr listResult
ptr
}
}
NULL
ptr->next = NULL; 1000 3
}
A(x) = 2x + x
B(x) = x4 + 10x3 + 3x2 + 4
Result(x) = 2x1000 + x4 + 11x3 + 3x2 + 4 122
M
C C C
R push(M) R item = pop() R
item = M
X X X
A A A
What Are Stacks Used For? What Are Stacks Used For?
• Real life (Pile of books, Plate trays, etc.) • More applications related to computer science
• More applications related to computer science – compilers
– Program execution stack: Most programming languages use a “call stack” to implement
function calling
• parsing data between delimiters (brackets)
• When a method is called, its line number and other useful information are pushed • Check: each “(”, “{”, or “[” has to pair with “)”, “}”, or “]”
(inserted) on the call stack Example:
• When a method ends, it is popped (removed) from the call stack and execution
restarts at the indicated line number in the method that is now at the top of the stack
– correct: ( )(( )){([( )])}
– correct: ((( )(( )){([( )])}
1. main pushed onto call stack, before invoking methodA
2. methodA pushed onto call stack, before invoking methodB
– incorrect: )(( )){([( )])}
3. methodB pushed onto call stack, before invoking methodC – incorrect: ({[ ])}
4. methodC pushed onto call stack, invoked then popped out from the
call stack when completes – incorrect: (
5. methodB popped out from call stack when completes.
6. methodA popped out from the call stack when completes. – virtual machines
7. main popped out from the call stack when completes. Program • manipulating numbers
exits.
– pop 2 numbers off stack, do work (such as add)
– Evaluating expressions (e.g. (4/(2-2+3))*(3-4)*2)
– push result back on stack and repeat
– artificial intelligence
• finding a path
Push(A)
Push(E)
Push(A)
Pop(A)
Pop(E)
DA E R
D Push(D) D Push(D) Pop(R)
A A
• Read each letter in the word and push it onto the stack • Read each letter in the word and push it onto the stack
E E
• When you reach the end of the word, pop the letters off
R R the stack and print them out
Implementing a Stack Stack: Array Implementation
• At least two different ways to implement a stack: • A stack consists of 4 elements: 3, 5, 7, 9.
– array • If an array is used to implement this stack, what is a good index for
– linked list the top item?
• Which method to use depends on the application – Is it position 0? S[0]=9 S[1]=7 S[2]=5 S[3]=3
– what advantages and disadvantages does each implementation have?
– Is it position 3? S[0]=3 S[1]=5 S[2]=7 S[3]=9
11 Top item
9
Let’s think when we need do operation:
7 - PUSH
- POP
5 The bottom of the stack is at S[0]
3 The top of the stack is at S[3]
Bottom item • pop off of the stack at S[3]
• push onto the stack at S[4]
…
S
0 1 2 numItems maxSize
maxSize: maximum number of elements in the array
Query
push(x) Insert an element with value x on the top of stack. Size
of stack will be increased by 1
pop() Remove the top element from stack
Example about declaration:
swap(stack s1, stack s2) Swap elements of stack s1 and s2
stack <int> s1; //declare variable stack s1 in which type of each element in s1 is int
• We can not declare stack<int> myStack (5) to initialize a stack with 5
empty elements as in array.
• Similarly, we can not declare stack<int> myStack (5,100) to initialize a
stack consisting of 5 elements with values 100.
NGUYỄN KHÁNH PHƯƠNG 145 NGUYỄN KHÁNH PHƯƠNG 146
CS - SOICT-HUST CS - SOICT-HUST
1
2 9 4
3 2 3
+ =
7 6 6
8 5 1
8732 + 5629 = 14361
The value of expression = 4
Application 3: Adding two large numbers Contents
• Read the numerals of the first number and store the numbers
Adding very
corresponding large
to them numbers:
on one stack; detail algorithm 1. Array
• Read the numerals of the second number and store the numbers
corresponding to them on another stack;
• carry=0; 2. Linked List
• while at least one stack is not empty
pop a number from each non-empty stack, add them and carry; 3. Stack
push the sum (minus 10 if necessary) on the result stack;
store carry in carry variable;
• push carry on the result stack if it is not zero; 4. Queue
• pop numbers from the result stack and display them
157 158
no changes of order
C rear E rear
B rear B C rear C
rear front B
A A A front B front front
front
enqueue(Q, A) enqueue(Q, B) enqueue(Q, C) dequeue(Q, A) enqueue(Q, E)
Stack Queue
Data structure with Last-In First-Out (LIFO) behavior Data structure with First-In First-Out (FIFO) behavior
In Out
C B A B C In Out
C B A B A
Implementing a Queue Implementing a Queue: using Array
• Just like a stack, we can implementing a queue in two ways: • Using an array to implement a queue is significantly harder than using an array
– Using an array to implement a stack. Why?
– A stack: we add and remove at the same end,
– Using a linked list
– A queue: we add to one end and remove from the other.
QUEUE
RADAR R R RADAR
ADAR A A ADAR
DAR D D DAR
AR A A AR
R R R R
empty empty empty empty