Linked Lists A linked list is a data structure that uses a "chain" of node objects, connected by pointers, to organize a collection of user data values.

Slides:



Advertisements
Similar presentations
Pointers.
Advertisements

Stacks, Queues, and Linked Lists
Queues and Linked Lists
DATA STRUCTURES USING C++ Chapter 5
Linked List Variations
Data Structure Lecture-5
Chapter 17 Linked List Saurav Karmakar Spring 2007.
Review Learn about linked lists
Linked Lists Compiled by Dr. Mohammad Alhawarat CHAPTER 04.
Data Structures Topic #3. Today’s Agenda Ordered List ADTs –What are they –Discuss two different interpretations of an “ordered list” –Are manipulated.
Chapter 3: Arrays, Linked Lists, and Recursion
Linked Lists list elements are stored, in memory, in an arbitrary order explicit information (called a link) is used to go from one element to the next.
Data Structures Week 5 Further Data Structures The story so far  We understand the notion of an abstract data type.  Saw some fundamental operations.
Chapter 1 Object Oriented Programming. OOP revolves around the concept of an objects. Objects are created using the class definition. Programming techniques.
Linked Lists part 2 CS 244 Brent M. Dingle, Ph.D. Game Design and Development Program Department of Mathematics, Statistics, and Computer Science University.
Prof. amr Goneid, AUC1 CSCE 110 PROGRAMMING FUNDAMENTALS WITH C++ Prof. Amr Goneid AUC Part 16. Linked Lists.
1 Linked-list, stack and queue. 2 Outline Abstract Data Type (ADT)‏ Linked list Stack Queue.
Linked List Chapter Data Abstraction separates the logical properties of a data type from its implementation LOGICAL PROPERTIES – What are the.
Linked lists. Data structures to store a collection of items Data structures to store a collection of items are commonly used Typical operations on such.
Doubly Linked List Exercises Sometimes it is useful to have a linked list with pointers to both the next and previous nodes. This is called a doubly linked.
Structs in C Computer Organization I 1 November 2009 © McQuain, Feng & Ribbens struct Properties The C struct mechanism is vaguely similar.
Lists List Implementations. 2 Linked List Review Recall from CMSC 201 –“A linked list is a linear collection of self- referential structures, called nodes,
Linked Lists Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University of Wisconsin.
CMSC 202 Computer Science II for Majors. CMSC 202UMBC Topics Templates Linked Lists.
CPSC 252 Linked Lists III Page 1 Variations on Singly Linked Lists Inserting or deleting at the front of a list is different from at any other point in.
STACKS & QUEUES for CLASS XII ( C++).
Lecture 6 of Computer Science II
Cpt S 122 – Data Structures Abstract Data Types
Pointers and Linked Lists
Data Structure By Amee Trivedi.
Chapter 4 The easy stuff.
Struct Properties The C struct mechanism is vaguely similar to the Java/C++ class mechanisms: - supports the creation of user-defined data types - struct.
Pointers and Linked Lists
Introduction to Linked Lists
Lectures linked lists Chapter 6 of textbook
Payload Type The following notes illustrate debugging a linked list implementation with gdb. The example makes use of the following payload type: struct.
Data Structure Dr. Mohamed Khafagy.
Doubly Linked List Review - We are writing this code
Data Structures and Algorithms
Chapter 4 Linked Lists.
Problems with Linked List (as we’ve seen so far…)
Stack and Queue APURBO DATTA.
Linked Lists head One downside of arrays is that they have a fixed size. To solve this problem of fixed size, we’ll relax the constraint that the.
CSCE 210 Data Structures and Algorithms
A Doubly Linked List There’s the need to access a list in reverse order prev next data dnode header 1.
Chapter 4 Linked Lists
LINKED LISTS CSCD Linked Lists.
Linked Lists Chapter 4.
Circularly Linked Lists
Object Oriented Programming COP3330 / CGS5409
Linked Lists: Implementation of Queue & Deque
Pointers and Linked Lists
Further Data Structures
Linked Lists.
Programming Abstractions
Linked Lists.
Doubly Linked List Implementation
Data Structures and Algorithms
Linked Lists Chapter 4.
Chapter 4 Linked Lists.
Chapter 17: Linked Lists.
Lecture No.02 Data Structures Dr. Sohail Aslam
Using a Queue Chapter 8 introduces the queue data type.
Using a Queue Chapter 8 introduces the queue data type.
Linked List Mechanics Slides Table of Contents Linear Lists
General List.
Doubly Linked List Implementation
Payload Type The following notes illustrate debugging a linked list implementation with gdb. The example makes use of the following payload type: struct.
BY PROF. IRSHAD AHMAD LONE.
Data Structures & Programming
Presentation transcript:

Linked Lists A linked list is a data structure that uses a "chain" of node objects, connected by pointers, to organize a collection of user data values. Here's a fairly typical conceptual view of a doubly-linked list: Head node 12 17 41 5 19 8 27 23 Tail node 33 32

Structural Considerations The use of "guard" nodes at the front and rear of a list eliminate any "special cases" when implementing insertion/deletion operations. This way, every "data" node will lie between two nodes. Front Guard Rear Guard 19 12 The common alternative is to simply have pointers to the first and last data nodes, probably stored in a list object. That leads to special cases when operating at the front or rear of the list.

Minimal Linked List Interface A linked list implementation will typically provide at least: - initialization function to set up basic structure for an empty list - insert functions to add new element to the list; at front, at rear, at user-selected position, ordered insertion - remove function to remove element from the list - find function to determine whether a given element occurs in the list - clear function to restore the list to an empty state In C we would organize this as a pair of struct types (list and node) and a collection of associated functions.

Generic Node and List #ifndef DLIST_H #define DLIST_H // List node: struct _DNode { struct _DNode *prev; // points toward front of list struct _DNode *next; // points toward tail of list }; // List object: struct _DList { struct _DNode head; // front guard node for list struct _DNode tail; // rear guard node for list typedef struct _DNode DNode; typedef struct _DList DList; #endif

DList Initialization DList object DNode head DNode tail Dnode* prev  An empty DList will be constructed as shown below: DList object DNode head DNode tail Dnode* prev  Dnode* next  Dnode* next Dnode* prev This eliminates special cases, because every data node will always be between two other nodes. We could also make head.prev point to tail and tail.next point to head, which would eliminate NULL pointers and allow the list to be used in a circular fashion.

Wrapping the Node in the Payload We may use a single DList of DNode objects with any user data type, without sacrificing type-checking. We merely have to create a "duct tape" object to attach a data object to a node: #ifndef INTEGERDT_H #define INTEGERDT_H #include "DList.h" struct _IntegerDT { // "duct tape" attaches data object to DNode int payload; DNode node; }; typedef struct _IntegerDT IntegerDT; void IntegerDT_Init(IntegerDT* const pLE, const int* const I); #endif

Example of "duct-taped" List Structure 7 DList 42 25 head tail IntegerDT The DList only "knows about" two DNode objects. Each DNode object only "knows about" one or two other DNode objects. The DList and Dnode objects "know" nothing of IntegerDT objects.

Inserting a DNode We want to insert the node on the bottom between the other two nodes: 3 next prev next prev a DNode a DNode before 2 4 1 next prev . . . elem->prev = before->prev; // 1 elem->next = before; // 2 before->prev->next = elem; // 3 before->prev = elem; // 4 elem

Inserting a DNode The DList only "knows about" two DNode objects. /* Inserts elem as the predecessor of before, which may be either an interior element or a tail. */ void DList_Insert (DNode* const before, DNode* const elem) { assert (is_interior (before) || is_tail (before)); assert (elem != NULL); elem->prev = before->prev; elem->next = before; before->prev->next = elem; before->prev = elem; }

Searching Clearly, we need to be able to search a list for a data value that matches some search criterion. 7 DList 42 25 head tail IntegerDT But we must follow the list pointers, which tie the DNode objects together… … so how are we going to access the user data objects?

Accessing the "duct tape" Suppose the IntegerDT object is laid out in memory as shown: memory p payload payload prev next prev next increasing addresses q IntegerDT p IntegerDT DNode We want a pointer q that points to the IntegerDT object that contains the Dnode that p points to. Then it appears we can set the value for q by subtracting 4 from p… … but that logic depends on the specific memory layout shown above.

offsetof() to the Rescue! The Standard Library includes a relevant C macro: offsetof(type, member-designator) expands to an integer constant expression that has type size_t, the value of which is the offset in bytes, to the structure member (designated by member-designator), from the beginning of its structure (designated by type). offsetof(F, member3) member1 offset of member3 member2 member3 struct F { member1; member2; member3; member4; }; member4 . . .

So… Let's say that we have a pointer P to a DNode, which is embedded within one of the IntegerDT objects seen earlier, and is also part of a DList. 7 node P IntegerDT Then, the address of the IntegerDT object would (almost) be given by: P – offsetof(IntegerDT, node) We just need to throw in a couple of typecasts: (IntegerDT*) ( (uint8_t*)(P) – offsetof(IntegerDT, node) )

DList_Entry() This is just begging to be turned into a C preprocessor macro: /* Converts pointer to a DNode NODE into a pointer to the structure that DNode is embedded inside. Supply the name of the outer structure STRUCT and the member name MEMBER of the DNode. */ #define DList_Entry(NODE, STRUCT, MEMBER) \ ((STRUCT *) ((uint8_t *) (NODE) – \ offsetof (STRUCT, MEMBER)))

Aside: Macro Translation When the preprocessor sees code whose pattern matches the macro "interface", it replaces that code with code generated from the macro "body": . . . IntegerDT *p = DList_Entry(e, IntegerDT, node); #define DList_Entry(NODE, STRUCT, MEMBER) \ ((STRUCT *) ((uint8_t *) (NODE) – \ offsetof (STRUCT, MEMBER))) . . . IntegerDT *p = ((IntegerDT*) ((uint8_t*) (e – offsetof(IntegerDT, node)) );

Traversing the DList void traverseList(DList* pL) { DNode* e = DList_Head(pL); while ( (e = DList_Next(e)) != DList_End(pL)) { // Get pointer to the "duct-tape" object from // the pointer to the DList element: IntegerDT *p = DList_Entry(e, IntegerDT, node); // Get value of payload within "duct-tape" object: int userData = p->payload; // do stuff with current user data element }

More DList Functions Here are some ideas for DList interface functions: // Set up an empty list: void DList_Init(DList* pList); // Insert node elem in front of node before: void DList_Insert(DNode* pBefore, DNode* pElem); // Remove node elem: DNode* DList_Remove(DNode* pElem); // Is list empty? bool DList_Empty(DList* pList); // Restore list to empty state: void Dlist_Clear(Dlist* pList); . . .

More DList Functions . . . // Get pointer to first/last data node in list: DNode* DList_Begin(DList* pList); DNode* DList_End(DList* pList); // Get pointer to successor/predecessor of node: DNode* DList_Next(DNode* pElem); DNode* DList_Prev(DNode* pElem); // Get pointer to head/tail of list: DNode* DList_Head(DList* pList); DNode* DList_Tail(DList* pList);

More DList Functions . . . // Insert elem at front/rear of list: void DList_PushFront(DList* pList, DNode* pElem); void DList_PushBack(DList* pList, DNode* pElem); // Remove elem from front/rear of list: DNode* DList_PopFront(DList* pList); DNode* DList_PopBack(DList* pList);