1. Trang chủ
  2. » Công Nghệ Thông Tin

Absolute C++ (4th Edition) part 70 pdf

10 525 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 178,95 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

For example, if p1 points to a node n1, then the following creates a new node pointed to by p2 such that this new node has data 42 and has its link member pointing to n1: IntNodePtr p2 =

Trang 1

IntNode* getLink( ) const { return link; } int getData( ) const { return data; } void setData( int theData) { data = theData; } void setLink(IntNode* pointer) { link = pointer; } private :

int data;

IntNode *link;

};

typedef IntNode* IntNodePtr;

Note that all the member functions in the class IntNode are simple enough to have inline definitions

Notice the two-parameter constructor for the class IntNode It will allow us to create nodes with a specified integer as data and with a specified link member For example, if p1 points to a node n1, then the following creates a new node pointed to by p2 such that this new node has data 42 and has its link member pointing to n1:

IntNodePtr p2 = new IntNode(42, p1);

After we derive some basic functions for creating and manipulating linked lists with this node type, we will convert the node type and the functions to template versions so they will work to store any type of data in the nodes

As a warm-up exercise, let’s see how we might construct the start of a linked list with nodes of this type We first declare a pointer variable, called head, that will point to the head of our linked list:

IntNodePtr head;

To create our first node, we use the operator new to create a new dynamic variable that will become the first node in our linked list:

head = new IntNode;

We then give values to the member variables of this new node:

head->setData(3);

head->setLink(NULL);

Notice that the pointer member of this node is set equal to NULL because this node is the last node in the list (as well as the first node in the list) At this stage our linked list looks like this:

a one-node linked list

3

NULL

head

Trang 2

That was more work than we needed to do By using the IntNode constructor with two parameters, we can create our one-node linked list much easier The following is an easier way to obtain the one-node linked list just pictured:

head = new IntNode(3, NULL);

As it turns out, we will always create new nodes using this two-argument constructor for IntNode Many programs would even omit the zero-argument constructor from the definition of IntNode so that it would be impossible to create a node without specifying values for each member variable

Our one-node list was built in an ad hoc way To have a larger linked list, your pro-gram must be able to add nodes in a systematic way We next describe one simple way

to insert nodes in a linked list

In this subsection we assume that our linked list already contains one or more nodes, and we develop a function to add another node The first parameter for the insertion function will be a call-by-reference parameter for a pointer variable that points to the head of the linked list, that is, a pointer variable that points to the first node in the linked list The other parameter will give the number to be stored in the new node The function declaration for our insertion function is as follows:

void headInsert(IntNodePtr& head, int theData);

To insert a new node into the linked list, our function will use the new operator and our two-argument constructor for IntNode The new node will have theData as its data and will have its link member pointing to the first node in the linked list (before inser-tion) The dynamic variable is created as follows:

new IntNode(theData, head)

We want the pointer head to point to this new node, so the function body can simply be {

head = new IntNode(theData, head);

}

Display 17.3 contains a diagram of the action head = new IntNode(theData, head);

when theData is 12 The complete function definition is given in Display 17.4 You will want to allow for the possibility that a list contains nothing For example, a shopping list might have nothing in it because there is nothing to buy this week A list

with nothing in it is called an empty list A linked list is named by naming a pointer

that points to the head of the list, but an empty list has no head node To specify an

empty list

Trang 3

Display 17.3 Adding a Node to the Head of a Linked List

head

3

NULL

15

head

12

3

NULL

15

head

12

3

NULL

15

Linked list before insertion

Node created by new IntNode(12, head)

Linked list after execution of head = new IntNode(12, head);

Trang 4

empty list, you use the value NULL If the pointer variable head is supposed to point to the head node of a linked list and you want to indicate that the list is empty, then set the value of head as follows:

head = NULL;

Whenever you design a function for manipulating a linked list, you should always check to see if it works on the empty list If it does not, you may be able to add a special case for the empty list If you cannot design the function to apply to the empty list, then your program must be designed to handle empty lists some other way or to avoid them completely Fortunately, the empty list can often be treated just like any other list For example, the function headInsert in Display 17.4 was designed with nonempty lists as the model, but a check will show that it works for the empty list as well

L OSING N ODES

You might be tempted to write the function definition for headInsert (Display 17.4) using the zero-argument constructor to set the member variables of the new node If you were to try, you might start the function as follows:

head = new IntNode;

head->setData(theData);

At this point the new node is constructed, contains the correct data, and is pointed to by the pointer head —all as it is supposed to be All that is left to do is attach the rest of the list to this node by setting the pointer member in this new node so that it points to what was formerly the first node of the list You could do it with the following, if only you could figure out what pointer

to put in place of the question mark:

head->setLink(?);

Display 17.5 shows the situation when the new data value is 12 and illustrates the problem If you were to proceed in this way, there would be nothing pointing to the node containing 15 Since there is no named pointer pointing to it (or to a chain of pointers extending to that node), there is

no way the program can reference this node The node and all nodes below this node are lost A program cannot make a pointer point to any of these nodes, nor can it access the data in these nodes or do anything else to the nodes It simply has no way to refer to the nodes Such a situation ties up memory for the duration of the program A program that loses nodes is sometimes said to have a m meeeem m mooo m orrrryyy y lllleeeeaaa akkkk A significant memory leak can result in the program running out of memory and terminating abnormally Worse, a memory leak (lost nodes) in an ordinary user’s program can, in rare situations, cause the operating system to crash To avoid such lost nodes, the program must always keep some pointer pointing to the head of the list, usually the pointer in a pointer variable like head

memory leak

Trang 5

Display 17.4 Functions for Adding a Node to a Linked List

N ODE AND P OINTER T YPE D EFINITIONS

class IntNode {

public : IntNode( ){}

IntNode(int theData, IntNode* theLink) : data(theData), link(theLink){}

IntNode* getLink( ) const { return link; } int getData( ) const { return data; } void setData( int theData) { data = theData; } void setLink(IntNode* pointer) { link = pointer; } private :

int data;

IntNode *link;

};

typedef IntNode* IntNodePtr;

F UNCTION TO A DD A N ODE AT THE H EAD OF A L INKED L IST

F UNCTION D ECLARATION

void headInsert(IntNodePtr& head, int theData);

//Precondition: The pointer variable head points to //the head of a linked list.

//Postcondition: A new node containing theData //has been added at the head of the linked list.

F UNCTION D EFINITION

void headInsert(IntNodePtr& head, int theData) {

head = new IntNode(theData, head);

}

F UNCTION TO A DD A N ODE IN THE M IDDLE OF A L INKED L IST

F UNCTION D ECLARATION

void insert(IntNodePtr afterMe, int theData);

//Precondition: afterMe points to a node in a linked list.

//Postcondition: A new node containing theData //has been added after the node pointed to by afterMe.

F UNCTION D EFINITION

void insert(IntNodePtr afterMe, int theData) {

afterMe->setLink( new IntNode(theData, afterMe->getLink( )));

}

Trang 6

INSERTING AND REMOVING NODES INSIDE A LIST

We next design a function to insert a node at a specified place in a linked list If you want the nodes in some particular order, such as numerical or alphabetical, you cannot simply insert the node at the beginning or end of the list We will therefore design a function to insert a node after a specified node in the linked list

We assume that some other function or program part has correctly placed a pointer called afterMe pointing to some node in the linked list We want the new node to be placed after the node pointed to by afterMe, as illustrated in Display 17.6 The same technique works for nodes with any kind of data, but to be concrete, we are using the same type of nodes as in previous subsections The type definitions are given in Display 17.4 The function declaration for the function we want to define is given below:

void insert(IntNodePtr afterMe, int theData);

//Precondition: afterMe points to a node in a linked list.

//Postcondition: A new node containing theData //has been added after the node pointed to by afterMe.

The new node is inserted inside the list in basically the same way a node is added to the head (start) of a list, which we have already discussed The only difference is that we use the pointer afterMe->link instead of the pointer head The insertion is done as follows: afterMe->setLink( new IntNode(theData, afterMe->getLink( )));

Display 17.5 Lost Nodes

head

3

NULL

15

Linked list before insertion

head

12

?

3 NULL

15

Lost nodes

Situation after executing head = new IntNode;

head->setData(theData);

inserting in

the middle

of a list

Trang 7

Display 17.6 Inserting in the Middle of a Linked List

afterMe

head

2

9 3

18 NULL

5

afterMe

head

2

9 3

18 NULL

5

Node created by new IntNode(5, afterMe->getLink( ));

afterMe->getLink( )

is highlighted.

Final result of

afterMe->setLink(

new IntNode(theData, afterMe->getLink( )));

Trang 8

The details with theData equal to 5 are pictured in Display 17.6, and the final function definition is given in Display 17.4

If you go through the code for the function insert, you will see that it works cor-rectly even if the node pointed to by afterMe is the last node in the list However, insert will not work for inserting a node at the beginning of a linked list The function headInsert given in Display 17.4 can be used to insert a node at the beginning of a list

By using the function insert you can maintain a linked list in numerical or alpha-betical order or in some other ordering You can squeeze a new node into the correct position by simply adjusting two pointers This is true no matter how long the linked list is or where in the list you want the new data to go If you instead used an array, much, and in extreme cases all, of the array would have to be copied in order to make room for a new value in the correct spot Despite the overhead involved in positioning the pointer afterMe, inserting into a linked list is frequently more efficient than insert-ing into an array

Removing a node from a linked list is also quite easy Display 17.7 illustrates the method Once the pointers before and discard have been positioned, all that is required

to remove the node is the following statement:

before->setLink(discard->getLink( ));

This is sufficient to remove the node from the linked list However, if you are not using this node for something else, you should destroy the node and return the memory it uses for recycling; you can do this with a call to delete as follows:

delete discard;

As we noted in Chapter 10, the memory for dynamic variables is kept in an area of

memory known as the freestore Because the freestore is not unlimited, when a dynamic

variable (node) is no longer needed by your program, you should return this memory for recycling using the delete operator We include a review of the delete operator in the accompanying box

T HE delete O PERATOR

The delete operator eliminates a dynamic variable and returns the memory that the dynamic variable occupied to the freestore The memory can then be reused to create new dynamic vari-ables For example, the following eliminates the dynamic variable pointed to by the pointer variable p :

delete p;

After a call to delete , the value of the pointer variable, like p above, is undefined.

insertion at

the ends

comparison to

arrays

removing a

node

Trang 9

Display 17.7 Removing a Node

discard before

2

6 1

5

NULL

head

discard

before

2

6 1

3

5

NULL

recycled before->setLink(discard->getLink( ));

delete discard;

Trang 10

U SING THE A SSIGNMENT O PERATOR WITH D YNAMIC D ATA S TRUCTURES

If head1 and head2 are pointer variables and head1 points to the head node of a linked list, the following will make head2 point to the same head node and hence the same linked list:

head2 = head1;

However, you must remember that there is only one linked list, not two If you change the linked list pointed to by head1 , then you will also change the linked list pointed to by head2 , because they are the same linked lists.

If head1 points to a linked list and you want head2 to point to a second, identical copy of this linked list, the above assignment statement will not work Instead, you must copy the entire linked list node by node.

Next we will design a function to search a linked list in order to locate a particular node We will use the same node type, called IntNode, that we used in the previous sub-sections (The definitions of the node and pointer types are given in Display 17.4.) The function we design will have two arguments: the linked list and the integer we want to locate The function will return a pointer that points to the first node that contains that integer If no node contains the integer, the function will return NULL This way our program can test whether the int is in the list by checking to see if the function returns

a pointer value that is not equal to NULL The function declaration and header com-ment for our function are as follows:

IntNodePtr search(IntNodePtr head, int target);

//Precondition: The pointer head points to the head of a //linked list The pointer variable in the last node is NULL.

//If the list is empty, then head is NULL.

//Returns a pointer that points to the first node that contains the //target If no node contains the target, the function returns NULL.

We will use a local pointer variable, called here, to move through the list looking for the target The only way to move around a linked list, or any other data structure made up of nodes and pointers, is to follow the pointers Thus, we will start with here pointing to the first node and move the pointer from node to node, following the pointer out of each node This technique is diagrammed in Display 17.8

search

Ngày đăng: 04/07/2014, 05:21

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN