Você está na página 1de 5

CSE211 Lecture Notes – 2004/2005-II CSE211 Lecture Notes – 2004/2005-II

CSE 211: Data Structures Nodes


Each node of a list consists of two parts. The first part holds the data. The first part holds the data. The
Lecture Notes VII data can be a simple variable or, more generally a structure ( or pointer to a structure) of some type.
by The second part is a pointer that indicatesthe location of the next node of the list. The nodes of a list
Ender Ozcan, Sebnem Baydere can be implemented by a recursive structure.
Consider the case where a single integer varaible is to be stored at each node of the list.
LINKED LISTS
In the previous lectures we have seen the representation of ordered lists using an array and sequential struct simplenode { class simplenode {
mapping. These representations had the property that successive nodes of the data object were stored int item; int item;
in a fixed distance apart.
For example : If the element aij of a table was stored at location Lij then a ij+1 was at the location Lij+c struct simplenode *next;}; simplenode *next; ... };
for a known constant c. typedef struct simplenode simple_t;
Problems :
• The sequential storage schemes are adequate if one wished to access for given node in a table, In this case the integer variable item holds the actual data in each node, and the pointer variable next
insertion or deletions of nodes within a stack or queue. However insertions or deletions of arbitrary holds the address of the next node.
elements become expensive.
• If we have several ordered lists of varying sizes, by storing each list in a different array of item next
maximum size, storage may be wasted. Additionally, in several cases we will need more than
accessing the top item as in the stacks or inserting to the tail and accessing the head (queues). We
need more general operations such as finding or removing any item in the list, inserting a new item
at any point. In general, the item part may contain several pieces of data defined in a strcut type. We can generalize
Solution: the list definition above as:
The problem of data movement in sequential representations may be solved by using linked
representations and dynamic memory allocation. Unlike a sequential representation where successive
items of a list are located a fixed distance apart, in a linked representation each item of the list may be struct generalList { template <class infoType>
placed anywhere in memory. To access elements in the list in the correct order, with each element we infoType item; class generalList {
store the location of the next element in that list. Associated with each data item in a linked struct generalList *next; }; infoType item;
representation there is a pointer to the next item. typedef struct generalList glist_t; generalList *next;
...
};
In modern languages providing built- in support for linked structures, the compiler associates a special
storage with an object program which it leaves initially unassigned to any program variable. This area We assume that info_type has been defined before.
is usually called the heap or the dynamic storage pool. There is a heap manager program for the The problem with this kind of implementation is that for each type of list you must assign the
allocation of this storage from the heap at execution time. The allocated space can be referenced using individual components one by one when transfering information to and from the nodes.
pointers. Remember that pointer is just an abstraction for a machine address.
Ex. if s1 and s2 are both structures. In C, you cannot say s1=s2. You can assign only a single structure
Linked List Building Blocks: A linked list is an ordered sequence of elements called nodes. A list has a component in each statement. You can however write a function called assign and call it whenever
beginning, or head and an end , or tail. Every node on the list is the same type, although that type can needed.
take different forms.
assign(s1,s2);
A central property of linked lists is their dynamic nature. Nodes can be added to or removed from a list info_type s1,s2;
at any time. Because the number of nodes cannot be predicted before run time. You should use {
pointers, rather than arrays, to achieve an efficient and reliable implementation. /* assign each component of struct 2 to struct 1 */
}
CSE211 Lecture Notes – 2004/2005-II CSE211 Lecture Notes – 2004/2005-II
This function carries out the detailed transfer of the individual structure components from 21 to s1. struct head{ template <class infoType>
You can then build a series of generic list manipulation functions that use assign. int length; class LinkedList{
node_type *first, *last; } int length;
The problem with this approach is the performance. You will be transfering data among different Node<infoType> *first,*last;
memory locations. However you only need to transfer the address of the blocks of data corresponding typedef struct head head_type; int insert(infoType *data)
to the structures. int append(infoType *data)
int delete(Node *ptr) … }
Solution: use a structure composed of a pair of pointers. The first pointer points to the data, the second
points to the next item.
If a symmetric header is used:
template <class infoType>
struct node { class Node {
infoType * item; infoType * item;
struct node *next; }; Node *next;
typedef struct node node_type; ...
};
If a custom head is used: (length, last, first)
item next
Manipulation of Linked Lists
Operations on One-way Lists and their Implementations
The manipulation of linked lists involves allocating storage for nodes (in C using malloc) and
assigning data and/or pointers so that the list is properly formed. List's boundary conditions must be Allocating Memory
decided. In other words how are the head and tail of a list will be indicated. For the representation of When an array is defined, storage is automatically allocated by the compiler. When you are using
the tail NULL pointer can be used (show it on the example) but for the head different approaches are pointers, however you must allocate the storage. In C, two standard library functions are provided for
possible. this purpose.
• Define a pointer variable to hold the starting adress of the list. malloc--- allocates a single piece of storage space and leaves it uninitialized
• Define a special header node with the same structure. In this case the next element of the header calloc() -- allocates entire set of storage locations and fills the total storage with zero
node indicates the beginning of the list. (item part is unused - a small waste)
• Define a header node with a separate structure which holds exactly the information required. In this char *malloc(size) -------- allocates size number of bytes and returns a pointer to the first
case other information related to the list such as number of elements in the list can be added to the
header. Although it returns a character pointer it can be used to allocate space for any type of element not just
characaters by applying a simple type casting
Size is the value returned by the sizeof operator
• sizeof expression
sizeof(type name)
CSE211 Lecture Notes – 2004/2005-II CSE211 Lecture Notes – 2004/2005-II
B) Inserting a new element at the beginning of a list
• Type casting : new_variable = (type_name) old_variable 1. Allocate memory for the new node and set it (if possible)
2. Link the first pointer of header to the new node (?last)
We will define a fucntion called MALLOC and use it in the algorithms 3. Increment length by 1
int insert_node (info_type *data, head_type *list) {
#define MALLOC(x) ((x *) malloc(sizeof(x))) node_type *new_node;
if (new _node = alloc_node(data, list->first)) {
float *place; /* A float pointer */ list->first = new_node; /* link in new node */
if (list->length == 0) /* if this is the first node */
place = (float *) malloc (sizeof(float)); list-> last = new_node; /* set last pointer to new */
place = MALLOC(float); list->length ++;
return(1); /* success */
place = new float[1]; } else return(0); /* error */ }
Creating a new list Appending a new item to the end of a list
1. allocate memory for header node
2. set length to 0 Another common operation appends a new item to the end of a list. The before and after situations are
3. set first and last nodes to NULL diagrammed below. You know where to find the current last node in the list by means of the last
pointer, which is maintained in the header block. Thus you only need to allocate me mory for a new
head_type *create(){ node and rearrange pointers accordingly.
head_type *new_node;
if (new _node = MALLOC(head_type) ) { int append (info_type *data, head_type *list) {
new_node ->length = 0; node_type *new_node;/* append data to end of list */
new_node -> first = new_node -> last = NULL; if (new_node=alloc_node(data, NULL){
} /* allocation OK, append data item */
return(new _node); /* adress of new list */ if (list -> length) /* if the list is not empty */
} list->last->next = new_node; /* link in new node */
else /* otherwise */
Inserting a new element at the beginning of a list list->first = new_node; /* set first pointer to new */
A) Create a storage for the new node list -> last = new_node; /* update last pointer */
list -> length++; /* update list length */
1. Create storage for a new list node;
return(1); /* success */
2. Assign appropriate pointer values to the new node } else /* allocation problem */
3. Assign new values to the components of the header node. return(0); /* error*/ }
Example given at the lecture.
/* create a storage for the new node */
node_type *alloc_node(info_type * val, node_type * ptr)
{ BEFORE:
node_type *new_node;
if (new_node = MALLOC(node_type)) {
new_node -> item = val;
new_node -> next = ptr;}
return(new_node);
} AFTER:
CSE211 Lecture Notes – 2004/2005-II CSE211 Lecture Notes – 2004/2005-II
Operations on Doubly Linked Lists (Two-Way Lists)
Deleting Nodes Study yourself.
Create operation
Doubly Linked Lists
Finding the predecessor of a node in a one-way list requires a linear search. We can add a pointer to its head_db_type *create_db()
predecessor, to each node. It will consume more space but search will be faster. Sometimes you may {
need to move through a list from the end to the beginning by following pointers. Inorder to be able to head_db_type *new_node;
/* attempt to allocate memory */ DoublyLinkedList(){
do this we can define two pointers in each node; first = NULL;
One points to the next and one points to the previous node. if (new_node =MALLOC(head_db_type)) {
/* allocation OK, initialize the values */ last = NULL;
new_node -> length = 0; length = 0;
new_node -> first = NULL; }
new_node ->last = NULL; }
/* return the address of the new list */
return(new_node);
Length Last First Previous Item Next }
(HEADER ) (NODE)
We also need to write a function which creates a new node.
/* create a storage for the new doubly linked node */
doubly_type
*alloc_db_node(val, prev, next) doubly( info_type *val,
info_type *val; doubly *prv,
doubly_type *prev, *next;{ doubly *nxt)
doubly_type *new_node; {
if(new_node=MALLOC(doubly_type)) item = val;
{ prev = prv;
(a doubly linked list) next = nxt;
new_node -> item = val;
new_node -> prev = prev; }
For doubly linked lists, you need to develop a new set of routines that are analogous to those for new_node -> next = next; }
ordinary (singly linked) lists. The function to create a new doubly linked list is nearly the same as that return(new_node);
for singly linked lists, in that you have to change only the data types of the header pointers. }
Let us first define the doubly linked list node:
Using this function we can write insert and append functions:
/* Insert node at the beginning of a doubly linked list */
struct doubly{ template <infoType>
info_type *item class doubly{
struct doubly *next, *prev; infoType *item
} doubly *next, *prev;
typedef struct doubly doubly_type; ... }
Header Node: It does not need to change. We only need to change the type of pointers from node_type
to doubly_type.
CSE211 Lecture Notes – 2004/2005-II CSE211 Lecture Notes – 2004/2005-II
int insert_dbl ( info_type *data, Deleting first node from a doubly linked list
head_db_type *list ){
doubly_type *new_node; We assume that before calling the delete function you have checked the length of the list.
if (new_node = alloc_db_node(data, NULL, list->first)) { The function retiurns the data field of the deleted node and frees the memory used by this
if (list->length == 0) /* if this is the first node */ Node.
list->last = new_node; /* set the last pointer to the new */
else { /* if not the first node link it in */ info_type *del_dbl(head_db_type *list){
list->first->prev = new_node; /* set prev field of first node */ doubly_type *temp; info_type *data; /* delete first node */
list->first = new_node; /*set the first pointer to the new */ } temp= list->first; /* save the pointer */
list->length++; data = temp->item; /* save the data */
return(1); /* success */ list->first = temp->next; /* reassign the first pointer */
}else return(0); } /* error */ list->length--; /* update list length */
if (list->length ) /* if new list is not empty */
list->first->prev = NULL; /* set prev field of first item to NULL*/
else /* otherwise */
list->last = NULL; /* set last pointer to NULL */;
free((char )temp); /* free node storage */
return(data); }
Previous field of the first node is 0
Next field of the last node is 0
(before insertion)
(before deletion )
(after deletion)
(after insertion)
Append a node to the end of the list Home study-- do it yo urself

Você também pode gostar