Download presentation
Presentation is loading. Please wait.
1
Linked Lists
2
Motivation A “List” is a useful structure to hold a collection of data. Currently, we use arrays for lists Examples: List of ten students marks int studentMarks[10]; List of temperatures for the last two weeks double temperature[14];
3
Motivation list using static array list using dynamic array
int myArray[1000]; int n; We have to decide (to oversize) in advance the size of the array (list) list using dynamic array int* myArray; cin >> n; myArray = new int[n]; We allocate an array (list) of any specified size while the program is running linked-list (dynamic size) size = ?? The list is dynamic. It can grow and shrink to any size.
4
‘n’ is removed, so we don’t need to ‘care’ about it!
How to use a linked list? int main() { … initialize(A,0); print(A); A = addEnd(A,5); print(A, n); A = addHead(A,5); A = deleteFirst(A); selectionSort(A); } int main() { … initialize(A, n, 0); print(A, n); A = addEnd(A,n,5); A = addHead(A,n,5); A = deleteFirst(A,n); selectionSort(A, n); } ‘n’ is removed, so we don’t need to ‘care’ about it!
5
Now the link is explicit, any places!
Array naturally represents a (ordered) list, the link is implicit, consecutive and contiguous! Now the link is explicit, any places! Data 75 85 20 45 Link Link Data 45 85 20 75 20 45 75 85 Data Link
6
Linked Lists: Basic Idea
A linked list is an ordered collection of data Each element of the linked list has Some data A link to the next element The link is used to chain the data Example: A linked list of integers: 20 45 75 85 Data Link
7
Linked Lists: Basic Ideas
The list can grow and shrink 20 45 75 85 addEnd(75), addEnd(85) deleteEnd(85), deleteHead(20), deleteHead(45) 75
8
Linked Lists: Operations
Original linked list of integers: Insertion (in the middle): Deletion (in the middle) 20 45 75 85 old value 20 45 75 85 60 20 45 75 85 deleted item
9
Definition of linked list type:
struct Node{ int data; Node* next; }; typedef Node* NodePtr;
10
typedef typedef allows you to make new shortcuts to existing types
typedef int WAH; WAH k; // same as: int k; typedef int* WAHPTR; WAHPTR p; // same as: int* p; typedef Node* NodePtr; NodePtr Head; // same as: Node* Head;
11
Linked List Structure Definition Definition Create a Node
struct Node { int data; Node* next; }; typedef Node* NodePtr; Create a Node NodePtr p; p = new Node; Delete a Node delete p; Definition struct Node { int data; Node* next; }; Create a Node Node* p; p = new Node; Delete a Node delete p;
12
Access fields in a node (*p).data; //access the data field
(*p).next; //access the pointer field Or it can be accessed this way p->data //access the data field p->next //access the pointer field
13
Representing and accessing linked lists
20 45 75 85 Head We define a pointer NodePtr head; (also: Node* head) that points to the first node of the linked list. When the linked list is empty then head is NULL.
14
Passing a Linked List to a Function
It is roughly the same as for an array!!! When passing a linked list to a function it should suffice to pass the value of head. Using the value of head the function can access the entire list. Problem: If a function changes the beginning of a list by inserting or deleting a node, then head will no longer point to the beginning of the list. Solution: When passing head always pass it by reference or using a function to return a new pointer value
15
Manipulation (implementation) of a Unsorted Linked List
16
Start the first node from scratch
head = NULL; Head NodePtr newPtr; newPtr = new Node; newPtr->data = 20; newPtr->next = NULL; head = newPtr; Head newPtr 20
17
Inserting a Node at the Beginning
newPtr = new Node; newPtr->data = 13; newPtr->next = Head; head = newPtr; 20 Head 13 newPtr
18
Keep going … Head newPtr 50 40 13 20
19
Adding an element to the head:
void addHead(NodePtr& head, int newdata){ NodePtr newPtr = new Node; newPtr->data = newdata; newPtr->next = Head; head = newPtr; }
20
It can also be written (more functionally) as:
NodePtr addHead(NodePtr head, int newdata){ NodePtr newPtr = new Node; newPtr->data = newdata; newPtr->next = Head; return newPtr; } Compare it with ‘addHead’ with a dynamic array implementation
21
Deleting the Head Node NodePtr p; p = head; head = head->next;
delete p; head (to delete) 50 40 13 20 p
22
Or as a function: void deleteHead(NodePtr& head){ if(head != NULL){
NodePtr p = head; head = head->next; delete p; } Or as a function: NodePtr deleteHead(NodePtr head){ if(head != NULL){ NodePtr p = head; head = head->next; delete p; } return head;
23
Displaying a Linked List
p = head; print out (*p) p = p->next; print out (*p) head 20 45 p head 20 45 p
24
A linked list is displayed by walking through its nodes one by one,
and displaying their data fields (similar to an array!). void displayList(NodePtr head){ NodePtr p; p = head; while(p != NULL){ cout << p->data << endl; p = p->next; } For an array: void displayArray(int data[], int size) { int* p; p=data; while ( (p-data)<size ) { cout << *p << endl; p++; } void displayArray(int data[], int size) { int n=0; while ( n<size ) { cout << data[i] << endl; n++; }
25
Searching for a value in a linked list (look at array searching first
26
Remember searching algorithm in an array: It is essentially the same!
void main() { const int size=8; int data[size] = { 10, 7, 9, 1, 17, 30, 5, 6 }; int value; cout << "Enter search element: "; cin >> value; int n=0; int position=-1; bool found=false; while ( (n<size) && (!found) ) { if(data[n] == value) { found=true; position=n;} n++; } if(position==-1) cout << "Not found!!\n"; else cout << "Found at: " << position << endl; It is essentially the same!
27
If we use a pointer to an array, it will be much closer!
Searching for a value NodePtr searchNode(NodePtr head, int item){ NodePtr p = head; NodePtr result = NULL; bool found=false; while((p != NULL) && (!found)){ if(p->data == item) { found = true; result = p;} p = p->next; } return result; int searchArray(int data[], int size, int value){ int n=0; int position=-1; bool found=false; while ( (n<size) && (!found) ) { if(data[n] == value) { found=true; position=n;} n++; } return position; If we use a pointer to an array, it will be much closer!
28
More operation: adding to the end
Original linked list of integers: Add to the end (insert at the end): 50 40 13 20 50 40 13 20 60 Last element The key is how to locate the last element or node of the list!
29
Link new object to last->next Link a new object to empty list
Add to the end: void addEnd(NodePtr& head, int newdata){ NodePtr newPtr = new Node; newPtr->data = newdata; newPtr->next = NULL; NodePtr last = head; if(last != NULL){ // general non-empty list case while(last->next != NULL) last=last->next; last->next = newPtr; } else // deal with the case of empty list head = newPtr; Link new object to last->next Link a new object to empty list
30
Add to the end as a function:
NodePtr addEnd(NodePtr head, int newdata){ NodePtr newPtr = new Node; newPtr->data = newdata; newPtr->next = NULL; NodePtr last = head; if(last != NULL){ // general non-empty list case while(last->next != NULL) last=last->next; last->next = newPtr; } else // deal with the case of empty list head = newPtr; return head;
31
Manipulation (implementation) of a
Sorted Linked List
32
Inserting a value in a sorted list
How to do it in a sorted array? a static array and a dynamic array 1. Find the position 2. Free up the place by moving the others 3. Insert the new value
33
Inserting a Node 1. (a) Create a new node using: 20 33 45 75 ...
NodePtr newPtr = new node; (b) Fill in the data field correctly. 2. Find “prev” and “cur” such that the new node should be inserted between *prev and *cur. 3. Connect the new node to the list by using: (a) newPtr->next = cur; (b) prev->next = newPtr; Head cur 20 33 45 75 prev ... newPtr
34
Finding prev and cur Suppose that we want to insert or delete a node with data value newValue. Then the following code successfully finds prev and cur such that prev->data < newValue <= cur->data
35
It’s a kind of search algo, Prev is necessary as we can’t go back!
prev = NULL; cur = head; found=false; while( (cur!=NULL) && (!found) ) { if (newValue > cur->data) { prev=cur; cur=cur->next; } else found = true; Prev is necessary as we can’t go back!
36
A useful programming ‘trick’: boolean ‘found’ can be avoided.
Finally, it is equivalent to: prev = NULL; cur = head; while( (cur!=NULL) && (newValue>cur->data) ) { prev=cur; cur=cur->next; } Logical AND (&&) is short-circuited, sequential, i.e. if the first part is false, the second part will not be executed.
37
If the position happens to be the head
//insert item into linked list according to ascending order void insertNode(NodePtr& head, int item){ NodePtr newp, cur, pre; newp = new Node; newp->data = item; pre = NULL; cur = head; while( (cur != NULL) && (item>cur->data)){ pre = cur; cur = cur->next; } if(pre == NULL){ //insert to head of linked list newp->next = head; head = newp; } else { pre->next = newp; new->next = cur; If the position happens to be the head General case
38
Deleting a Node To delete a node from the list
1. Locate the node to be deleted (a) cur points to the node. (b) prev points to its predecessor 2. Disconnect node from list using: prev->next = cur->next; 3. Return deleted node to system: delete cur; Head (to delete) ... 20 45 75 85 prev cur
39
Delete an element in a sorted linked list:
void deleteNode(NodePtr& head, int item){ NodePtr prev=NULL, cur = head; while( (cur!=NULL) && (item > cur->data)){ prev = cur; cur = cur->next; } if ( cur!==NULL && cur->data==item) { if(cur==Head) Head = Head->next; else prev->next = cur->next; delete cur; Get the location If it’s in, negation of ‘not in’ We can delete only if the element is present! If (cur==NULL || cur->data!=item) Item is not in the list! If the element is at the head General case
40
Other variants of linked lists
41
A note on ‘Dummy Head node’
A well-known implementation ‘trick’ or ‘method’: add one more node at the beginning, which does not store any data, to ease operations. always present, even when the linked list is empty Insertion and deletion algorithms initialize prev to reference the dummy head node, rather than NULL head empty list! head 40 13 20 Dummy head node list of (40,13,20)
42
Circular Linked Lists A Circular Linked List is a special type of Linked List It support the traversing from the end of the list to the beginning of the list by making the last node points back to the head of the list 10 20 40 55 70 Rear
43
Doubly Linked Lists In a Doubly Linked-List each item points to both its predecessor and successor prev points to the predecessor next points to the successor 10 70 20 55 40 Head Cur Cur->next Cur->prev
44
Doubly Linked List Definition
struct Node{ int data; Node* next; Node* prev; }; typedef Node* NodePtr;
45
Doubly Linked Lists with Dummy Head Node
To simplify insertion and deletion by avoiding special cases of deletion and insertion at front and rear, a dummy head node is added at the head of the list The last node also points to the dummy head node as its successor
46
Idea of ‘dummy’ object ‘dummy object’ is also called a ‘sentinel’, it allows the simplification of special cases, but confuses the emptyness NULL! Instead of pointing to NULL, point to the ‘dummy’!!! Skip over the dummy for the real list 70 20 55 40 Head 10 Dummy Head Node
47
Head->next = head; compared with head=NULL;
Empty list: Head Dummy Head Node Head->next = head; compared with head=NULL;
48
Binary tree A drawing of linked list with one pointer …
A drawing of binary tree with two pointers … Struct BinaryNode { double element; // the data BinaryNode* left; // left child BinaryNode* right; // right child }
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.