360 likes | 403 Views
Understand the fundamentals of linked list nodes, including insertion, removal, composition, and traversal. Learn about building and inserting to linked lists efficiently, handling ordered lists, and node deletion strategies. Check out examples and revisions for better linked list management. Explore designing a new linked list structure with improved insertion methods. Discover how to insert nodes at specific positions in a linked list, addressing scenarios like adding nodes before a target integer. Dive into linked list concepts to strengthen your data structure knowledge.
E N D
Introduction to Data Structure Chapter 9 Ming Li Department of Computer Science California State University, Fresno Fall 2006
Linked List Nodes • Each Node is like a piece of a chain • To insert a new link, break the chain at the desired location and simply reconnect at both ends of the new piece.
Linked List Nodes • Removal is like Insertion in reverse.
Node Composition • An individual Node is composed of two parts, a Data field containing the data stored by the node, and a Pointer field that marks the address of the next Node in the list. struct node { int data; struct node* next; }
Declaring a Node Class Template <typename T> class node { public: T nodeValue; node<T> *next; node():next(NULL) {} node(const T& item, node<T> *nextNode = NULL): nodeValue(item), next(nextNode) {} }
Inserting at the Front of a Linked List front item struct node* newNode; newNode = new(struct node); newNode->data = item; newNode->next = NULL; front = newNode;
Inserting at the Front of a Linked List front 20 55 struct node* newNode; newNode = new(struct node); newNode->data = 10; newNode->next = front; front = newNode; 10
Building a Linked List struct node* front, *newNode; front = NULL; for(int i=1;i<5;i++) { newNode = new(struct node); newNode->data = i; newNode->next = front; front = newNode; } front 4 3 1 next 2
Traversing a Linked List struct node* p; p = front; while(p->next != NULL) { p=p->next; } front 4 3 1 next 2 p p p p p
Traversing a Linked List struct node* p = front; while(p->next != NULL) { ….. p = p->next; } struct node* p; for(p=front;p->next!=NULL;p=p->next) { ….. }
Inserting at the middle of a Linked List struct node* newNode; newNode = new(struct node); newNode->data = 2; newNode->next = p->next; p->next = newNode; p->next? front 4 3 0 next 1 p 2
Inserting to an ordered Linked List void InsertToLList(struct node* front, struct node* newItem) { struct node* p = front; while(p->next != NULL && p->next->data < newItem->data) { p = p->next; } if(p->next != NULL) { newItem->next = p->next; p->next = newItem; } else { newItem->next = NULL; p->next = newItem; } }
Inserting to an ordered Linked List - Improvement void InsertToLList(struct node* front, struct node* newItem) { struct node* p = front; while(p->next != NULL && p->next->data < newItem->data) { p = p->next; } newItem->next = p->next; p->next = newItem; }
Inserting to an ordered Linked List - Correction void InsertToLList(struct node* front, struct node* newItem) { struct node* p = front; if(p->data > newItem->data) { newItem->next = p; front = newItem; return; } while(p->next != NULL && p->next->data < newItem->data) { p = p->next; } newItem->next = p->next; p->next = newItem; }
Deleting From the Front of a Linked List front = front->next; or if(front->next == NULL) front = NULL; front // front = NULL Deleting front of a 1-node list
Deleting From the Front of a Linked List struct node* p = front; front = front->next; delete p; front // Deleting front of a multi-node list
Deleting in a Linked List struct node* curr = p->next; p->next = curr->next; delete curr; front 4 3 1 next 2 p curr
Removing a Target Node Question: Can we delete the last element of the linked list? struct node* p = front; while(p->next != NULL) { struct node* curr = p->next; if(curr->data == target) { p->next = curr->next; delete curr; } p=p->next; } front next target // // p curr
Removing a Target Node struct node* p = front; if(p->data == target) { front = p->next; delete p; return; } while(p->next != NULL) { struct node* curr = p->next; if(*curr == target) { p->next = curr->next; delete curr; } } Question: Can we delete the first element of the linked list?
top D C B A Stack Handling the Back of the List front C B A D Linked List
Designing a New Linked List Structure Insertion will take constant time!
Designing a New Linked List Structure prevLast front ... back item Push_back() now takes constant time!
Inserting a Node at a Position Declare the data structure: struct node { int data; struct node* next; struct node* prev; }
Inserting a Node at a Position 1 // // prev next // // succNode = curr next prevNode = curr prev -> -> curr 2 curr->prev = prevNode; curr->next = succNode; prevNode->next = curr; succNode->prev = curr;
Inserting a Node at a Position To insert a node pointed by “curr” before a node in the linked list whose data is an integer “target”. If the node is found, do the insertion. Otherwise, the function simply returns. int InsertBefore(struct node* front, struct node* curr, int target) { …… …… } return 1; }
Inserting a Node at a Position int InsertBefore(struct node* front, struct node* curr, int target) { struct node *prevNode, *prevNode; prevNode = front; succNode= NULL; while(prevNode->next != front) { succNode = prevNode->next; if(succNode->data == target) { curr->prev = prevNode; curr->next = succNode; prevNode->next = curr; succNode->prev = curr; return 0; } prevNode = prevNode->next; } return 1; }
Inserting a Node at a Position int InsertBefore(struct node* front, struct node* curr, int target) { struct node *prevNode, *prevNode; if(front->data == target) { curr->prev = front->prev; curr->next = front; front->prev->next = curr; front->prev = curr; front = curr; return 0; } prevNode = front; succNode= NULL; while(prevNode->next != front) { …. } return; }
Inserting a Node at a Position int InsertBefore(struct node* front, struct node* curr, int target) { struct node *prevNode, *prevNode; if(front->data == target) { curr->prev = front->prev; curr->next = front; front->prev->next = curr; (front->next)->prev = curr; front = curr; return 0; } prevNode = front; succNode= NULL; while(prevNode->next != front) { succNode = prevNode->next; if(succNode->data == target) { curr->prev = prevNode; curr->next = succNode; prevNode->next = curr; succNode->prev = curr; return 0; } } return; }
Inserting a Node at a Position int InsertBefore(struct node* front, struct node* curr, int target) { struct node *prevNode, *prevNode; if(front == NULL) return 1; if(front->data == target) { … } prevNode = front; succNode= NULL; while(prevNode->next != front) { …. } return; }
Inserting a Node at a Position int InsertBefore(struct node* front, struct node* curr, int target) { struct node *prevNode, *prevNode; if(front == NULL) return 1; if(front->data == target) { curr->prev = front->prev; curr->next = front; front->prev->next = curr; (front->next)->prev = curr; front = curr; return 0; } prevNode = front; succNode= NULL; while(prevNode->next != front) { succNode = prevNode->next; if(succNode->data == target) { curr->prev = prevNode; curr->next = succNode; prevNode->next = curr; succNode->prev = curr; return 0; } } return 1; }
Deleting a Node at a Position prevNode->next = succNode; succNode->prev = prevNode;
Typical Linked List Problems Reverse a linked list. Swap two elements in a linked list. Insert into an ordered linked list. Find the middle of a linked list. Check if a linked list is cyclic. Split a linked list to two lists Concantenate two linked lists to one list
Finding middle of a linked list p1 p1 p1 p1 p2 p2 p2 p2 p2 p2 p2 struct node* p1, *p2; p1= p2= front; while(p2->next != NULL) { p1 = p1->next; p2 = p2->next; if(p2->next != NULL) p2->next = p2; }
Finding loop in a linked list p1 p1 p1 p1 p1 p2 p2 p2 p2 p2 p2 struct node* p1, *p2; p1=front->next; p2=p1->next; while(p1 != p2) { p1 = p1->next; p2 = p2->next; if(p2->next != NULL) p2->next = p2; }
Combining two linked lists p1 p1 p1 p1 p1 p1 p1 p2 struct node* p1, *p2; p1= front1; p2= front2; while(p1->next != NULL) p1 = p1->next; p1->next = p2;