Вы находитесь на странице: 1из 14

Software Engineering II Algorithms and Data Structures Linked Lists

Dr. Christos Bouganis Imperial College London

4.1

Outline

In this lecture we will:


study the use of pointers to create dynamic data structures. Dynamic data structures can grow and shrink during program execution, so you can use as much memory as you need. study how linked lists are implemented. quick look at the idea of abstract data types, data structures whose implementation details are hidden. familiarize ourselves with the heap. study how to operate on a linked list

Automatic variables
Until now we always declare the variables that will be used
int i; int myArray[25];

These variables are called automatic variables, because their creation and destruction is controlled automatically for you. These variables are created when a function is called and are destroyed when the function terminates.
i myArray Memory

int i; int myArray[25];

Downside?
3

Dynamic variables
Dynamic variables are created and destroyed while the program is running. Pointers are used in dynamic variable creation and operation.

Stage 1 int *p; p? Stage 2


// create a new dynamic integer variable // and set p to point to the variable

p Stage 3

p = new int; *p = 25; What happens if p=&i;


4

Example using automatic variables


Stage 1 int *p;
// create a new dynamic integer variable

p? Stage 2

// and set p to point to the variable p = new int; *p = 25;

p Stage 3 p Stage 1 i Stage 2 p Stage 3 p i


5

int i; int *p = &i; *p = 25;

Example using dynamic variables


Here is a dynamic array:
int* myArray = new int[arraySize]; Specified during program execution

We can use the new operator to dynamically allocate an object of any type, i.e.,
char* myInit = new char; Point* ptr = new Point;

Object of type Point myInit Object of type char ptr

x y

LINKED LIST

Lets consider the following problem


Write a program for a big company that can store information regarding the salaries of its employees.
Step 1: You have to decide how you will store the data in the computer. Option 1: use an array data structure item SalaryData[N]; What happens if you want to hire/fire someone? Indicate entries as not valid =>Waste of memory Create a new array =>Time consuming Computer Memory John Smith 35,000 Alex Green 45,000 Ken Sedcole 38,000

Is there a better solution?


8

Lets see the problem again


Main problem: In an array, we store information sequentially: => one data is stored after the other
Computer Memory Using an array data structure Computer Memory John Smith 35,000 Alex Green 45,000 Ken Sedcole 38,000 Lets not store the data sequentially John Smith 35,000 link Alex Green 45,000 link Ken Sedcole 38,000 link
9

but how can you access the data? Link the data together

A Linked list
A linked list is a dynamic data structure that can grow and shrink during program execution, so you can use as much memory as you need.
Computer Memory Delete operation John Smith 35,000 link Alex Green 45,000 link Ken Sedcole 38,000 link Computer Memory John Smith 35,000 link Alex Green 45,000 link Ken Sedcole 38,000 link
10

Is a linked list the answer to everything?

What are the advantages of a linked list? Use as much memory as you need Computational efficient to add/delete data

What are the disadvantages of a linked list? Memory overhead. Store of extra information Slow access of the data. You have to traverse the list

11

Linked Lists
A building block of a linked list is a block of memory that has two items: data stored in the list, and a pointer to the rest of the list. A linked list is a set of building blocks where one block points to the next. The start of the list, called head, is a pointer that points to the first element of the list. In other words, a linked list is an element followed by a linked list. So linked lists are recursively defined structures, in other words they are defined in terms of themselves. Finally, theres a special linked list: the empty list. This is usually represented by a special pointer, the null pointer. The end of the list is indicated by the null pointer. A linked list that stores a list of characters: CAT.

12

Uses of Linked Lists


Linked lists are absolutely everywhere in almost all large application programs. If things are created and destroyed during a programs execution, there is usually a dynamic data structure involved a linked list or something very similar. Some obvious examples include, The set of open windows on your computers desktop. The set of files inside a folder. The text being typed into a window, which would typically be stored as a list of blocks of characters. But there are many more hidden examples temporary internal structures created during a programs execution.

13

Another example of a linked list


This depicts a linked list holding a sequence of numbers: 87, 42, 53, 4.
87 53

42

Each node includes: A container for individual data structure A link to next node in the chain

/ used to signify there are no more elements in list

14

Declare a linked list in C++


The structure of a node in a linked list is implemented as struct in C++
member are used to hold data contents of node a pointer to next member in list, i.e. data member contains variable of type Node*

Example:
struct Node { int data; Node* next; };

data

next

15

Linked lists in C++


Lets see how to create a linked list with ONE integer. The steps are: 1. Declare the data type for a node 2. Declare a pointer to the head of the linked list
struct Node { int data; Node* next; }; Node* hdList; hdList = new Node; hdList->data = 20; hdList->next = NULL;

3. Create the first node as a dynamic variable using the new operator
4. Fill in the data for the node 5. Make the next pointer pointing to null, denoting the end of the list
hdList 20

NULL
16

A better version
Better to use typedef to make the data type more abstract and hence easier to change in the future. In this case, the integer data element is defined a type named Item. We also define a type named NodePtr as pointer to a Node. typedef int Item; struct Node { Item data; Node* next; }; typedef Node* NodePtr; NodePtr hdList = new Node; hdList->data = 20; hdList->next = NULL;

hdList

20

NULL

17

Abstract Data Types (ADT)


The idea of an abstract data type (ADT) is that the underlying implementation of the data structure is invisible to the procedures that use it. All they see are a number of predefined functions for manipulating it. An example of ADT is the data type int. Why? The aim is programmer-defined types to be ADTs.

18

Lists as an ADT
Linked lists, as well as being an example of a dynamic data structure, are also an example of an abstract data type. An abstract data type (ADT) is one whose underlying implementation is invisible to the procedures that use it. Instead, they manipulate the data structure via a number of predefined functions and routines, known as access routines. Access routines come in two main varieties:

those for constructing data structures,


and those for accessing their parts. Let us first consider the access routine that adds an item to the list.

19

The Heap
At run-time, every program maintains an area of memory known as the heap. Dynamic data structures, such as linked lists, inhabit the heap. The heap comprises an area of allocated memory and an area of free memory. To grow a data structure to add an element to a list, for example the program grabs a piece of free memory, and allocates it to the new element. When a data structure shrinks when an element is deleted from a list, for example the memory allocated to that element becomes free again. In this way, the memory used up at any time while a program is running is exactly the amount the program needs, and no more.
20

Allocated Memory
C A T

Free Memory

10

Heap

10 ??

??

NULL

hdList

NodePtr hdList; hdList = new Node; hdList -> data = 10; hdList -> next = Null;

21

Add an element to the head of the list


hdList
12

NULL
45 93

newNode

?? ??

hdList
12

NULL
45 93

newNode

37

hdList newNode

NULL
12 45 93

37

22

11

Access routines to build the list


addToList takes two parameters: the number to add, and a pointer pointing to the head of the list.

On exit, hdList will be pointing to a new node. Therefore it must be passed to the function by reference, hence the & in front of hdList. Is the new item added to the beginning (i.e. head) or the end (i.e. tail) of the linked list?
Do I have a memory leak here?

23

Build a list of szList items


The function buildList will create a linked list of szList nodes and return a pointer hdList that points to the head of the list. The items are generated randomly in the routine getItem(). firstTime is used to detect when getItem() is first called and randomize() is invoked for the random number generator. If DEBUG is true, the random numbers are displayed on the console as they are generated.
24

12

Access routine to read the data


getFromList() extracts one item from the head of the list and than return the its value. In addition, it also return a new pointer pointing to rest of the list NOT include the returned item. printAll() displays on the console ALL the items stored in the entire linked list. It terminates when the next pointer is pointing to NULL (i.e. empty). Why is it better NOT to combine these two routines into one? In what order is the list printed?
25

Putting these together


Here is the very clear and clean main program. However, this program has a memory leak, i.e. it create dynamic memory to store 4 items, and these are never returned even after the items are taken from the list. To fix this problem, getFromList() is modified to delete the node immediate after it is extracted from the list.

Important: You do not delete the pointer, you delete the space where this pointer points to. How does the program know how many bytes to delete?

26

13

Maintaining the Heap


To ensure that space on the heap is not wasted, redundant structures should be taken apart, and the space they occupy should be made available again. In C++, the delete operator is used to return unwanted memory back to the heap. As an alternative to the previous slide heres a function that destroys the list that we have created.
void destroyList (NodePtr hdList) { NodePtr nowPtr; while (hdList != NULL) { nowPtr = hdList; hdList = hdList->next; delete nowPtr; } }
27

What to do before the next lecture?


Read first part of Chapter 15.1 of Savitch

28

14

Вам также может понравиться