Data Structures AZHAR MAQSOOD NUST Institute of Information Technology (NIIT) Lecture 6: Linked Lists Linked List Basics

Embed Size (px)

DESCRIPTION

 Simplest form of linked list  Linked list object holds a reference to the first node on the list  Each node object consists of a reference to the data object being stored, and a reference to the next node in the list

Citation preview

Data Structures AZHAR MAQSOOD NUST Institute of Information Technology (NIIT) Lecture 6: Linked Lists Linked List Basics Consists of items that are linked to each other Each item on the list is associated with a reference (pointer) that indicates where the next item is found A dynamic data structure: grows and shrinks as necessary at runtime There are no unused/empty locations Simplest form of linked list Linked list object holds a reference to the first node on the list Each node object consists of a reference to the data object being stored, and a reference to the next node in the list The pointer to the first node in the list is referred to as the head pointer, because it points to the head node in the list. In addition to the head pointer, there are usually other pointers associated with the list. These can include a pointer to the last element in the list (tail pointer) and a pointer that traverses the list to find data (navigator or traversal pointer). Memory Loc ValueName Pointer to Linked list first element 1000AliPerson.Name Person.Age Next_Person 5500ZainPerson.Name 55265Person.Age 5530NULLNext_Person . head Linked List object Node objects Data objects size 3 To find the n th item in a linked list: Follow the head pointer to the first node Find the reference to the next node Follow it to the second node Find the reference to the next node Follow it to the third node Etc, until n th node is reached Data pointer points to the n th item . head Linked List object size tail 3 tail reference makes it easier to add to the end of the linked list Oftentimes it is convenient to create a structure that contains the head pointer of a list and also information about the list itself (e.g., number of elements currently in the list, maximum number of elements to be allowed in the list, etc). This extra data is referred to as metadata. With a linked list, there are a standard set of functions that operate on the list: Creating the list Initialize pointers to NULL; Inserting nodes Insert at beginning Insert at middle Insert at last Deleting nodes Delete from beginning, middle, last Traversing the list Destroying the list #include struct person { char name[25]; int age; struct person *Next_Person; }; struct linkedlist { struct person *head; struct person *tail; int nodeCount; }; void initialize(linkedlist *ll); void InsertFront(linkedlist *ll); void InsertRear(linkedlist *ll); void DeleteRear(linkedlist *ll); void getData(person *p); void PrintList(linkedlist *ll); void main (void) { linkedlist ll; //linked list created initialize(&ll); //linked list initialized int choice = 0; //list is empty, lets create person dynamically do { cout head = p; ll->tail = p; ll->nodeCount++;} void getData(person *p) { cin >> p->name ; cin >> p->age ; p->Next_Person = NULL; //just to initialize } headsize tail 0.. Build the new node, and put the reference to the new data item in it. headsize tail 1 Make both head and tail point at the new node, and increment the lists size. . headsize tail 3 Build the new node, and put the reference to the new data item in it. . headsize tail 3 Make the new node point at the current front node . headsize tail 4 Reset head so that it points at the new node, and increment size of the linked list void InsertRear(linkedlist *ll) { if (ll->head == NULL && ll- >nodeCount == 0) //means empty list { person *p; p = (person*) malloc(sizeof(person)); getData(p); ll->head = p; ll->tail = p; ll->nodeCount++; }else{ person *p; p = (person*) malloc(sizeof(person)); getData(p); p->Next_Person = NULL; //rear insertion... hence points to NULL. ll->tail->Next_Person = p; //now point tail of second last element to last ll->tail = p;//yes tail is now the new element inserted ll->nodeCount++; //increment counter }} . headsize tail 3 Build the new node, and put the reference to the new data item in it. null reference headsize tail 3 Make the current tail node point to the new node. headsize tail 4 Reset tail so that it points to the new node, and increment the list size. void RemoveFront(linkedlist *ll) { if (ll->nodeCount > 0 ) //means not empty list { person *temp; temp = ll->head ; ll->head =ll->head->Next_Person if (ll->head==NULL) //if list has only single item ll->tail =NULL ll->tail =NULL delete temp; ll->nodeCount --; }} headsize tail 4 Save the value of head, so that we will be able to retrieve the data item to be deleted. headsize tail 4 Replace the value in head with a reference to the second node on the list. headsize tail 4 Save a reference to the data item in the first node. headsize tail 3 Get rid of the (original) first node, decrement the size of the list, and return the reference to the removed item. headsize tail 1 Save a reference to the node, and a reference to the data item found in the first node. headsize tail 0 Set head and tail to NULL, and decrement the size of the list... headsize tail 0 Get rid of the node, and return the reference to the data item... void DeleteRear(linkedlist *ll) { person *tempNext; person *tempPrevious; tempNext = ll->head ; if (ll->nodeCount > 0 ) {if (ll->nodeCount ==1){ only single item in the linkedlist ll->head = NULL; ll->tail=NULL; } else{//more than one items in the linked list while (tempNext->Next_Person != NULL) { tempPrevious = tempNext; tempNext = tempNext->Next_Person; } ll->tail=tempPrevious; tempPrevious->Next_Person = NULL; } delete tempNext; ll->nodeCount --; }} headsize tail 4 Save the value of tail, so that we will be able to retrieve the data item to be deleted. headsize tail 4 Beginning at head, traverse the list until we reach the node that points at the tail node. 1 23 headsize tail 3 Set the link reference in this node to NULL, make tail point at this node, and decrement the list size.. headsize tail 3 Save a reference to the removed data object, get rid of the removed node object, and return the reference to the data object.. Algorithms that traverse a list start at the first node and examine each node in succession until the last node has been processed. Traversal logic is used by several different types of algorithms, such as changing a value in each node, printing the list, summing a field in the list, or calculating the average of a field. Etc etc etc.. ( so many requirements) Any application that requires that the entire list be processed uses a traversal. To traverse the list we need a walking (navigator) pointer. This pointer is used to move from node to node as each element is processed. Example is our print function. A search list is used by several algorithms to locate data in a list: To insert data, we need to know the logical predecessor to the new data. To delete data, we need to find the node to be deleted and identify its logical predecessor. To retrieve data from a list, we need to search the list and find the data. Worst case is that the data to be retrieved is at the last of the list. E.g Find the employee whos name is Salman, if salman is present then the record (node) having salman will be returned else return null node. First let us consider searching a list in which the elements are sorted based on a field value. Given a target key, the ordered list search attempts to locate the requested node in the linked list. If a node in the list matches the target, the search returns true, else we return false. True can also be returning the specific node E.g Find the employee whos name is Salman, It will be faster if the list was in alphabetical order