Worksheet 9: Linked List Introduction, List Stack - Data Structures | CS 261, Exams of Data Structures and Algorithms

Material Type: Exam; Class: DATA STRUCTURES; Subject: Computer Science; University: Oregon State University; Term: Summer 2006;

Typology: Exams

Pre 2010

Uploaded on 08/30/2009

koofers-user-lfq
koofers-user-lfq 🇺🇸

10 documents

1 / 4

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Worksheet 9: Linked List Introduction List Stack Name:
An Active Learning Approach to Data Structures using C
1
Worksheet 9: Linked List Introduction, List Stack
The Vector is not the only way to organize a collection. A weakness of the
Vector is that elements are stored in a contiguous block. As a consequence,
when a new element is inserted into the collection, all the adjacent elements
must be moved in order to make space for the new value.
An alternative approach is to use the idea of a
Linked List
. In a linked list each value is stored in a
separate block of memory, termed a
link
. In addition
to a value, each link contains a reference to the next
link in sequence. As a data structure, a link can be
described as shown at right.
We can visualize collection formed out of links as follows. A data field named
firstLink will hold the first link in the collection. Each link refers to the next. The
final link will have a null value in the next field:
The simplest data structure to create using links is a Stack. When a new element
is pushed on the stack a new link will be created and placed at the front of the
chain.
To remove a link the variable firstLink is simply changed to point to the next
element in the chain. The space for the Link is then freed.
struct link {
EleType value;
struct link * next;
};
pf3
pf4

Partial preview of the text

Download Worksheet 9: Linked List Introduction, List Stack - Data Structures | CS 261 and more Exams Data Structures and Algorithms in PDF only on Docsity!

Worksheet 9: Linked List Introduction, List Stack

The Vector is not the only way to organize a collection. A weakness of the Vector is that elements are stored in a contiguous block. As a consequence, when a new element is inserted into the collection, all the adjacent elements must be moved in order to make space for the new value. An alternative approach is to use the idea of a Linked List. In a linked list each value is stored in a separate block of memory, termed a link. In addition to a value, each link contains a reference to the next link in sequence. As a data structure, a link can be described as shown at right. We can visualize collection formed out of links as follows. A data field named firstLink will hold the first link in the collection. Each link refers to the next. The final link will have a null value in the next field: The simplest data structure to create using links is a Stack. When a new element is pushed on the stack a new link will be created and placed at the front of the chain. To remove a link the variable firstLink is simply changed to point to the next element in the chain. The space for the Link is then freed. struct link { EleType value; struct link * next; };

The following is the beginning of an implementation of a LinkedListStack based on these ideas. Complete the implementation. Each operation should have constant time performance. Use an assertion to ensure that when a top or pop is performed the stack has at least one element. When you pop a value from the stack, make sure you free the link field. struct link { EleType value; struct link * next; }; struct linkedListStack { struct link *firstLink; } void linkedListStackCreate (struct linkedListStack *s) { s->firstLink = 0; } void linkedListStackDestroy (struct linedListStack *s) { while (! linkedListStackIsEmpty(s)) linkedListStackPop(s); } void linkedListStackPush (struct linkedListStack *s, double d) { struct link * newLink = (struct link *) malloc(sizeof(struct link)); assert (newLink != 0); } double linkedListStackTop (struct linkedListStack *s) { } void linkedListStackPop (struct linkedListStack *s) { } int linkedListStackIsEmpty (struct linkedListStack *s) { }

An important principle of good memory management is “everybody must clean up their own mess”. (This is sometimes termed the kindergarden principle). The linked list allocates space for the link, and so must ensure that the space is freed by calling the associated pop routine. The user of the list allocates space for the data value, and must therefore ensure that the field is freed when no longer needed. When ever you create a dynamically allocated value you need to think about how and when it will be freed. The first paragraph of this lesson pointed out the problem involved in placing a new element into the middle of a vector (namely, that the following elements must then be moved). Linked lists will help solve this problem, although we have not yet demonstrated that in this lesson. For the vector we created a single general-purpose data structure, and then showed how to use that data structure in a variety of ways. In examining the linked list we will take a different approach. Rather than making a single data abstraction, we will examine the idea of the linked list in a variety of different forms. In subsequent lessons we will examine a number of variations on this idea, such as header or sentinel links, single versus double links, maintaining a pointer to the last as well as the first link, and more. Occasionally you will find links placed directly into a data object. For example, suppose you were creating a card game, and needed a list of cards. One way to do this would be the following: Each card can then be used as a link in a linked list. Although this approach is easy to implement, it should be avoided, for several reasons. It confuses two issues, the management of cards, and the manipulation of the list. These problems should be dealt with independently. It makes your code very rigid; for example, you cannot move the Card abstraction to another program in which cards are not on a list, or must be placed in two different lists at the same time. And finally, you end up duplicating code that you can more easily write once and reuse by using a standard container. struct Card { int suit; int rank; struct Card * next; // link to next card };