Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Data Structures and Algorithms Pointers and Dynamic Data.

Similar presentations


Presentation on theme: "1 Data Structures and Algorithms Pointers and Dynamic Data."— Presentation transcript:

1 1 Data Structures and Algorithms Pointers and Dynamic Data

2 2 Topics Using the Address-Of Operator & Declaring and Using Pointer Variables Using the Indirection (Dereference) Operator * The NULL Pointer Using C++ Operators new and delete Meaning of an Inaccessible Object Meaning of a Dangling Pointer Use of a Class Destructor Shallow Copy vs. Deep Copy of Class Objects Use of a Copy Constructor

3 3 Recall that... char str [ 8 ]; str is the base address of the array. We say str is a pointer because its value is an address. It is a pointer constant because the value of str itself cannot be changed by assignment. It “points” to the memory location of a char. str [0] [1] [2] [3] [4] [5] [6] [7] ‘H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘\0’ 6000

4 4 Addresses in Memory when a variable is declared, enough memory to hold a value of that type is allocated for it at an unused memory location. This is the address of the variable int x; float number; char ch; 2000 2002 2006 x number ch

5 5 Obtaining Memory Addresses the address of a non-array variable can be obtained by using the address-of operator & int x; float number; char ch; cout << “Address of x is “ << &x << endl; cout << “Address of number is “ << &number << endl; cout << “Address of ch is “ << &ch << endl;

6 6 What is a pointer variable? A pointer variable is a variable whose value is the address of a location in memory. to declare a pointer variable, you must specify the type of value that the pointer will point to,for example, int* ptr; // ptr will hold the address of an int char* q; // q will hold the address of a char

7 7 Using a Pointer Variable int x; x = 12; int* ptr; ptr = &x; NOTE: Because ptr holds the address of x, we say that ptr “points to” x 2000 12 x 3000 2000 ptr

8 8 2000 12 x 3000 2000 ptr int x; x = 12; int* ptr; ptr = &x; cout << *ptr; NOTE: The value pointed to by ptr is denoted by *ptr Unary operator * is the indirection (deference) operator

9 9 int x; x = 12; int* ptr; ptr = &x; *ptr = 5; // changes the value // at address ptr to 5 Using the Dereference Operator 2000 12 5 x 3000 2000 ptr

10 10 char ch; ch = ‘A’; char* q; q = &ch; *q = ‘Z’; char* p; p = q; // the rhs has value 4000 // now p and q both point to ch Another Example 4000 A Z ch 5000 6000 4000 4000 q p

11 11 ptr Using a Pointer to Access the Elements of a String ‘H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘\0’ 3000 char msg[ ] = “Hello”; ‘M’ ‘a’ 3001 char* ptr; 3000 ptr = msg; // recall that msg == &msg[ 0 ] *ptr = ‘M’ ; ptr++; // increments the address in ptr *ptr = ‘a’;

12 12 int StringLength ( /* in */ const char str[ ] ) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Precondition: str is a null-terminated string // Postcondition: FCTVAL == length of str (not counting ‘\0’) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { char* p ; int count = 0; p = str; while ( *p != ‘\0’ ) { count++ ; p++ ; // increments the address p by sizeof char } return count; }

13 Some C++ Pointer Operations Precedence Higher -> Select member of class pointed to Unary: ++ -- ! * new delete Increment, Decrement, NOT, Dereference, Allocate, Deallocate + - Add Subtract >= Relational operators == != Tests for equality, inequality Lower = Assignment

14 Operator new Syntax new DataType new DataType [IntExpression] If memory is available, in an area called the heap (or free store) new allocates the requested object or array, and returns a pointer to (address of ) the memory allocated. Otherwise, program terminates with error message. The dynamically allocated object exists until the delete operator destroys it.

15 15 The NULL Pointer There is a pointer constant 0 called the “null pointer” denoted by NULL in header file cstddef. But NULL is not memory address 0. NOTE: It is an error to dereference a pointer whose value is NULL. Such an error may cause your program to crash, or behave erratically. It is the programmer’s job to check for this. while (ptr != NULL) {... // ok to use *ptr here }

16 16 3 Kinds of Program Data STATIC DATA: memory allocation exists throughout execution of program static long currentSeed; AUTOMATIC DATA: automatically created at function entry, resides in activation frame of the function, and is destroyed when returning from function DYNAMIC DATA: explicitly allocated and deallocated during program execution by C++ instructions written by programmer using operators new and delete

17 17 Allocation of Memory STATIC ALLOCATION Static allocation is the allocation of memory space at compile time. DYNAMIC ALLOCATION Dynamic allocation is the allocation of memory space at run time by using operator new.

18 18 2000 ptr Dynamically Allocated Data char* ptr; ptr = new char; *ptr = ‘B’; cout << *ptr;

19 19 Dynamically Allocated Data char* ptr; ptr = new char; *ptr = ‘B’; cout << *ptr; NOTE: Dynamic data has no variable name 2000 ptr

20 20 Dynamically Allocated Data char* ptr; ptr = new char; *ptr = ‘B’; cout << *ptr; NOTE: Dynamic data has no variable name 2000 ptr ‘B’

21 21 Dynamically Allocated Data char* ptr; ptr = new char; *ptr = ‘B’; cout << *ptr; delete ptr; 2000 ptr NOTE: delete deallocates the memory pointed to by ptr ?

22 Operator delete returns to the free store memory which was previously allocated at run-time by operator new. The object or array currently pointed to by the pointer is deallocated, and the pointer is considered unassigned. Using Operator delete 22

23 23 Dynamic Array Allocation char *ptr; // ptr is a pointer variable that // can hold the address of a char ptr = new char[ 5 ]; // dynamically, during run time, allocates // memory for a 5 character array // and stores the base address into ptr ptr 6000

24 24 Dynamic Array Allocation char *ptr ; ptr = new char[ 5 ]; strcpy( ptr, “Bye” ); ptr[ 1 ] = ‘u’; // a pointer can be subscripted cout << ptr[ 2] ; ptr 6000 ‘B’ ‘y’ ‘e’ ‘\0’ ‘u’

25 Operator delete Syntax delete Pointer delete [ ] Pointer If the value of the pointer is 0 there is no effect. Otherwise, the object or array currently pointed to by Pointer is deallocated, and the value of Pointer is undefined. The memory is returned to the free store. Square brackets are used with delete to deallocate a dynamically allocated array.

26 26 Dynamic Array Deallocation char *ptr ; ptr = new char[ 5 ]; strcpy( ptr, “Bye” ); ptr[ 1 ] = ‘u’; delete ptr; // deallocates array pointed to by ptr // ptr itself is not deallocated // the value of ptr is undefined. ptr ?

27 27 int* ptr = new int; *ptr = 3; ptr = new int; // changes value of ptr *ptr = 4; What happens here? 3 ptr 3 ptr 4

28 28 Inaccessible Object An inaccessible object is an unnamed object that was created by operator new and which a programmer has left without a pointer to it. int* ptr = new int; *ptr = 8; int* ptr2 = new int; *ptr2 = -5; How else can an object become inaccessible? 8 ptr -5 ptr2

29 29 Making an Object Inaccessible int* ptr = new int; *ptr = 8; int* ptr2 = new int; *ptr2 = -5; ptr = ptr2; // here the 8 becomes inaccessible 8 ptr -5 ptr2 8 ptr -5 ptr2

30 30 Memory Leak A memory leak is the loss of available memory space that occurs when dynamic data is allocated but never deallocated.

31 31 is a pointer that points to dynamic memory that has been deallocated int* ptr = new int; *ptr = 8; int* ptr2 = new int; *ptr2 = -5; ptr = ptr2; A Dangling Pointer 8 ptr -5 ptr2 FOR EXAMPLE,

32 32 int* ptr = new int; *ptr = 8; int* ptr2 = new int; *ptr2 = -5; ptr = ptr2; delete ptr2; // ptr is left dangling ptr2 = NULL; Leaving a Dangling Pointer 8 ptr -5 ptr2 8 ptr NULL ptr2

33 33 // SPECIFICATION FILE (dynarray.h) // Safe integer array class allows run-time specification // of size, prevents indexes from going out of bounds, // allows aggregate array copying and initialization. class DynArray { public: DynArray( /* in */ int arrSize ); // Constructor. // PRE: arrSize is assigned // POST: IF arrSize >= 1 && enough memory THEN // Array of size arrSize is created with // all elements == 0 ELSE error message. DynArray( const DynArray& otherArr ); // Copy constructor. // POST: this DynArray is a deep copy of otherArr // Is implicitly called for initialization.

34 34 // SPECIFICATION FILE continued (dynarray.h) ~DynArray( ); // Destructor. // POST: Memory for dynamic array deallocated. int ValueAt ( /* in */ int i ) const; // PRE: i is assigned. // POST: IF 0 <= i < size of this array THEN // FCTVAL == value of array element at index i // ELSE error message. void Store ( /* in */ int val, /* in */ int i ) // PRE: val and i are assigned // POST: IF 0 <= i < size of this array THEN // val is stored in array element i // ELSE error message.

35 35 // SPECIFICATION FILE continued (dynarray.h) void CopyFrom ( /* in */ DynArray otherArr); // POST: IF enough memory THEN // new array created (as deep copy) // with size and contents // same as otherArr // ELSE error message. private: int* arr ; int size ; };

36 36 class DynArray 80 40 90 ? ? Private data: size 5 arr 6000 Free store 6000 DynArray Store ValueAt DynArray ~DynArray CopyFrom

37 37 DynArray beta(5); //constructor ? ? ? Private data: size 5 arr 2000 Free store 2000 DynArray Store ValueAt DynArray ~DynArray CopyFrom beta

38 38 DynArray::DynArray( /* in */ int arrSize ) // Constructor. // PRE: arrSize is assigned // POST: IF arrSize >= 1 && enough memory THEN // Array of size arrSize is created with // all elements == 0 ELSE error message. { int i; if ( arrSize < 1 ) { cerr << “DynArray constructor - invalid size: “ << arrSize << endl; exit(1); } arr = new int[arrSize] ; // allocate memory size = arrSize; for (i = 0; i < size; i++) arr[i] = 0; } 38

39 39 beta.Store(75, 2); ? 75 ? ? Private data: size 5 arr 2000 Free store 2000 DynArray Store ValueAt DynArray ~DynArray CopyFrom beta

40 40 void DynArray::Store ( /* in */ int val, /* in */ int i ) // PRE: val and i are assigned // POST: IF 0 <= i < size of this array THEN // arr[i] == val // ELSE error message. { if ( i = size ) { cerr << “Store - invalid index : “ << i << endl; exit(1) ; } arr[i] = val ; }

41 41 ? ? Private: size 4 arr 3000 3000 Private: size 5 arr 2000 2000 ? 75 ? ? gamma beta DynArray gamma(4); //constructor DynArray Store ValueAt DynArray ~DynArray CopyFrom DynArray Store ValueAt DynArray ~DynArray CopyFrom

42 42 ? -8 ? Private: size 4 arr 3000 3000 Private: size 5 arr 2000 2000 ? 75 ? ? gamma beta gamma.Store(-8,2); DynArray Store ValueAt DynArray ~DynArray CopyFrom DynArray Store ValueAt DynArray ~DynArray CopyFrom

43 43 int DynArray::ValueAt ( /* in */ int i ) const // PRE: i is assigned. // POST: IF 0 <= i < size THEN // FCTVAL == arr[i] // ELSE halt with error message. { if ( i = size ) { cerr << “ValueAt - invalid index : “ << i << endl; exit(1) ; } return arr[i]; }

44 44 Why is a destructor needed? When a DynArray class variable goes out of scope, the memory space for data members size and pointer arr is deallocated. But the dynamic array that arr points to is not automatically deallocated. A class destructor is used to deallocate the dynamic memory pointed to by the data member.

45 45 DynArray::~DynArray( ); // Destructor. // POST: Memory for dynamic array deallocated. { delete [ ] arr ; } class DynArray Destructor

46 46 What happens... When a function is called that uses pass by value for a class object of DynArray type? ? 75 ? ? Private: size 5 arr 2000 2000 DynArray Store ValueAt DynArray ~DynArray CopyFrom

47 47 // FUNCTION CODE void SomeFunc( DynArray someArr ) // Uses pass by value {. } Passing a Class Object by Value

48 48 By default, Pass-by-value makes a shallow copy DynArray beta(5); // CLIENT CODE. SomeFunc( beta ); // function call beta someArr ? 75 ? ? 2000 DynArray. Private: size 5 arr 2000 DynArray. Private: size 5 arr 2000 shallow copy

49 49 Shallow Copy vs. Deep Copy a shallow copy copies only the class data members, and does not make a copy of any pointed-to data a deep copy copies not only the class data members, but also makes a separate stored copy of any pointed-to data

50 50 What’s the difference? a shallow copy shares the pointed to dynamic data with the original class object a deep copy makes its own copy of the pointed to dynamic data at different locations than the original class object

51 51 ? 75 ? ? 4000 DynArray. Private: size 5 arr 4000 beta someArr deep copy ? 75 ? ? 2000 DynArray. Private: size 5 arr 2000 Making a (Separate) Deep Copy

52 52 Initialization of Class Objects C++ defines initialization to mean – initialization in a variable declaration – passing an object argument by value – returning an object as the return value of a function by default, C++ uses shallow copies for these initializations

53 53 As a result... when a class has a data member pointer to dynamically allocated data, you should write what is called a copy constructor the copy constructor is implicitly called in initialization situations and makes a deep copy of the dynamic data in a different memory location

54 54 More about Copy Constructors when there is a copy constructor provided for a class, the copy constructor is used to make copies for pass by value you do not call the copy constructor like other constructors, it has no return type because the copy constructor properly defines pass by value for your class, it must use pass by reference in its definition

55 55 Copy Constructor copy constructor is a special member function of a class that is implicitly called in these 3 situations: – passing object parameters by value – initializing an object variable in its declaration – returning an object as the return value of a function

56 56 ? 75 ? ? Private: size 5 arr 2000 2000 Private: size 5 arr 4000 4000 ? 75 ? ? beta someArr SomeFunc(beta); // copy-constructor // beta passed by value DEEP COPY DynArray Store ValueAt DynArray ~DynArray CopyFrom DynArray Store ValueAt DynArray ~DynArray CopyFrom

57 57 // FUNCTION CODE void SomeFunc( DynArray someArr ) // Uses pass by value { someArr.Store(290, 2);. } WHAT HAPPENS IN THE SHALLOW COPY SCENARIO? Suppose SomeFunc calls Store

58 58 DynArray beta(5); // CLIENT CODE. SomeFunc( beta); beta.arr[2] has changed beta someArr ? 290 ? ? 2000 DynArray. Private: size 5 arr 2000 DynArray. Private: size 5 arr 2000 shallow copy

59 59 beta.arr[2] has changed NOTICE THAT NOT JUST FOR THE SHALLOW COPY, BUT ALSO FOR ARGUMENT beta, THE DYNAMIC DATA HAS CHANGED! beta someArr ? 290 ? ? 2000 DynArray. Private: size 5 arr 2000 DynArray. Private: size 5 arr 2000 shallow copy

60 60 CONSTRUCTOR COPY CONSTRUCTOR DESTRUCTOR Classes with Data Member Pointers Need

61 61 DynArray::DynArray( const DynArray& otherArr ) // Copy constructor // Implicitly called for deep copy in initializations. // POST: If room on free store THEN // new array of size otherArr.size is created // on free store && arr == its base address // && size == otherArr.size // && arr[0..size-1] == otherArr.arr[0..size-1] // ELSE error message. { int i ; size = otherArr.size ; arr = new int[size] ; // allocate memory for copy for ( i = 0; i< size ; i++ ) arr[i] = otherArr.arr[i] ; // copies array } 61

62 62 What about the assignment operator? the default method used for assignment of class objects makes a shallow copy if your class has a data member pointer to dynamic data, you should write a member function to create a deep copy of the dynamic data

63 63 gamma.CopyFrom(beta); ? 75 ? ? Private: size 5 arr 3000 3000 Private: size 5 arr 2000 2000 ? 75 ? ? gamma beta DEEP COPY DynArray Store ValueAt DynArray ~DynArray CopyFrom DynArray Store ValueAt DynArray ~DynArray CopyFrom

64 64 void DynArray::CopyFrom ( /* in */ DynArray otherArr ) // Creates a deep copy of otherArr. // POST: Array pointed to by arr@entry deallocated // && IF room on free store // THEN new array is created on free store // && arr == its base address // && size == otherArr.size // && arr[0..size-1] == otherArr[0..size-1] // ELSE halts with error message. { int i ; delete [ ] arr ;// delete current array size = otherArr.size ; arr = new int [size] ;// allocate new array for ( i = 0; i< size ; i++ ) // deep copy array arr[i] = otherArr.arr[i] ; } 64

65 65 Linked Structures Data Structures and Algorithms Week #3

66 66 Topics Meaning of a Linked List Meaning of a Dynamic Linked List Traversal, Insertion and Deletion of Elements in a Dynamic Linked List Specification of a Dynamic Linked Sorted List Insertion and Deletion of Elements in a Dynamic Linked Sorted List

67 67 What is a List? A list is a varying-length, linear collection of homogeneous elements. linear means each list element (except the first) has a unique predecessor, and each element (except the last) has a unique successor

68 68 To implement the List ADT The programmer must 1) choose a concrete data representation for the list, and 2) implement the list operations

69 Array-Based Sorted List Operations Transformers –Insert –Delete Observers –IsEmpty –IsFull –Length –IsPresent –Print change state observe state 69

70 70 Array-based class SortedList IsFull Length IsPresent Delete IsEmpty Insert Print Private data: length data [ 0 ] [ 1 ] [ 2 ] [MAX_LENGTH-1] SortedList

71 71 // SPECIFICATION FILE ARRAY-BASED SORTED LIST( slist.h ) const int MAX_LENGTH = 50 ; typedef int ItemType ; class SortedList { public : // public member functions SortedList ( ) ;// constructor bool IsEmpty ( ) const ; bool IsFull ( ) const ; int Length ( ) const ; // returns length of list void Insert ( ItemType item ) ; void Delete ( ItemType item ) ; bool IsPresent( ItemType item ) const ; void Print ( ) ; private :// private data members int length ; // number of values currently stored ItemTypedata[MAX_LENGTH] ; void BinSearch ( ItemType item, bool& found, int& position ) const ; } ; 71

72 72 How to Implement a List use a built-in array stored in contiguous memory locations, implementing operations Insert and Delete by moving list items around in the array, as needed use a linked list (to avoid excessive data movement from insertions and deletions) not necessarily stored in contiguous memory locations

73 73 Implementation Possibilities for a List ADT List Linked list Built-in array Built-in dynamic data and pointers Built-in array of structs

74 74 Self-referential data types class Node { private Object data; // the “data” private Node next; // the “link” } datanext

75 75 A Linked List a linked list is a list in which the order of the components is determined by an explicit link member in each node the nodes are struct s--each node contains a component member and also a link member that gives the location of the next node in the list head ‘X’ ‘C’ ‘L’

76 76 Dynamic Linked List head “Ted” “Irv” “Lee” in a dynamic linked list, nodes are linked together by pointers, and an external pointer (or head pointer) points to the first node in the list

77 77 Nodes can be located anywhere in memory the link member holds the memory address of the next node in the list head 3000 “Ted” 5000 “Irv” 2000 “Lee” NULL 3000 5000 2000

78 78 // Type DECLARATIONS struct NodeType { char info; NodeType* link; } typedef NodeType* NodePtr; // Variable DECLARATIONS NodePtr head; NodePtr ptr; Declarations for a Dynamic Linked List. info. link ‘A’ 6000

79 79 Pointer Dereferencing and Member Selection. info. link ‘A’ 6000 ptr. info. link ‘A’ 6000 *ptr ptr. info. link (*ptr).info ptr->info ‘A’ 6000

80 80 ptr is a pointer to a node. info. link ‘A’ 6000 ptr

81 81 *ptr is the entire node pointed to by ptr ptr. info. link ‘A’ 6000 *ptr

82 82 ptr->info is a node member ptr. info. link ptr->info (*ptr).info // equivalent ‘A’ 6000

83 83 ptr->link is a node member ptr. info. link ptr->link (*ptr).link // equivalent ‘A’ 6000

84 84 Traversing a Dynamic Linked List //PRE: head points to a dynamic linked list ptr = head ; while (ptr != NULL) { cout info ; // Or, do something else with node *ptr ptr = ptr->link ; } ptr 3000 “Ted” 5000 “Irv” 2000 “Lee” NULL 3000 5000 2000 head

85 85 //PRE: head points to a dynamic linked list ptr = head ; while (ptr != NULL) { cout info ; // Or, do something else with node *ptr ptr = ptr->link ; } ptr 3000 3000 “Ted” 5000 “Irv” 2000 “Lee” NULL 3000 5000 2000 head Traversing a Dynamic Linked List

86 86 //PRE: head points to a dynamic linked list ptr = head ; while (ptr != NULL) { cout info ; // Or, do something else with node *ptr ptr = ptr->link ; } ptr 3000 3000 “Ted” 5000 “Irv” 2000 “Lee” NULL 3000 5000 2000 head Traversing a Dynamic Linked List

87 87 //PRE: head points to a dynamic linked list ptr = head ; while (ptr != NULL) { cout info ; // Or, do something else with node *ptr ptr = ptr->link ; } ptr 3000 3000 “Ted” 5000 “Irv” 2000 “Lee” NULL 3000 5000 2000 head Traversing a Dynamic Linked List

88 88 //PRE: head points to a dynamic linked list ptr = head ; while (ptr != NULL) { cout info ; // Or, do something else with node *ptr ptr = ptr->link ; } ptr 5000 3000 “Ted” 5000 “Irv” 2000 “Lee” NULL 3000 5000 2000 head Traversing a Dynamic Linked List

89 89 //PRE: head points to a dynamic linked list ptr = head ; while (ptr != NULL) { cout info ; // Or, do something else with node *ptr ptr = ptr->link ; } ptr 5000 3000 “Ted” 5000 “Irv” 2000 “Lee” NULL 3000 5000 2000 head Traversing a Dynamic Linked List

90 90 //PRE: head points to a dynamic linked list ptr = head ; while (ptr != NULL) { cout info ; // Or, do something else with node *ptr ptr = ptr->link ; } ptr 5000 3000 “Ted” 5000 “Irv” 2000 “Lee” NULL 3000 5000 2000 head Traversing a Dynamic Linked List

91 91 //PRE: head points to a dynamic linked list ptr = head ; while (ptr != NULL) { cout info ; // Or, do something else with node *ptr ptr = ptr->link ; } ptr 2000 3000 “Ted” 5000 “Irv” 2000 “Lee” NULL 3000 5000 2000 head Traversing a Dynamic Linked List

92 92 //PRE: head points to a dynamic linked list ptr = head ; while (ptr != NULL) { cout info ; // Or, do something else with node *ptr ptr = ptr->link ; } ptr 2000 3000 “Ted” 5000 “Irv” 2000 “Lee” NULL 3000 5000 2000 head Traversing a Dynamic Linked List

93 93 //PRE: head points to a dynamic linked list ptr = head ; while (ptr != NULL) { cout info ; // Or, do something else with node *ptr ptr = ptr->link ; } ptr 2000 3000 “Ted” 5000 “Irv” 2000 “Lee” NULL 3000 5000 2000 head Traversing a Dynamic Linked List

94 94 //PRE: head points to a dynamic linked list ptr = head ; while (ptr != NULL) { cout info ; // Or, do something else with node *ptr ptr = ptr->link ; } ptr NULL 3000 “Ted” 5000 “Irv” 2000 “Lee” NULL 3000 5000 2000 head Traversing a Dynamic Linked List

95 95 //PRE: head points to a dynamic linked list ptr = head ; while (ptr != NULL) { cout info ; // Or, do something else with node *ptr ptr = ptr->link ; } ptr NULL 3000 “Ted” 5000 “Irv” 2000 “Lee” NULL 3000 5000 2000 head Traversing a Dynamic Linked List

96 Using Operator new If memory is available in an area called the free store (or heap), operator new allocates the requested object, and returns a pointer to the memory allocated. The dynamically allocated object exists until the delete operator destroys it. 96

97 97 Inserting a Node at the Front of a List char item = ‘B’; NodePtr location; location = new NodeType; location->info = item; location->link = head; head = location; head ‘X’ ‘C’ ‘L’ ‘B’ item

98 98 Inserting a Node at the Front of a List char item = ‘B’; NodePtr location; location = new NodeType; location->info = item; location->link = head; head = location; head ‘X’ ‘C’ ‘L’ ‘B’ item location

99 99 Inserting a Node at the Front of a List char item = ‘B’; NodePtr location; location = new NodeType; location->info = item; location->link = head; head = location; head ‘X’ ‘C’ ‘L’ ‘B’ item location

100 100 Inserting a Node at the Front of a List char item = ‘B’; NodePtr location; location = new NodeType; location->info = item; location->link = head; head = location; head ‘X’ ‘C’ ‘L’ ‘B’ item location ‘B’

101 101 Inserting a Node at the Front of a List char item = ‘B’; NodePtr location; location = new NodeType; location->info = item; location->link = head; head = location; head ‘X’ ‘C’ ‘L’ ‘B’ item location ‘B’

102 102 Inserting a Node at the Front of a List char item = ‘B’; NodePtr location; location = new NodeType; location->info = item; location->link = head; head = location; head ‘X’ ‘C’ ‘L’ ‘B’ item location ‘B’

103 The object currently pointed to by the pointer is deallocated, and the pointer is considered undefined. The object’s memory is returned to the free store. Using Operator delete 103

104 104 Deleting the First Node from the List NodePtr tempPtr; item = head->info; tempPtr = head; head = head->link; delete tempPtr; head item ‘B’ ‘X’ ‘C’ ‘L’ tempPtr

105 105 Deleting the First Node from the List NodeType * tempPtr; item = head->info; tempPtr = head; head = head->link; delete tempPtr; head item ‘B’ ‘X’ ‘C’ ‘L’ tempPtr ‘B’

106 106 Deleting the First Node from the List NodeType * tempPtr; item = head->info; tempPtr = head; head = head->link; delete tempPtr; head item ‘B’ ‘X’ ‘C’ ‘L’ tempPtr ‘B’

107 107 Deleting the First Node from the List NodeType * tempPtr; item = head->info; tempPtr = head; head = head->link; delete tempPtr; head item ‘B’ ‘X’ ‘C’ ‘L’ tempPtr ‘B’

108 108 Deleting the First Node from the List NodeType * tempPtr; item = head->info; tempPtr = head; head = head->link; delete tempPtr; head item ‘X’ ‘C’ ‘L’ tempPtr ‘B’

109 109 What is a List? a list is a varying-length, linear collection of homogeneous elements linear means each list element (except the first) has a unique predecessor, and each element (except the last) has a unique successor

110 ADT Unsorted List Operations Transformers –Create –InsertAfter –InsertBefore –Delete Observers –IsFull –IsEmpty –EndOfList –CurrentItem Iterators –Reset –Advance change state observe state process all 110

111 111 class PersonList Private data: head currPtr ~PersonList IsEmpty Advance. InsertAfter PersonList CurrentRec Delete 13 21 E d \0M a x \0

112 // SPECIFICATION FILE person.h #include “bool.h”... struct PersonRec { char* name ;// Pointer to person’s name int age ;// Person’s age } ; typedef PersonNode* NodePtr; struct PersonNode { char* name ;// Pointer to person’s name int age ;// Person’s age NodePtr link ;// Pointer to next node in list } ; 112

113 // SPECIFICATION FILE continued person.h class PersonList { public : // LINKED LIST IMPLEMENTATION PersonList ( ) ; ~PersonList ( ) ; Boolean IsEmpty ( ) const ; Boolean IsFull ( ) const ; void Reset ( ) ; Boolean EndOfList ( ) const ; void InsertAfter ( PersonRec someRec ) ; void InsertBefore ( PersonRec someRec ) ; void Advance ( ); void Delete ( ) ; PersonRec CurrentRec ( ) const ; private : PersonNode* head ; PersonNode* currPtr ; } ; 113

114 // LINKED LIST IMPLEMENTATION FILE ( person.cpp ) #include “person.h”... PersonList::PersonList ( ) // constructor // PRE: None. // POST: Empty list created && EndOfList( ). { head = NULL; currPtr = NULL; } Boolean PersonList::IsEmpty ( ) const // POST:FCTVAL == ( list is empty ) { return ( head == NULL ) ; } 114

115 // IMPLEMENTATION CONTINUED ( person.cpp ) void PersonList::Reset ( ) // PRE: NOT IsEmpty ( ) // POST:List cursor is at front of list { currPtr = head ; } PersonRec PersonList::CurrentRec ( ) const // PRE: NOT IsEmpty ( ) && NOT EndOfList ( ) // POST:FCTVAL == record at list cursor { PersonRec rec ; rec.name = currPtr->name ; rec.age = currPtr->age ; return rec ; } 115

116 Boolean PersonList::EndOfList ( ) const // POST:FCTVAL == ( list cursor is beyond end of list ) { return ( currPtr == NULL ) ; } void PersonList::Advance ( ) // PRE: NOT IsEmpty( ) && NOT EndOfList( ) // POST: List cursor has advanced to next record { currPtr = currPtr->link ; } PersonList::~PersonList ( ) // destructor // POST: List destroyed { currPtr = head ; while ( ! EndOfList ( ) ) Delete ( ) ; } 116

117 void PersonList::InsertAfter ( /* in */ PersonRec someRec ) // PRE: Assigned (someRec) && NOT IsEmpty( ) // && NOT IsFull ( ) && NOT EndOfList ( ) // POST: someRec inserted after list cursor // && This new node has become the current record { // obtain and fill a node NodePtr ptr = new PersonNode ; ptr->name = new char [ strlen ( someRec.name) + 1 ] ; strcpy( ptr->name, someRec.name ); ptr->age = someRec.age ; ptr->link = currPtr->link ; currPtr->link = ptr ; currPtr = ptr ; } 117

118 118 Private data: head currPtr ~PersonList IsEmpty Advance. InsertAfter PersonList CurrentRec Delete Insert into the PersonList 13 21 M a x \0 E d \0 16 Ted \0

119 Inserting into the PersonList after list cursor someRec 16 Ted \0 Private data: head currPtr 13 21 E d \0M a x \0 50

120 120 NodePtr ptr = new PersonNode ; someRec ptr 16 Ted \0 Private data: head currPtr 13 21 E d \0M a x \0

121 121 ptr->name = new char[4] ; Private data: head currPtr 13 21 E d \0M a x \0 16 Ted \0 someRec ptr

122 122 strcpy( ptr->name, someRec.name ) ; Private data: head currPtr 13 21 E d \0M a x \0 16 Ted \0 someRec ptr Ted \0

123 123 ptr->age = someRec.age ; Private data: head currPtr 13 21 E d \0M a x \0 16 Ted \0 someRec ptr Ted \0 16

124 124 ptr->link = currPtr->link ; Private data: head currPtr 13 21 E d \0M a x \0 16 Ted \0 someRec ptr Ted \0 16

125 125 currPtr->link = ptr ; Private data: head currPtr 13 21 E d \0 M a x \0 16 Ted \0 someRec ptr Ted \0

126 126 currPtr = ptr ; “Ted” 16 Private data: head currPtr 13 21 E d \0M a x \0 16 Ted \0 someRec ptr

127 127 Insert algorithm How would the algorithm to Insert an item differ for a sorted linked list? That is, for a linked list with the following class invariant: // CLASSINV: list elements sorted in ascending order

128 128 class SortedList2 Print ~SortedList2 Insert InsertTop SortedList2 IsEmpty Delete ‘C’ ‘L’ ‘X’ Private data: head DeleteTop

129 ADT SortedList2 Operations Transformers –InsertTop –Insert –DeleteTop –Delete Observers –Print –IsEmpty change state observe state 129

130 130 // SPECIFICATION FILE DYNAMIC-LINKED SORTED LIST( slist2.h ) typedef int ItemType ; // Type of each component // is simple type or string type struct NodeType { ItemType item ;// Pointer to person’s name NodeType* link ;// link to next node in list } ; typedef NodeType* NodePtr; struct NodeType

131 131 // SPECIFICATION FILE DYNAMIC-LINKED SORTED LIST( slist2.h ) class SortedList2 { public : bool IsEmpty ( ) const ; void Print ( ) const ; void InsertTop ( /* in */ ItemType item ) ; void Insert ( /* in */ ItemType item ) ; void DeleteTop ( /* out */ ItemType& item ) ; void Delete ( /* in */ ItemType item ); SortedList2 ( ) ;// Constructor ~SortedList2 ( ) ;// Destructor SortedList2 ( const SortedList2& otherList ) ; // Copy-constructor private : NodeType* head; } ; 131

132 132 Insert Algorithm what will be the algorithm to Insert an item into its proper place in a sorted linked list? that is, for a linked list whose elements are maintained in ascending order?

133 133 Insert algorithm for SortedList2 find proper position for the new element in the sorted list using two pointers prevPtr and currPtr, where prevPtr trails behind currPtr obtain a node for insertion and place item in it insert the node by adjusting pointers

134 134 Implementing SortedList2 Member Function Insert // DYNAMIC LINKED LIST IMPLEMENTATION (slist2.cpp) void SortedList2 :: Insert ( /* in */ ItemType item ) // PRE: item is assigned && List components in ascending order // POST: item is in List && List components in ascending order {. }

135 135 Inserting ‘S’ into a Sorted List ‘C’ ‘L’ ‘X’ Private data: head prevPtr currPtr

136 136 Finding Proper Position for ‘S’ ‘C’ ‘L’ ‘X’ Private data: head prevPtr currPtr NULL

137 137 ‘C’ ‘L’ ‘X’ Private data: head prevPtr currPtr Finding Proper Position for ‘S’

138 138 ‘C’ ‘L’ ‘X’ Private data: head prevPtr currPtr Finding Proper Position for ‘S’

139 139 ‘C’ ‘L’ ‘X’ Private data: head prevPtr currPtr Inserting ‘S’ into Proper Position ‘S’

140 140 // IMPLEMENTATION DYNAMIC-LINKED SORTED LIST (slist2.cpp) SortedList2 ::SortedList2 ( ) // Constructor // Post: head == NULL { head = NULL ; } SortedList2 :: ~SortedList2 ( ) // Destructor // Post: All linked nodes deallocated { ItemType temp ; // keep deleting top node while ( !IsEmpty ) DeleteTop ( temp ); } 140

141 141 void SortedList2 :: Insert( /* in */ ItemType item ) // Pre: item is assigned && list components in ascending order // Post:new node containing item is in its proper place // && list components in ascending order { NodePtr currPtr ; NodePtr prevPtr ; NodePtr location ; location = new NodeType ; newNodePtr->info = item ; prevPtr = NULL ; currPtr = head ; while ( currPtr != NULL && item > currPtr->info ) {prevPtr = currPtr ; // advance both pointers currPtr = currPtr->link ; } location->link = currPtr ; // insert new node here if ( prevPtr == NULL ) head = location ; else prevPtr->link = location ; } 141

142 142 void SortedList2 :: DeleteTop ( /* out */ ItemType& item ) // Pre: list is not empty && list elements in ascending order // Post: item == element of first list node @ entry // && node containing item is no longer in linked list // && list elements in ascending order { NodePtr tempPtr = head ; // obtain item and advance head item = head->info ; head = head->link ; delete tempPtr ; }

143 143 void SortedList2 :: Delete ( /* in */ ItemType item ) // Pre: list is not empty && list elements in ascending order // && item == component member of some list node // Post: item == element of first list node @ entry // && node containing first occurrence of item is no longer // in linked list && list elements in ascending order { NodePtr delPtr ; NodePtr currPtr ;// Is item in first node? if ( item == head->info ) { delPtr = head ;// If so, delete first node head = head->link ; } else {// search for item in rest of list currPtr = head ; while ( currPtr->link->info != item ) currPtr = currPtr->link ; delPtr = currPtr->link ; currPtr->link = currPtr->link->link ; } delete delPtr ; } 143

144 144 class SortedList2 Print ~SortedList2 Insert InsertTop SortedList2 IsEmpty Delete ‘C’ L’ Private data: head DeleteTop ‘S’ ‘X’


Download ppt "1 Data Structures and Algorithms Pointers and Dynamic Data."

Similar presentations


Ads by Google