Vous êtes sur la page 1sur 6

C Structures in Action: Linked-lists No programming language discussion is complete without discussing data structures that can be constructed from

the basics of the language. In this note we will study linked-list, one of the most widely used data structures. A singly linked-list is a sequence of items called nodes, each of which contains two pieces of information: data stored in the node and a reference to the next item in the sequence. The last item in a linked-list will have a special reference called null indicating the fact that it is the last element in the sequence. (See Fig. 1 below.) o There is no restriction on the number of items that a singly linked-list could have (except, of course, constrained by computer memory). So, this structure can be used as an expandable array, in a way. o Time to access an element depends on where the element is located in the sequence since we need to start the search from the very first element in the list (we cannot access an element by its index as in the case of arrays)

Figure 1. A singly linked-list of n elements A linked-list data structure has an advantage over an array collection in that there is no restriction on the number of elements it can hold. Structure could grow and shrink dynamically depending on the need. Array size, on the other hand, need to be determined before an array structure is created and resizing an array is a costly operation. On the other hand, accessing a particular element in a linked-list is not as efficient as accessing an array element: time to access a particular element depends on the location of that element in the linked-list structure. In an array, on the other hand, the time to access an element is the same for all elements. A linked-list data structure typically maintains a pointer to the first element in the list. This pointer provides the entry into the structure. All basic operations start with this pointer, which is sometimes called header. Basic operations on a linked-list are inserting a new element, deleting an element, searching for an element, and traversing all elements. Below is the pseudocode for these operations (pseudocode is what people typically use to sketch out an algorithm; the actual code could be built by following the logic in pseudocode): a) Algorithm insert(newElement) // create a new data node to add to the linked-list

newNode = allocateNewNode(newElement) // just add the new element to the beginning of the list // newElements address becomes the entry point to the list newNode.nextElement header header address(newNode) b) Algorithm delete(element) previousNode null nextNode header while nextNode != null and nextNode.element != element do // Keep a reference to the previous element previousNode nextNode // Move to the next element nextNode nextNode-->nextElement end while // The loop above terminates either when the element is found or // when the list is completely traversed and the element is not found. If nextNode != null // This implies that the element pointed by nextNode is the one // to be deleted. So, the node before it should now point to the // node after it. previousNode-->nextElement = nextElement-->nextElement deallocate memory used by nextElement else // Else block will be entered when element is not found. Nothing // to do here

c) Algorithm find(element) nextNode header

while nextNode != null and nextNode.element != element do // Move to the next element nextNode nextNode-->nextElement end while // The loop above terminates either when the element is found or

// when the list is completely traversed and the element is not found. If nextNode != null return nextNode element else // Else block will be entered when element is not found. return null d) Algorithm traverseList() nextNode header

while nextNode != null and nextNode.element != element do // Work on the operation on the current element someOperation(nextNode) // Move to the next element nextNode nextNode-->nextElement end while An example: A linked-list of student records We will go over a simple example of a linked-list of student records. I will keep the structure simple since the point of this exercise is not to build a full student record. Lets define the student structure in a linked-list:
struct Student { char* firstName; char* lastName; char* studentNumber; float gpa; /* * Pointer to the next student record. */ struct Student* nextStudentRecord; };

Note that the last element is a pointer to a student record. This will be the link from one record to the next that we will use in order to traverse the linked-list of records. (See Figure 1 above.) Code to insert an element to the linked-list is as follows:
/** * Inserts a given element to the linked list, the first element of

* which is referenced by the header pointer. * * linkedListHeader: the pointer to the first element in the * linked list * newElement: the new element to be added to the linked list */ struct Student* insert(struct Student* linkedListHeader, struct Student* newElement) { /* * Add the new element to the top of the list. */ newElement->nextStudentRecord = linkedListHeader; /* * Mark the header node of the list as the new node just added. */ linkedListHeader = newElement; return linkedListHeader; }

And the code to find an element in the list is as follows:


/** * Finds the student record with the given student number and * returns the record to the caller. * * linkedListHeader: the pointer to the first element in the * linked list * studentNumber: number of the student whose record to be found * * returns: student record if found; otherwise, returns NULL. */ struct Student* find(struct Student* linkedListHeader, char* studentNumber) { struct Student* currentNode; currentNode = linkedListHeader; /* * Traverse the linked-list until the student record is found * or until the whole list is traversed. */ while (currentNode != NULL && strcmp(currentNode->studentNumber, studentNumber) != 0) { currentNode = currentNode->nextStudentRecord; } return currentNode; }

About the strcmp() function above: this is a C library function that compares two strings (or two character arrays). It returns 0 if the two strings are the same. We will cover strings at length later. Here is a simple test program that inserts two records into a list, finds a given student record, and prints it.
#include "linkedlist.h" int main() { /* * Declare and initialize two student records. */ struct Student s1 = {"Turgut", "Ozben", "123890", 3.5, NULL}; struct Student s2 = {"Selim", "Isik", "872340", 3.8, NULL}; /* * Pointer to the first element of the linked list. */ struct Student* studentList; /* * Initially there are no students in the list. */ studentList = NULL; /* * Add students s1 and s2 to the list. */ studentList = insert(studentList, &s1); studentList = insert(studentList, &s2); /* * Find student record with student id of 123890 */ struct Student* p; p = find(studentList, "123890"); /* * Print the student record. */ if (p != NULL) { printf("Student record found \n"); printf("First Name: %s Last Name: %s Student No: %s GPA: %f \n", p->firstName, p->lastName, p->studentNumber, p->gpa); } else { printf("Student record not found \n"); }

return (0); }

The source files are in hbar server in the usual location. File names are linkedlist.h and linkedlist.c. There is also a test program called testlinkedlist.c.

Vous aimerez peut-être aussi