2006 Pearson Education, Inc. All rights reserved. 1 21 Data Structures.

65
1 2006 Pearson Education, Inc. All rights rese 2 1 Data Structures
  • date post

    21-Dec-2015
  • Category

    Documents

  • view

    214
  • download

    0

Transcript of 2006 Pearson Education, Inc. All rights reserved. 1 21 Data Structures.

1

2006 Pearson Education, Inc. All rights reserved.

2121

Data Structures

2

2006 Pearson Education, Inc. All rights reserved.

21.2 Self-Referential Classes

• Self-referential class– Contains a pointer member that points to an object of the

same class type

– Example• Class Node{ … Node *nextPtr;};

– Pointer data member nextPtr is a link

• Can tie a Node to another Node

3

Fig. 21.1 | Two self-referential class objects linked together.

4

2006 Pearson Education, Inc. All rights reserved.

21.3 Dynamic Memory Allocation and Data Structures

• Dynamic memory allocation– Enables a program to obtain more memory at execution

time• That memory can be released when it is no longer needed

– Limited by amount of physical or virtual memory• Memory must be shared among many programs

Common Programming Error 21.1

Not setting the link in the last node of a linked data structure to null (0) is a (possibly fatal) logic error.

6

Lets look at lists:

Using Arraysfixed sizeMust shift to add something to the front or delete the first element (or anywhere in the middle)

Easy to add at the endUsing Vectors

Not fixed sizeStill have to shift to add something

To add an element, one has to shift everything over

8

complexity

To add an element to a list of size n: O(n)

To delete an element to a list of size n: O(n)

Shifting is an expensive operation since it involves a copy. Not practical for large lists!

Can we do something else?

9

2006 Pearson Education, Inc. All rights reserved.

21.4 Linked Lists

• Linked list– Linear collection of self-referential class objects

• Called nodes

• Connected by pointer links

– Accessed via a pointer to the first node• Subsequent nodes are accessed via previous node’s link

– By convention, link in last node is set to null pointer 0

– Additional nodes are dynamically allocated as necessary

10

2006 Pearson Education, Inc. All rights reserved.

21.4 Linked Lists (Cont.)

• Linked list (Cont.)– Advantages over arrays

• Linked lists are dynamic

– Length can increase or decrease as necessary

• Efficient insertion of new elements into a sorted list

– Existing list elements do not need to be moved

Performance Tip 21.1

An array can be declared to contain more elements than the number of items expected, but this can waste memory. Linked lists can provide better memory utilization in these situations. Linked lists allow the program to adapt at runtime. Note that class template vector (introduced in Section 7.11) implements a dynamically resizable array-based data structure.

Performance Tip 21.2

Insertion and deletion in a sorted array can be time consuming—all the elements following the inserted or deleted element must be shifted appropriately. A linked list allows efficient insertion operations anywhere in the list.

Performance Tip 21.3

The elements of an array are stored contiguously in memory. This allows immediate access to any array element, because the address of any element can be calculated directly based on its position relative to the beginning of the array. Linked lists do not afford such immediate “direct access” to their elements. So accessing individual elements in a linked list can be considerably more expensive than accessing individual elements in an array. The selection of a data structure is typically based on the performance of specific operations used by a program and the order in which the data items are maintained in the data structure. For example, it is typically more efficient to insert an item in a sorted linked list than a sorted array.

Performance Tip 21.4

Using dynamic memory allocation (instead of fixed-size arrays) for data structures that grow and shrink at execution time can save memory. Keep in mind, however, that pointers occupy space and that dynamic memory allocation incurs the overhead of function calls.

alice barney batman robin superman

1st element 2nd element 3rd element 4th element 5th element

To add an element named “powerranger”

alice barney batman robin superman

powerranger

A graphical representation of a linked list

HeadOfList

To delete alice

alice barney batman robin superman

powerranger

HeadOfListHeadOfList

17

Fig. 21.2 | A graphical representation of a list.

18

Using Self Referential classes

Same as structs!

19

int main()

{

ListNode n1(5);

ListNode n2(4);

n1.nextPtr = &n2;

n2.nextPtr = new ListNode (7);

ListNode *pp;

pp= &n1;

for(int I = 0; i<2; i++) {

pp=pp->nextPtr;

cout <<pp->getData() <<endl;

}

class ListNode {public: ListNode( const int & ); // constructor int getData() const; // return data in

node// everything is public for this example int data; // data ListNode *nextPtr; // next node in list}; // end class ListNode

ListNode::ListNode( const int &info ) : data( info ), nextPtr( 0 ) { // empty body } // end ListNode

constructor

int ListNode::getData() const { return data; } // end function getData

20

int main(){ListNode *p1,* p2*,p3;p1= new ListNode (7);P1->nextPtr=new ListNode(5);P3 = new ListNode(6);P3->nextPtr=p1;ListNode *pp=p3;for(int I = 0; i<2; i++) {cout <<pp->getData() <<endl; pp=pp->nextPtr;;}

21

Int data

ListNode *nextPtr

Holds an address of a ListNode

int main()

{

ListNode n1(5);

ListNode n2(4);

n1.nextPtr = &n2;

n2.nextPtr = new ListNode (7);

ListNode *pp;

pp= &n1;

for(int I = 0; i<2; i++) {

pp=pp->nextPtr;

cout <<pp->getData() <<endl;

}

22

Have a class

That includes the listnode class and that has all the functions of a list:

insertAtFront

insertAtBack

removeFromFront

RemoveFromBack

Etc….

23

Problem: Listnode has everything public

Let the new class LIST be a friend of listnode and make listnode private.

24

class List; class ListNode { friend class List; // make List a friendpublic: ListNode( const int & ); // constructor int getData() const; // return data in nodeprivate: int data; // data ListNode *nextPtr; // next node in list}; // end class ListNode

ListNode::ListNode( const int &info ) : data( info ), nextPtr( 0 ) { // empty body} // end ListNode constructor

int ListNode::getData() const { return data; } // end function getData

File: ListNode.h

NOTE FORWARD DECLARATION HERE SO that when the statement “friend class List” is encountered the compiler knows that the definition for class List will be coming…..

25#include <iostream>using std::cout;#include "ListnodeINT.h" // ListNode class definition

class List {public: List(); // constructor ~List(); // destructor void insertAtFront( const int & ); void insertAtBack( const int & ); bool removeFromFront( int & ); bool removeFromBack( int & ); bool isEmpty() const; void print() const;private: ListNode *firstPtr; // pointer to first node ListNode *lastPtr; // pointer to last node -- optional

// utility function to allocate new node ListNode *getNewNode( const int& );}; // end class List

26

constructor

List::List()

: firstPtr( 0 ), lastPtr( 0 )

{

// empty body

} // end List constructor

27

isempty

bool List::isEmpty() const

{

return firstPtr == 0;

} // end function isEmpty

28

ListNode getnewNode(const in &value)

ListNode *List::getNewNode(const int &value )

{

return new ListNode( value );

} // end function getNewNode

29

insertAtFront(const int &value)

void List::insertAtFront( const int &value ){ ListNode *newPtr = getNewNode( value ); // new

node

if ( isEmpty() ) // List is empty firstPtr = lastPtr = newPtr; // new list has only one

node else // List is not empty { newPtr->nextPtr = firstPtr; // point new node to

previous 1st node firstPtr = newPtr; // aim firstPtr at new node } // end else} // end function insertAtFront

30

insertAtBack

void List::insertAtBack( const int &value ){ ListNode *newPtr = getNewNode( value ); // new node

if ( isEmpty() ) // List is empty firstPtr = lastPtr = newPtr; // new list has only one

node else // List is not empty { lastPtr->nextPtr = newPtr; // update previous last

node lastPtr = newPtr; // new last node } // end else} // end function insertAtBack

31

bool removeFromFront(int &value)

bool List::removeFromFront( int &value ){ if ( isEmpty() ) // List is empty return false; // delete unsuccessful else { ListNode *tempPtr = firstPtr; // hold tempPtr to delete

if ( firstPtr == lastPtr ) firstPtr = lastPtr = 0; // no nodes remain after removal else firstPtr = firstPtr->nextPtr; // point to previous 2nd node

value = tempPtr->data; // return data being removed delete tempPtr; // reclaim previous front node return true; // delete successful } // end else} // end function removeFromFront

32

removeFromBackbool List::removeFromBack( int &value ){ if ( isEmpty() ) // List is empty return false; // delete unsuccessful else { ListNode *tempPtr = lastPtr; // hold tempPtr to delete

if ( firstPtr == lastPtr ) // List has one element firstPtr = lastPtr = 0; // no nodes remain after removal else { ListNode *currentPtr = firstPtr;

// locate second-to-last element while ( currentPtr->nextPtr != lastPtr ) currentPtr = currentPtr->nextPtr; // move to next node

lastPtr = currentPtr; // remove last node currentPtr->nextPtr = 0; // this is now the last node } // end else

value = tempPtr->data; // return value from old last node delete tempPtr; // reclaim former last node return true; // delete successful } // end else} // end function removeFromBack

33

print

void List::print() const{ if ( isEmpty() ) // List is empty { cout << "The list is empty\n\n"; return; } // end if

ListNode *currentPtr = firstPtr;

cout << "Am at print The list is: ";

while ( currentPtr != 0 ) // get element data { cout << currentPtr->data << ' '; currentPtr = currentPtr->nextPtr; } // end while

cout << "\n\n";} // end function print

34

Using the list in a main program

Can use the same program as before with the array list!!!!!

35

#include “ListI.h”int main(){

List alist; bool success;alist.insertAtFront(1);alist.insertAtFront(2);alist.insertAtFront(3); //list is 3 2 1alist.insertAtBack(4); //list is now 3 2 1 4alist.print();int a[100];alist.copylisttoarray(a);for (int i= 0; i< 4; i++) cout <<a[i];

36

An example of data hiding

The list is an abstract data type --- the implementation can be hidden from its use!

37

Write a menu based main program which asks the user what they want to do with the list and then performs that action…..

38

What happens with this code?

int main(){ // test List of int values List integerList; List int2list; for (int i = 0; i < 10; i++) integerList.insertAtFront(i);

int2list = integerList;

cout << "testing original" << endl; integerList.print(); cout << "testing copy" << endl; int2list.print();

integerList.insertAtBack(11); cout << "testing original" << endl; integerList.print(); cout << "testing copy" << endl; int2list.print();}

39

List with Templates

40

2006 Pearson Education, Inc. All rights reserved.

1 // Fig. 21.3: Listnode.h

2 // Template ListNode class definition.

3 #ifndef LISTNODE_H

4 #define LISTNODE_H

5

6 // forward declaration of class List required to announce that class

7 // List exists so it can be used in the friend declaration at line 13

8 template< typename NODETYPE > class List;

9

10 template< typename NODETYPE>

11 class ListNode

12 {

13 friend class List< NODETYPE >; // make List a friend

14

15 public:

16 ListNode( const NODETYPE & ); // constructor

17 NODETYPE getData() const; // return data in node

18 private:

19 NODETYPE data; // data

20 ListNode< NODETYPE > *nextPtr; // next node in list

21 }; // end class ListNode

22

23 // constructor

24 template< typename NODETYPE>

25 ListNode< NODETYPE >::ListNode( const NODETYPE &info )

26 : data( info ), nextPtr( 0 )

27 {

28 // empty body

29 } // end ListNode constructor

Outline

Listnode.h

(1 of 2)

Member data stores a value of type parameter NODETYPE

Member nextPtr stores a pointer to the next ListNode object in the linked list

Declare class List< NODETYPE > as a friend

41

2006 Pearson Education, Inc. All rights reserved.

30

31 // return copy of data in node

32 template< typename NODETYPE >

33 NODETYPE ListNode< NODETYPE >::getData() const

34 {

35 return data;

36 } // end function getData

37

38 #endif

Outline

Listnode.h

(2 of 2)

42

2006 Pearson Education, Inc. All rights reserved.

1 // Fig. 21.4: List.h

2 // Template List class definition.

3 #ifndef LIST_H

4 #define LIST_H

5

6 #include <iostream>

7 using std::cout;

8

9 #include "listnode.h" // ListNode class definition

10

11 template< typename NODETYPE >

12 class List

13 {

14 public:

15 List(); // constructor

16 ~List(); // destructor

17 void insertAtFront( const NODETYPE & );

18 void insertAtBack( const NODETYPE & );

19 bool removeFromFront( NODETYPE & );

20 bool removeFromBack( NODETYPE & );

21 bool isEmpty() const;

22 void print() const;

23 private:

24 ListNode< NODETYPE > *firstPtr; // pointer to first node

25 ListNode< NODETYPE > *lastPtr; // pointer to last node

26

27 // utility function to allocate new node

28 ListNode< NODETYPE > *getNewNode( const NODETYPE & );

29 }; // end class List

30

Outline

List.h

(1 of 7)

private data members firsrtPtr (a pointer to the first ListNode in a List) and lastPtr (a pointer to the last ListNode in a List)

43

2006 Pearson Education, Inc. All rights reserved.

31 // default constructor

32 template< typename NODETYPE >

33 List< NODETYPE >::List()

34 : firstPtr( 0 ), lastPtr( 0 )

35 {

36 // empty body

37 } // end List constructor

38

39 // destructor

40 template< typename NODETYPE >

41 List< NODETYPE >::~List()

42 {

43 if ( !isEmpty() ) // List is not empty

44 {

45 cout << "Destroying nodes ...\n";

46

47 ListNode< NODETYPE > *currentPtr = firstPtr;

48 ListNode< NODETYPE > *tempPtr;

49

50 while ( currentPtr != 0 ) // delete remaining nodes

51 {

52 tempPtr = currentPtr;

53 cout << tempPtr->data << '\n';

54 currentPtr = currentPtr->nextPtr;

55 delete tempPtr;

56 } // end while

57 } // end if

58

59 cout << "All nodes destroyed\n\n";

60 } // end List destructor

Outline

List.h

(2 of 7)

Initialize both pointers to 0 (null)

Ensure that all ListNode objects in a List object are destroyed when that List object is destroyed

44

2006 Pearson Education, Inc. All rights reserved.

Outline

List.h

(6 of 7)Determine whether the List is empty

Return a dynamically allocated ListNode object

45

Fig. 21.6 | Operation insertAtFront represented graphically.

46

Insert at front:

What if there are none in the list?

Make sure the first pointer is set properly.

What if there is only one?

47

Outline

List.h

(3 of 7)

Places a new node at the front of the list

Use function getNewNode to allocate a new ListNode containing value and assign it to newPtr

If the list is empty, then both firstPtr and lastPtr are set to newPtr

Thread the new node into the list so that the new node points to the old first node and firstPtr points to the new node

48

Fig. 21.7 | Operation insertAtBack represented graphically.

49

2006 Pearson Education, Inc. All rights reserved.

Outline

List.h

(3 of 7)

Use function getNewNode to allocate a new listNode containing value and assign it to newPtr

If the list is empty, then both firstPtr and lastPtr are set to newPtr

Thread the new node into the list so that the old last node points to the new node and lastPtr points to the new node

50

Fig. 21.8 | Operation removeFromFront represented graphically.

51

2006 Pearson Education, Inc. All rights reserved.

91

92 // delete node from front of list

93 template< typename NODETYPE >

94 bool List< NODETYPE >::removeFromFront( NODETYPE &value )

95 {

96 if ( isEmpty() ) // List is empty

97 return false; // delete unsuccessful

98 else

99 {

100 ListNode< NODETYPE > *tempPtr = firstPtr; // hold tempPtr to delete

101

102 if ( firstPtr == lastPtr )

103 firstPtr = lastPtr = 0; // no nodes remain after removal

104 else

105 firstPtr = firstPtr->nextPtr; // point to previous 2nd node

106

107 value = tempPtr->data; // return data being removed

108 delete tempPtr; // reclaim previous front node

109 return true; // delete successful

110 } // end else

111 } // end function removeFromFront

112

Outline

List.h

(4 of 7)

Removes the front node of the list and copies the node value to the reference parameter

Return false if an attempt is made to remove a node from an empty list

Save a pointer to the first node, which will be removed

If the list has only one element, leave the list empty

Set firstPtr to point to the second node (the new first node)

Copy the removed node’s data to reference parameter value

delete the removed node

52

Fig. 21.9 | Operation removeFromBack represented graphically.

53

2006 Pearson Education, Inc. All rights reserved.

113 // delete node from back of list

114 template< typename NODETYPE >

115 bool List< NODETYPE >::removeFromBack( NODETYPE &value )

116 {

117 if ( isEmpty() ) // List is empty

118 return false; // delete unsuccessful

119 else

120 {

121 ListNode< NODETYPE > *tempPtr = lastPtr; // hold tempPtr to delete

122

123 if ( firstPtr == lastPtr ) // List has one element

124 firstPtr = lastPtr = 0; // no nodes remain after removal

125 else

126 {

127 ListNode< NODETYPE > *currentPtr = firstPtr;

128

129 // locate second-to-last element

130 while ( currentPtr->nextPtr != lastPtr )

131 currentPtr = currentPtr->nextPtr; // move to next node

132

133 lastPtr = currentPtr; // remove last node

134 currentPtr->nextPtr = 0; // this is now the last node

135 } // end else

136

137 value = tempPtr->data; // return value from old last node

138 delete tempPtr; // reclaim former last node

139 return true; // delete successful

140 } // end else

Outline

List.h

(5 of 7)

Removes the back node of the list and copies the node value to the reference parameter

Return false if an attempt is made to remove a node from an empty list

Save a pointer to the last node, which will be removed

If the list has only one element, leave the list empty

Assign currentPtr the address of the first node to prepare to “walk the list”

“Walk the list” until currentPtr points to the node before the last node, which will be the new last node

Make the currentPtr node the new last node

Copy the removed node’s data to reference parameter value

delete the removed node

54

2006 Pearson Education, Inc. All rights reserved.

Outline

List.h

(6 of 7)

167

168 ListNode< NODETYPE > *currentPtr = firstPtr;

169

170 cout << "The list is: ";

171

172 while ( currentPtr != 0 ) // get element data

173 {

174 cout << currentPtr->data << ' ';

175 currentPtr = currentPtr->nextPtr;

176 } // end while

177

178 cout << "\n\n";

179 } // end function print 180 181 #endif

55

2006 Pearson Education, Inc. All rights reserved.

1 // Fig. 21.5: Fig21_05.cpp

2 // List class test program.

3 #include <iostream>

4 using std::cin;

5 using std::cout;

6 using std::endl;

7

8 #include <string>

9 using std::string;

10

11 #include "List.h" // List class definition

12

13 // function to test a List

14 template< typename T >

15 void testList( List< T > &listObject, const string &typeName )

16 {

17 cout << "Testing a List of " << typeName << " values\n";

18 instructions(); // display instructions

19

20 int choice; // store user choice

21 T value; // store input value

22

23 do // perform user-selected actions

24 {

25 cout << "? ";

26 cin >> choice;

27

Outline

Fig21_05.cpp

(1 of 6)

56

2006 Pearson Education, Inc. All rights reserved.

28 switch ( choice )

29 {

30 case 1: // insert at beginning

31 cout << "Enter " << typeName << ": ";

32 cin >> value;

33 listObject.insertAtFront( value );

34 listObject.print();

35 break;

36 case 2: // insert at end

37 cout << "Enter " << typeName << ": ";

38 cin >> value;

39 listObject.insertAtBack( value );

40 listObject.print();

41 break;

42 case 3: // remove from beginning

43 if ( listObject.removeFromFront( value ) )

44 cout << value << " removed from list\n";

45

46 listObject.print();

47 break;

48 case 4: // remove from end

49 if ( listObject.removeFromBack( value ) )

50 cout << value << " removed from list\n";

51

52 listObject.print();

53 break;

54 } // end switch

55 } while ( choice != 5 ); // end do...while

56

Outline

Fig21_05.cpp

(2 of 6)

57

2006 Pearson Education, Inc. All rights reserved.

57 cout << "End list test\n\n";

58 } // end function testList

59

60 // display program instructions to user

61 void instructions()

62 {

63 cout << "Enter one of the following:\n"

64 << " 1 to insert at beginning of list\n"

65 << " 2 to insert at end of list\n"

66 << " 3 to delete from beginning of list\n"

67 << " 4 to delete from end of list\n"

68 << " 5 to end list processing\n";

69 } // end function instructions

70

71 int main()

72 {

73 // test List of int values

74 List< int > integerList;

75 testList( integerList, "integer" );

76

77 // test List of double values

78 List< double > doubleList;

79 testList( doubleList, "double" );

80 return 0;

81 } // end main

Outline

Fig21_05.cpp

(3 of 6)

58

2006 Pearson Education, Inc. All rights reserved.

Outline

Fig21_05.cpp

(4 of 6)

Testing a List of integer values Enter one of the following: 1 to insert at beginning of list 2 to insert at end of list 3 to delete from beginning of list 4 to delete from end of list 5 to end list processing ? 1 Enter integer: 1 The list is: 1 ? 1 Enter integer: 2 The list is: 2 1 ? 2 Enter integer: 3 The list is: 2 1 3 ? 2 Enter integer: 4 The list is: 2 1 3 4 ? 3 2 removed from list The list is: 1 3 4 (continued at top of next slide... )

59

2006 Pearson Education, Inc. All rights reserved.

Outline

Fig21_05.cpp

(5 of 6)

(...continued from bottom of previous slide) ? 3 1 removed from list The list is: 3 4 ? 4 4 removed from list The list is: 3 ? 4 3 removed from list The list is empty ? 5 End list test Testing a List of double values Enter one of the following: 1 to insert at beginning of list 2 to insert at end of list 3 to delete from beginning of list 4 to delete from end of list 5 to end list processing ? 1 Enter double: 1.1 The list is: 1.1 ? 1 Enter double: 2.2 The list is: 2.2 1.1 (continued at top of next slide... )

60

2006 Pearson Education, Inc. All rights reserved.

Outline

Fig21_05.cpp

(6 of 6)

(...continued from bottom of previous slide) ? 2 Enter double: 3.3 The list is: 2.2 1.1 3.3 ? 2 Enter double: 4.4 The list is: 2.2 1.1 3.3 4.4 ? 3 2.2 removed from list The list is: 1.1 3.3 4.4 ? 3 1.1 removed from list The list is: 3.3 4.4 ? 4 4.4 removed from list The list is: 3.3 ? 4 3.3 removed from list The list is empty ? 5 End list test All nodes destroyed All nodes destroyed

Error-Prevention Tip 21.1

Assign null (0) to the link member of a new node. Pointers should be initialized before they are used.

62

2006 Pearson Education, Inc. All rights reserved.

21.4 Linked Lists (Cont.)

• Linked list (Cont.)– Circular, singly linked list

• Pointer in last node points back to first node

– Doubly linked list• Each node has a link to next node and a link to previous node

• Two “start pointers”

– One to first node, one to last node

• Allows traversals both forward and backward

– Circular, doubly linked list• Forward link of last node points back to first node

• Backward link of first node points to last node

63

Fig. 21.10 | Circular, singly linked list.

64

Fig. 21.11 | Doubly linked list.

65

Fig. 21.12 | Circular, doubly linked list.