Download presentation
Presentation is loading. Please wait.
1
Concept of lists and array implementations of lists
2
A simple ‘list’ example * Concept of a list, e.g. a list of integers * A list is a linear sequence of objects n Print out info n Empty test n Search n Insertion n Deletion n … * implemented n by a static array (over-sized if necessary) int list[1000]; int size; n by a dynamic array int list[size]; int size; n by a linked list and more …
3
int main() { int A[1000]; int n; cin >> n; initialize(A, n, 0); print(A, n); addEnd(A,n,5); // or A = addEnd(A,n,5); print(A, n); addHead(A,n,5); // or A = addHead(A,n,5); print(A, n); deleteFirst(A,n); // or A = deleteFirst(A,n); print(A, n); selectionSort(A, n); print(A, n); } How to use a list? Static array! const int DIM=1000; int main() { int A[DIM]; int n; cin >> n; … } Using a (static) array
4
Initialize void initialize(int list[], int size, int value){ for(int i=0; i<size; i++) list[i] = value; }
5
void print(int list[], int size) { cout << "[ "; for(int i=0; i<size; i++) cout << list[i] << " "; cout << "]" << endl; } Print out a list
6
Delete the first element int* deleteFirst(int list[], int& size){ for(int i=0; i<size-1; i++) list[i] = list[i+1]; size--; return list; } // for deleting the first element of the array void deleteFirst(int list[], int& size){ for(int i=0; i<size-1; i++) list[i] = list[i+1]; size--; } B = deleteFirst(A,n) deleteFirst(A,n) Pointer type!
7
int* deleteFirst(int list[], int& size){ for(int i=0; i<size-1; i++) list[i] = list[i+1]; size--; return list; } int* deleteFirst(int* list, int& size){ for(int i=0; i<size-1; i++) *(list+i) = *(list+i+1); size--; return list; } int* deleteFirst(int* head, int& size){ for(int i=0; i<size-1; i++) *(head+i) = *(head+i+1); size--; return head; } int* deleteFirst(int* head, int& size){ size--; return head++; }
8
Adding Elements int* addEnd(int list[], int& size, int value){ if ((size>0) && (size < DIM)) { list[size] = value; size++; } return list; } // for adding a new element to end of array void addEnd(int list[], int& size, int value){ if (size < DIM) { list[size] = value; size++; } B = addEnd(A,n,v) addEnd(A,n,v) If not full!
9
int* addHead(int list[], int& size, int value){ if(size < DIM){ for(int i=size-1; i>0; i--) list[i+1] = list[i]; list[0] = value; size++; return list; } else … } Add at the beginning: // for adding a new element at the beginning of the array void addHead(int list[], int& size, int value){ if(size < DIM){ for(int i=size-1; i>0; i--) list[i+1] = list[i]; list[0] = value; size++; } else cout << “out of array memory!!! << endl; } B = addHead(A,n,v) addHead(A,n,v)
10
Using a dynamic array int main() { cout << "Enter list size: "; int n; cin >> n; int* A = new int[n]; … }
11
int main() { cout << "Enter list size: "; int n; cin >> n; int* A = new int[n]; initialize(A, n, 0); print(A, n); A = addEnd(A,n,5); print(A, n); A = addHead(A,n,5); print(A, n); A = deleteFirst(A,n); print(A, n); selectionSort(A, n); print(A, n); delete[] A; } How to use a list? int A[1000]; int n; cin >> n;
12
Initialize and Print-out: the same as before void initialize(int list[], int size, int value){ for(int i=0; i<size; i++) list[i] = value; } void print(int list[], int size) { cout << "[ "; for(int i=0; i<size; i++) cout << list[i] << " "; cout << "]" << endl; }
13
Delete the first element // for deleting the first element of the array int* deleteFirst(int list[], int& size){ int* newList; if (size>1) { newList = new int[size-1]; // make new array // copy and delete old array for(int i=0; i<size-1; i++) newList[i] = list[i+1]; delete[] list; size--; return newList; } else … } If not empty!!!, cannot delete an empty list.
14
Instead of A = deleteFirst(A,n) we can also just do deleteFirst(A,n) if we define as a void type function: void deleteFirst(int* & A, int& size) { … A = newList; } Remark: For a static array, A does not change, but the content of A changed. For a dynamic array, A changed!
15
Adding Elements // for adding a new element to end of array int* addEnd(int list[], int& size, int value){ int* newList; newList = new int [size+1]; // make new array if(size){// copy and delete old array for(int i=0; i<size; i++) newList[i] = list[i]; delete[] list; } newList[size] = value; size++; return newList; } Not empty list
16
// for adding a new element at the beginning of the array int* addHead(int list[], int& size, int value){ int* newList; newList = new int [size+1]; // make new array if(size){// copy and delete old array for(int i=0; i<size; i++) newList[i+1] = list[i]; delete[] list; } newList[0] = value; size++; return newList; } Add at the beginning:
17
Search and delete … // for adding a new element to end of array int* delete(int list[], int& size, int value){ Search the element in the array and get the position Shift all elements after it towards this position … }
18
Linked Lists
19
Motivation * A “List” is a useful structure to hold a collection of data. n 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];
20
Motivation * list using static 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; int n; 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.
21
How to use a linked list? int main() { … initialize(A, n, 0); print(A, n); A = addEnd(A,n,5); print(A, n); A = addHead(A,n,5); print(A, n); A = deleteFirst(A,n); print(A, n); selectionSort(A, n); print(A, n); … } int main() { … initialize(A,0); print(A); A = addEnd(A,5); print(A); A = addHead(A,5); print(A); A = deleteFirst(A); print(A); selectionSort(A); print(A); … } ‘n’ is removed, so we don’t need to ‘care’ about it!
22
Array naturally represents a (ordered) list, the link is implicit, consecutive and contiguous! Now the link is explicit, any places! 2045 7585 Data Link 20 45 75 85 Data Link 20457585 Data Link
23
Linked List Structure n Definition struct Node { int data; Node* next; }; n Create a Node Node* p; p = new Node; n Delete a Node delete p; n Definition struct Node { int data; Node* next; }; typedef Node* NodePtr; n Create a Node NodePtr p; p = new Node; n Delete a Node delete p;
24
n 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
25
Representing and accessing linked lists * 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. 20457585 Head
26
Passing a Linked List to a Function 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 It is roughly the same as for an array!!!
27
Manipulation (implementation) of a Unsorted Linked List
28
Start the first node from scratch NodePtr newPtr; newPtr = new Node; newPtr->data = 20; newPtr->next = NULL; head = newPtr; Head newPtr 20 Head head = NULL;
29
Inserting a Node at the Beginning newPtr = new Node; newPtr->data = 13; newPtr->next = Head; head = newPtr; Head newPtr 13 20
30
Keep going … Head newPtr 50401320
31
void addHead(NodePtr& head, int newdata){ NodePtr newPtr = new Node; newPtr->data = newdata; newPtr->next = Head; head = newPtr; } Adding an element to the head:
32
NodePtr addHead(NodePtr head, int newdata){ NodePtr newPtr = new Node; newPtr->data = newdata; newPtr->next = Head; return newPtr; } It can also be written (more functionally) as: Compare it with ‘addHead’ with a dynamic array implementation
33
(to delete) Deleting the Head Node NodePtr p; p = head; head = head->next; delete p; head p 50401320
34
void deleteHead(NodePtr& head){ if(head != NULL){ NodePtr p = head; head = head->next; delete p; } NodePtr deleteHead(NodePtr head){ if(head != NULL){ NodePtr p = head; head = head->next; delete p; } return head; } Or as a function:
35
A (unsorted) list with linked representation struct Node { int data; Node* next; }; void deleteHead(Node*& head){ if(head != NULL){ Node* p = head; head = head->next; delete p; } void addHead(Node*& head, int newdata){ Node* newPtr = new Node; newPtr->data = newdata; newPtr->next = Head; head = newPtr; } Data representation Operations void …(…){ … }
36
Displaying a Linked List p = head; print out (*p) p = p->next; print out (*p) 2045 head p 2045 head p
37
void displayList(NodePtr head){ NodePtr p; p = head; while(p != NULL){ cout data << endl; p = p->next; } A linked list is displayed by walking through its nodes one by one, and displaying their data fields (similar to an array!). void displayArray(int data[], int size) { int i; i=0; while ( i<size ) { cout << data[i] << endl; i++; } For an array: void displayArray(int data[], int size) { int* p; p=data; while ( (p-data)<size ) { cout << *p << endl; p++; } i p p++ p->next
38
Searching for a value in a linked list (look at array searching first!)
39
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; } Remember searching algorithm in an array: It is essentially the same!
40
NodePtr searchNode(NodePtr head, int item){ NodePtr p = head; NodePtr position = NULL; bool found=false; while((p != NULL) && (!found)){ if(p->data == item) { found = true; position = p;} p = p->next; } return position; } Searching for a value 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 even closer! npnp
41
* Original linked list of integers: * Add to the end (insert at the end): More operation: adding to the end 50401320 50401320 60 Last element The key is how to locate the last element or node of the list!
42
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; } Add to the end: Link new object to last->next Link a new object to empty list
43
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; } Add to the end as a function:
44
Manipulation (implementation) of a Sorted Linked List
45
Inserting a value in a sorted list 1. Find the position 2. Free up the place by moving the others 3. Insert the new value How to do it in a sorted array? a static array and a dynamic array
46
Inserting a Node Head cur 20 33 4575 prev... newPtr 1.(a) Create a new node using: 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;
47
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 data
48
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! It’s a kind of search algo,
49
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. Finally, it is equivalent to: A useful programming ‘trick’: boolean ‘found’ can be avoided.
50
//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
51
(to delete) 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 cur 20457585 prev...
52
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; } Delete an element in a sorted linked list: If the element is at the head General case We can delete only if the element is present! If (cur==NULL || cur->data!=item) Item is not in the list! Get the location If it’s in, negation of ‘not in’
53
Other variants of linked lists
54
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. n always present, even when the linked list is empty n Insertion and deletion algorithms initialize prev to reference the dummy head node, rather than NULL head 401320 Dummy head node head empty list! list of (40,13,20)
55
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 Rear 1020407055
56
Doubly Linked Lists In a Doubly Linked-List each item points to both its predecessor and successor n prev points to the predecessor n next points to the successor 1070205540 Head Cur Cur->nextCur->prev
57
struct Node{ int data; Node* next; Node* prev; }; typedef Node* NodePtr; Doubly Linked List Definition
58
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
59
Idea of ‘dummy’ object l Instead of pointing to NULL, point to the ‘dummy’!!! l Skip over the dummy for the real list 70205540 Head 10 Dummy Head Node ‘dummy object’ is also called a ‘sentinel’, it allows the simplification of special cases, but confuses the emptyness NULL!
60
Head Dummy Head Node Empty list: Head->next = head; compared with head=NULL;
61
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 } Binary tree
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.