1 / 77

Chapter 6 Lists Plus

Lecture 12. Chapter 6 Lists Plus. What is a Circular Linked List?. A circular linked list is a list in which every node has a successor ; the “ last ” element is succeeded by the “ first ” element. External Pointer to the Last Node. What is a Doubly Linked List?.

quemby-dale
Télécharger la présentation

Chapter 6 Lists Plus

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Lecture 12 Chapter 6 Lists Plus

  2. What is a Circular Linked List? • A circular linked list is a list in which every node has a successor; the “last” element is succeeded by the “first” element.

  3. External Pointer to the Last Node

  4. What is a Doubly Linked List? • A doubly linked list is a list in which each node is linked to both its successor and its predecessor.

  5. Linking the New Node into the List

  6. Deleting from a Doubly Linked List What are the advantages of a circular doubly linked list?

  7. What are Header and Trailer Nodes? • A Header Node is a node at the beginning of a list that contains a key value smaller than any possible key. • A Trailer Node is a node at the end of a list that contains a key larger than any possible key. • Both header and trailer are placeholding nodes used to simplify list processing.

  8. A linked list in static storage ? A Linked List as an Array of Records

  9. A Sorted list Stored in an Array of Nodes

  10. An Array with Linked List of Values and Free Space

  11. An Array with Three Lists (Including the Free List)

  12. What is a Class Template? • A class template allows the compiler to generate multiple versions of a class type by using type parameters. • The formal parameter appears in the class template definition, and • the actual parameter appears in the client code. • Both are enclosed in pointed brackets, < >

  13. //-------------------------------------------------------- // CLASS TEMPLATE DEFINITION //-------------------------------------------------------- #include "ItemType.h" // for MAX_ITEMS and ItemType template<class ItemType> // formal parameter list class StackType { public: StackType( ); boolIsEmpty() const; boolIsFull( ) const; void Push( ItemTypeitem ); void Pop( ItemType item ); ItemTypeTop( ); private: int top; ItemTypeitems[MAX_ITEMS]; };

  14. top 3 [MAX_ITEMS-1] . . . [ 3 ] 789 [ 2 ] -56 [ 1 ] 132 items [ 0 ] 5670 ACTUAL PARAMETER StackType<int> numStack;

  15. top 3 [MAX_ITEMS-1] . . . [ 3 ] 3456.8 [ 2 ] -90.98 [ 1 ] 98.6 items [ 0 ] 167.87 ACTUAL PARAMETER StackType<float> numStack;

  16. top 3 [MAX_ITEMS-1] . . . [ 3 ] Bradley [ 2 ] Asad [ 1 ] Rodrigo items [ 0 ] Max ACTUAL PARAMETER StackType<string> numStack;

  17. //-------------------------------------------------------- // SAMPLE CLASS MEMBER FUNCTIONS //-------------------------------------------------------- template<class ItemType> // formal parameter list StackType<ItemType>::StackType( ) { top = -1; } template<class ItemType> // formal parameter list void StackType<ItemType>::Push ( ItemTypenewItem ) { if (IsFull()) throw FullStack(); top++; items[top] = newItem; // STATIC ARRAY IMPLEMENTATION }

  18. Using class templates The actual parameter to the templateis a data type. Any type can be used, either built-in or user-defined. Templates are instantiated at run time. Can you see how this might cause a problem?

  19. When creating class template • Put .h and .cpp code in the same .h file • or • Have .h include .cpp file at the end

  20. Recall Definition of Stack • Logical (or ADT) level:A stack is an ordered group of homogeneous items (elements), • in which the removal and addition of stack items can take place only at the top of the stack. • A stack is a LIFO“last in, first out” structure.

  21. StackType Top Private data: topPtr IsEmpty 20 30 IsFull Push Pop ~StackType class StackType<int>

  22. What happens . . . • When a function is called that uses pass by value for a class object like our dynamically linked stack?

  23. Pass by value makes a shallow copy StackType<int> myStack; // CLIENT CODE . . . MyFunction( myStack ); // function call myStack momeStack Private data: topPtr7000 Private data: 7000 6000 topPtr7000 20 30 shallow copy

  24. What’s the difference? • A shallow copyshares the pointed to data with the original class object. • A deep copystores its own copy of the pointed to data at different locations than the data in the original class object.

  25. Making a deep copy myStack Private data: 7000 6000 topPtr7000 20 30 someStack Private data: 5000 2000 topPtr5000 20 30 deep copy

  26. Suppose MyFunction Uses Pop // FUNCTION CODE template<class ItemType> void MyFunction( StackType<ItemType> SomeStack ) // Uses pass by value { ItemType item; SomeStack.Pop(item); . . . } What happens in a shallow copy?

  27. MyStack.topPtr is left dangling StackType<int> myStack; // CLIENT CODE . . . MyFunction( myStack ); myStack someStack Private data: topPtr6000 Private data: 7000 6000 topPtr7000 ? 30 shallow copy

  28. MyStack.topPtr is left dangling Notice that the shallow copy and the actual parameter myStack, have changed! myStack someStack Private data: topPtr6000 Private data: 7000 6000 topPtr7000 ? 30 shallow copy

  29. As a result . . . • This default method used for pass by value is not the best way when a data member points to dynamic data. • Instead, you should write what is called acopy constructor, • which makes a deep copy of the dynamic data in a different memory location.

  30. 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.

  31. // DYNAMICALLY LINKED IMPLEMENTATION OF STACK template<class ItemType> class StackType { public: StackType( ); // Default constructor. // Post: Stack is created and empty. StackType( constStackType<ItemType>& anotherStack ); // Copy constructor. // Implicitly called for pass by value. . . . ~StackType( ); // Destructor. // Post: Memory for nodes has been deallocated. private: NodeType<ItemType>* topPtr; };

  32. Classes with Data Member Pointers Need CLASS CONSTRUCTOR CLASS COPY CONSTRUCTOR CLASS DESTRUCTOR

  33. template<class ItemType>// COPY CONSTRUCTOR StackType<ItemType>:: StackType( constStackType<ItemType>& anotherStack ) { NodeType<ItemType>* ptr1; NodeType<ItemType>* ptr2; if ( anotherStack.topPtr== NULL ) topPtr = NULL; else // allocate memory for first node { topPtr = new NodeType<ItemType>; topPtr->info = anotherStack.topPtr->info; ptr1 = anotherStack.topPtr->next; ptr2 = topPtr; while ( ptr1 != NULL ) // deep copy other nodes { ptr2->next = new NodeType<ItemType>; ptr2 = ptr2->next; ptr2->info = ptr1->info; ptr1 = ptr1->next; } ptr2->next = NULL; } }

  34. 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 overload the assignment operator to make a deep copy of the dynamic data.

  35. // DYNAMICALLY LINKED IMPLEMENTATION OF STACK template<class ItemType> class StackType { public: StackType( ); // Default constructor. StackType(constStackType<ItemType>& anotherStack ); // Copy constructor. void operator= ( StackType<ItemType> ); // Overloads assignment operator. . . . ~StackType( ); // Destructor. private: NodeType<ItemType>* topPtr; };

  36. Using Overloaded Binary operator+ When a Member Function was defined myStack + yourStack myStack.operator+(yourStack) When a Friend Function was defined myStack + yourStack operator+(myStack, yourStack)

  37. C++ Operator Overloading Guides • All operators except these :: . sizeof ?: may be overloaded. • At least one operand must be a class instance. • You cannot change precedence, operator symbols, or number of operands. • Overloading ++ and -- requires prefix form use by default. • An operator can be given multiple meanings if the data types of operands differ.

  38. Polymorphism with Virtual Functions • formalParameter.MemberFunction(...); • then • If MemberFunction is not a virtual function, the type of the formal parameterdetermines which function to call. • Static binding is used. • If MemberFunction is a virtual function, the type of the actual parameterdetermines which function to call. • Dynamic binding is used.

  39. class ItemType { public: virtual RelationTypeComparedTo(ItemType) const; private: char lastName[50] ; } ; class NewItemType : public ItemType { public: RelationTypeComparedTo( ItemType) const; private: char firstName[50] ; } ; void PrintResult( ItemType& first, ItemType& second) { using namespace std; if ( first. ComparedTo( second) ==LESS) cout<< " First comes before second" ; else cout<< " First does not come before second" ; } ItemType item1 , item2; NewItemType item3 , item4: PrintResult( item1 , item2) ; PrintResult( item3 , item4) ; You should pass by reference to access derived data members

  40. Chapter 7 Programming with Recursion

  41. What Is Recursion? • Recursive call A method call in which the method being called is the same as the one making the call • Direct recursionRecursion in which a method directly calls itself • Indirect recursionRecursion in which a chain of two or more method calls returns to the method that originated the chain

  42. Recursion • You must be careful when using recursion. • Recursive solutions are typically less efficient than iterative solutions. • Still, many problems lend themselves to simple, elegant, recursive solutions. • We must avoid making an infinite sequence of function calls • infinite recursion

  43. Some Definitions • Base case The case for which the solution can be stated nonrecursively • General (recursive) case The case for which the solution is expressed in terms of a smaller version of itself • Recursive algorithm A solution that is expressed in terms of • smaller instances of itself and • a base case

  44. Writing a recursive function to find n factorial DISCUSSION The function call Factorial(4) should have value 24, because that is 4 * 3 * 2 * 1 . For a situation in which the answer is known, the value of 0! is 1. So our base case could be along the lines of if ( number == 0 ) return 1;

  45. General format for many recursive functions if (some condition for which answer is known) // base case solution statement else// general case recursive function call • Each successive recursive call should bring you closer to a situation in which the answer is known. • Each recursive algorithm must have at least one base case, as well as the general (recursive) case

  46. Writing a recursive function to find Factorial(n) Now for the general case . . . The value of Factorial(n) can be written as n * the product of the numbers from (n - 1) to 1, that is, n * (n - 1) * . . . * 1 or, n * Factorial(n - 1) And notice that the recursive call Factorial(n - 1) gets us “closer” to the base case of Factorial(0).

  47. Recursive Solution int Factorial ( int number ) // Pre: number is assigned and number >= 0. { if ( number == 0)// base case return 1 ; else // general case return number + Factorial ( number - 1 ) ; }

More Related