Sei sulla pagina 1di 10

Linked Lists

Problems with using arrays to keep lists of data


1. Predefined size, many languages have arrays that are fixed at compile time
(static)
If you choose an array size that is too small, you may need to later increase the
array size and recompile the program. Choose an array size that is too large will
waste space.
2. Insertion and deletion of elements to maintain order requires
- processing time to "make room" or "close the hole"
- special handling of unused elements

Advantages of array implementation of lists

 direct access to any element


 relatively easy programming

Linked lists

 provide a way to maintain an ordered list structure


 relatively easy insertion and deletion capability
 dynamic (memory allocation)

Node organization
Basic element of a linked list is a "record" structure of at least two fields (a class
definition with these instance variables). The object that holds the data and refers to
the next element in the list is called a node.

data next ptr


data component may actually be several fields or instance variables of any
complexity

next ptr is a reference to the next element in the structure. There can be multiple
reference fields but we won't consider that now. pointer/reference/link are
synonymous in this discussion.

Example
insertion of the value 8 into the above list (middle of the list)
Insertion
of the value 2 (at the head/beginning of the list)

Insertion
of the value 19 (at the tail of the list)
Deletion
of the value 7

Definition of a node class


Because a linked list is recursive in nature, we need a structure to manage the node as
well as the data to be contained in the node. We will typically use a feature of Java
called inner classes (a class that is defined within a class).

1. Define the instance variables to hold data and refer to the next node in the list.
2. Define a null node constructor (default).
3. Define a non-empty node constructor; this requires a link to the next node
passed as a parameter

private class Node extends Object{


private Object value;
private Node next;
private Node(){
value = null;
next = null;
}
private Node(Object value, Node next){
this.value = value;
this.next = next;
}
}

Creating elements
An empty node:

Node aNode = null; //not the same as the default constructor

A node containing data but doesn't point to anything; a single node list.

Node singleNode = new Node ("datum", null);

A list with two elements.

Node head = new Node("first", singleNode);

Recommendation: DRAW PICTURES! Draw the nodes and links from for the
above three statements.
Null pointer exceptions
You may have already seen this error. It arises when you have a reference variable
that really isn't referencing anything (as in aNode above).

For example the code aNode.next would throw the null pointer exception. There is
no object to which you can refer a next
temp = new NodeType;
temp->data = 450;
temp->next = NULL;
head->next = temp;

cout << head->data; //what does this print?

cout << head->next->data; //what does this print?

Traversing an existing list


void Traverse(NodePtr head)
for (temp = head; temp;
{
temp = temp->next)
temp = head;
cout << temp->data << endl;
while (temp != NULL) {
cout << temp->data << endl;
temp = temp->next;
}
}
void Traverse(NodePtr head)
{
if(head == NULL) return;
cout << head->data << endl;
Traverse (head->next);
}

Implementation file echocity.cpp as linked list example.

Inserting a new Node


3 points of insertion must be considered:

1. as the first element, requires updating the head pointer


2. in the middle of an existing list
3. at the end of the list

void LLinsert(NodePtr& head, int void LLinsert(NodePtr& head, int


value) value)
{ {
NodePtr prev; if(head == NULL){
NodePtr temp; temp = new NodeType;
NodePtr cur = head; temp->data = value;
temp = new NodeType; temp->next = head;
temp->data = value; head = temp;
while( cur &&cur->data < value){ return;
prev = cur; }
cur = cur->next; if(head->data < value){
} LLinsert(head->next,value);
if(cur == head){ //new first value } else {
temp->next = head; temp = new NodeType;
head = temp; temp->data = value;
} else { //middle or last value temp->next = head;
temp->next = prev->next; head = temp;
prev->next = temp; return;
} }
} }
void LLinsert(NodePtr& head, int
value)
{
if(head == NULL
|| head->data > value){
temp = new NodeType;
temp->data = value;
temp->next = head;
head = temp;
} else {
LLinsert(head->next,value);
}
}

Deleting a node
void LLdelete(NodePtr& head, int
value)
{
NodePtr prev;
NodePtr cur = head;
void LLdelete(NodePtr& head, int
value)
while(cur && cur->data != value){
{
prev = cur;
if(head == NULL) return;
cur = cur->next;
}
if(head->data == value){
if(cur == NULL) return; //not
NodePtr cur = head;
found
head = head->next;
delete cur;
if(cur == head){ //delete first
} else {
value
LLdelete(head->next,value);
head = cur->next;
}
} else { //delete middle or end
}
value
prev->next = cur->next;
}
delete cur;
}
Head Nodes
Managing the insertion and deletion of the first element is a special case, especially in
non-recursive solutions.

The middle and last elements are similar in management.

This special case handling can be eliminated by creating a special "head node"

 allocated like a regular node


 store no data in it
 head points to it, and the head node points to the first element of the list

void LLinsert(NodePtr head, int value) //no reference params needed


{
NodePtr prev = head;
NodePtr temp;
NodePtr cur = head->next;

temp = new NodeType;


temp->data = value;

while(cur && cur->data < value){


prev = cur;
cur = cur->next;
}
temp->next = prev->next;
prev->next = temp;
}
}

Trade a little space for improvement in program time.


What does temp->next->data refers to in linked list c
programing?
Linked list is a linear data structure, they have nodes which contain address of the next (and
sometimes previous) node and some data. They are similar to arrays except that any index
can’t be accessed directly, you have a head node which is the starting node of the list and
you iterate to the index using address of next node stored in the current node. (node->next)

In your case (assuming that node is defined such that next contains address of next node
and data contains data in the current node) temp is the current node, temp->next refers to
the next node of the linked list, temp->next->data refers to the data in the next node of the
linked list. This may change if the node is defined

I'm reading up on linked lists here and I'm kind of confused. I've drawn it out but it still looks
like they are the same thing.
Traversing through a linked list:

Node tmp = head;


while(tmp != null) {
tmp = tmp.next;
}
My thought process for the while loop: tmp starts at head. Now while tmp points to a next
node, tmp moves on to pointing to the node next to it. And it goes on until tmp is not
pointing to another node next to it.

Adding to the end of a linked list:

public void addLast(AnyType item)


{
if(head == null) addFirst(item);
else
{
Node<AnyType> tmp = head;
while(tmp.next != null)
tmp = tmp.next;

tmp.next = new Node<AnyType>(item, null);


}
}
My thought process for the while loop: tmp starts at head. Now while tmp points to a next
node, tmp moves on to pointing to the node next to it. And it goes on until tmp is not
pointing to another node next to it. Then it breaks out of the loop and assigns tmp to point
next to a new Node.

Potrebbero piacerti anche