CH4. LINKED LISTS.

Slides:



Advertisements
Similar presentations
CSCE 3110 Data Structures & Algorithm Analysis
Advertisements

DATA STRUCTURES USING C++ Chapter 5
Chapter 4 Lists Pointers Singly Linked Lists
CS Data Structures Chapter 4 Lists. Chain (1/3) Chain: Chain: A singly linked list in which the last node has a null link A singly linked list in.
CSE Lecture 12 – Linked Lists …
Chapter 4.
Review of Sequential Representations Previously introduced data structures, including array, queue, and stack, they all have the property that successive.
C++ Programming: Program Design Including Data Structures, Fifth Edition Chapter 17: Linked Lists.
CS Data Structures Chapter 4 Lists.
Chapter 4 1. Why “linked lists” 2 IndexWord A[0]BAT A[1]CAT A[2]EAT … A[n]WAT Insert “FAT” ? Or delete something.
Data Structures Using C++ 2E
C++ Programming: Program Design Including Data Structures, Fourth Edition Chapter 13: Pointers, Classes, Virtual Functions, and Abstract Classes.
Data Structures Using C++ 2E Chapter 3 Pointers and Array-Based Lists.
C++ Programming: From Problem Analysis to Program Design, Fourth Edition Chapter 14: Pointers, Classes, Virtual Functions, and Abstract Classes.
Introduction to Data Structure
Nirmalya Roy School of Electrical Engineering and Computer Science Washington State University Cpt S 122 – Data Structures Custom Templatized Data Structures.
Linked Lists list elements are stored, in memory, in an arbitrary order explicit information (called a link) is used to go from one element to the next.
Copyright © 2008 Pearson Addison-Wesley. All rights reserved. Chapter 13 Pointers and Linked Lists.
Linked List Containers. Linked List Example Polynomials –Interested in representing and manipulating polynomials –Polynomial defined as: Y = coef_n *
Pointers OVERVIEW.
Linked List (Part II). Introduction  Definition of equivalence relation: A relation ≡ over a set S, is said to be an equivalence relation over S iff.
Data Structures Chapter 4: Linked Lists 4-1. Singly Linked List DABC 561 data link(pointer, address) 以 -1 代表結尾 (null pointer) first = 2 header,
Chap 4 Linked Lists. Review of Sequential Representations Previously introduced data structures, including array, queue, and stack, they all have the.
Review of Sequential Representations Previously introduced data structures, including array, queue, and stack, they all have the property that successive.
Chapter 12: Pointers, Classes, Virtual Functions, and Abstract Classes.
Chapter 4 (cont.) Additional Lists Operations Circular Lists The link field of the last node points to the first node in the list... BATCATFATWAT.
Slide 1 Linked Data Structures. Slide 2 Learning Objectives  Nodes and Linked Lists  Creating, searching  Linked List Applications  Stacks, queues.
Lists Chapter 8. 2 Linked Lists As an ADT, a list is –finite sequence (possibly empty) of elements Operations commonly include: ConstructionAllocate &
Linked List (Part I). Introduction  Weakness of storing an ordered list in array: Insertion and deletion of arbitrary elements are expensive. ○ Example:
Linked List Containers. Linked Lists List consists of multiple listnodes List consists of multiple listnodes Each listnode consists of Each listnode consists.
Linked List Containers. Concatenate Example Concatenate(LinkedList listB): Add all of the elements of a second list to the end of the first list Concatenate(LinkedList.
CHAPTER 17 LINKED LISTS. In this chapter, you will:  Learn about linked lists  Become aware of the basic properties of linked lists  Explore the insertion.
1 Classes II Chapter 7 2 Introduction Continued study of –classes –data abstraction Prepare for operator overloading in next chapter Work with strings.
Prof. amr Goneid, AUC1 CSCE 110 PROGRAMMING FUNDAMENTALS WITH C++ Prof. Amr Goneid AUC Part 15. Dictionaries (1): A Key Table Class.
Chapter 17: Linked Lists. Objectives In this chapter, you will: – Learn about linked lists – Learn the basic properties of linked lists – Explore insertion.
Linked List Containers. Useful Linked List Add-Ons Are there new variables/changes to the lists as they have been defined that could make our jobs as.
1 CS 132 Spring 2008 Chapter 5 Linked Lists p
Chapter 12: Pointers, Classes, Virtual Functions, Abstract Classes, and Lists.
LINKED LISTS.
Chapter 16: Linked Lists.
C++ Programming:. Program Design Including
Pointers and Linked Lists
Chapter 7: User-Defined Functions II
Pointers and Linked Lists
CS 215 Final Review Ismail abumuhfouz Fall 2014.
Chapter 13: Pointers, Classes, Virtual Functions, and Abstract Classes
Data Structure Dr. Mohamed Khafagy.
CSCE 3110 Data Structures & Algorithm Analysis
UNIT-3 LINKED LIST.
CSE 143 Linked Lists [Chapter , 8.8] 3/30/98.
Data Structures 7th Week
EEE2108: Programming for Engineers Chapter 4. Linked Lists
CSCE 210 Data Structures and Algorithms
Lecture 4 Linked List and STL
Stack Lesson xx   This module shows you the basic elements of a type of linked list called a stack.
Chapter 12: Pointers, Classes, Virtual Functions, and Abstract Classes
Linked Lists.
Chapter 18: Linked Lists.
ليست هاي پيوندي.
Linked List (Part I) Data structure.
Pointers and Linked Lists
Classes and Objects.
Doubly Linked List Implementation
Pointers & Dynamic Data Structures
Chapter 8: Class Relationships
Data Structures & Algorithms
CS410 – Software Engineering Lecture #5: C++ Basics III
Data Structures Chapter 4: Linked Lists.
Doubly Linked List Implementation
Presentation transcript:

CH4. LINKED LISTS

4.1 Singly Linked Lists Sequential representation successive nodes of the data object are stored a fixed distance apart order of elements is the same as in ordered list adequate for functions such as accessing an arbitrary node in a table operations such as insertion and deletion of arbitrary elements from ordered lists become expensive Linked representation successive items of a list may be placed anywhere in memory order of elements need not be the same as order in list each data item is associated with a pointer (link) to the next item 11/11/2018

4.1 Singly Linked Lists(Cont’) List of 3-letter words : (BAT, CAT, EAT, ..., VAT, WAT) data link 1 HAT 15 2 3 CAT 4 EAT 9 5 6 7 WAT 8 BAT FAT 10 11 VAT . data[8] = BAT first = 8 link[8] = 3 data[3] = CAT Figure 4.1: Nonsequential list representation 11/11/2018

4.1 Singly Linked Lists(Cont’) first BAT CAT EAT WAT Figure 4.2 : Usual way to draw a linked list 11/11/2018

4.1 Singly Linked Lists(Cont’) To insert GAT between FAT and HAT (1) get a node N that is currently unused ; let its address be x (2) set the data field of N to GAT (3) set the link field of N to point to the node after FAT, which contains HAT (4) set the link field of the node containing FAT to x 11/11/2018

4.1 Singly Linked Lists(Cont’) Figure 4.3 : Inserting a node 11/11/2018

4.1 Singly Linked Lists(Cont’) To delete GAT find the element that immediately precedes GAT, which is FAT set the link field of FAT to the position of HAT first BAT CAT EAT FAT GAT HAT WAT Figure 4.4 : Delete GAT from list Note : must know the previous element 11/11/2018

4.2 Representing Lists in C++ 4.2.1 Defining A List Node in C++ Defining a List Node in C++ Class definition for 3-letter node A more complicated list structure class ThreeLetterNode{ private: char data[3]; ThreeLetterNode *link; }; class nodea{ private: int data1; char data2; float data3; nodea *linka; nodeb *linkb; }; class nodeb{ private: int data; nodeb *link; }; 11/11/2018

4.2 Representing Lists in C++(Cont’) data 22 data1 5.5 data2 link ‘c’ data3 3.14 linka linkb nodea nodeb Figure 4.5 : Illustration of the node structures nodea and nodeb 11/11/2018

4.2 Representing Lists in C++(Cont’) 4.2.2 Designing a list in C++ Design approach use a class ThreeLetterList corresponding to the entire list data structure ThreeLetterList supports member functions for list manipulation operations use a composite of two classes, ThreeLetterNode and ThreeLetterList ThreeLetterList HAS-A ThreeLetterNode Definition a data object of type A HAS-A data object of type B if A conceptually contains B 11/11/2018

4.2 Representing Lists in C++(Cont’) Figure 4.6 : Referencing the data members of a node 11/11/2018

4.2 Representing Lists in C++(Cont’) ThreeLetter List ThreeLetter Node first CAT EAT WAT Figure 4.7 : Conceptual relationship between ThreeLetterList and ThreeLetterNode 11/11/2018

4.2 Representing Lists in C++(Cont’) ThreeLetterList contains only the pointer first declare to be a friend of ThreeLetterNode only member functions of ThreeLetterList and ThreeLetterNode can access the private members of ThreeLetterNode only list manipulation operations have access to data members of ThreeLetterNode ThreeLetter List ThreeLetter Node first BAT CAT WAT Figure 4.8 : Actual relationship between ThreeLetterList and ThreeLetterNode 11/11/2018

4.2 Representing Lists in C++(Cont’) class ThreeLetterList; // forward declaration class ThreeLetterNode{ friend class ThreeLetterList; private: char data[3]; ThreeLetterNode *link; }; class ThreeLetterList{ public: // List Manipulation operations … private: ThreeLetterNode *first; }; Program 4.1 : Composite classes 11/11/2018

4.2 Representing Lists in C++(Cont’) Nested Classes one class is defined inside the definition of another class ThreeLetterNode objects (private) cannot be accessed outside class ThreeLetterList ThreeLetterNode data members are public, so they can be accessed by member functions of ThreeLetterList 11/11/2018

4.2 Representing Lists in C++(Cont’) class ThreeLetterList{ public: // List Manipulation operations …. private: class ThreeLetterNode{ // nested class public: char data[3]; ThreeLetterNode *link; }; ThreeLetterNode *first; }; Program 4.2 : Nested classes 11/11/2018

4.2 Representing Lists in C++(Cont’) Using composite classes, the node class can be used by two data structures 11/11/2018

4.2 Representing Lists in C++(Cont’) 4.2.3 Pointer Manipulation in C++ new command delete command null command ThreeLetterNode* f; nodea* y; nodeb* z; f = new ThreeLetterNode; y = new nodea; z = new nodeb; *f : the node of type ThreeLetterNode delete f; delete y; delete z; constant 0 11/11/2018

4.2 Representing Lists in C++(Cont’) x a a b x y b y b b (a) (b) x=y (c) *x=*y Figure 4.9 : Effect of pointer assignments 11/11/2018

4.2 Representing Lists in C++(Cont’) 4.2.4 List Manipulation Operations class List { private: ListNode *first; public: .... }; class ListNode { friend class List; private: int data; ListNode *link; 11/11/2018

4.2 Representing Lists in C++(Cont’) void List::Create2(){ first = new ListNode(10); // create and initialize first node // create and initialize second node and place its address in first→link first→link = new ListNode(20); } ListNode::ListNode(int element = 0) // 0 is the default argument // in constructor for List Node { data = element; link = 0; // null pointer constant } Program 4.3 : Creating a two-node list 11/11/2018

4.2 Representing Lists in C++(Cont’) first 10 20 Figure 4.10 : A two-node list 11/11/2018

4.2 Representing Lists in C++(Cont’) Example void List::Insert50(ListNode *x) { //insert new node after x ListNode *t = new ListNode(50); //create and initialize new node if(!first) //insert into empty list { first = t; return; //exit List::Insert50 } //insert after x t->link = x->link; x->link = t; } Program 4.4 : Inserting a node 11/11/2018

4.2 Representing Lists in C++(Cont’) first first x 50 t t 50 (a) (b) Figure 4.11 : Inserting into an empty and nonempty list 11/11/2018

4.2 Representing Lists in C++(Cont’) Void List::Delete(ListNode *x, ListNode *y) { // delete x placed after y if(!y) first = first->link; else y->link = x->link; delete x; // return the node } Program 4.5 : Deleting a node x first y x first 11/11/2018

4.2 Representing Lists in C++(Cont’) Figure 4.12 : Possible configuration for a singly linked list traversed in both directions 11/11/2018

4.3 A Reusable Linked List Class 4.3.1 Implementing Linked Lists with Templates Implementing Linked Lists with Templates Linked-list a container class good for implementation with templates an empty linked list of integers intlist List<int> intlist; 11/11/2018

4.3 A Reusable Linked List Class(Cont’) template <class Type> class List; // forward declaration template <class Type> class ListNode{ friend class List<Type>; private: Type data; ListNode *link; }; template <class Type> class List{ public: List() first = 0;; // constructor initializing first to 0 // List manipulation operations …. private: ListNode<Type> *first; }; Program 4.6 : Template definition of linked lists 11/11/2018

4.3 A Reusable Linked List Class(Cont’) 4.3.2 Linked Lists Iterators Iterator an object that is used to traverse all the elements of a container class Example operations on an integer container class C print all integers in C obtain the max, min, mean, median, or mode of all integers in C obtain the sum or product of all integers in C Pseudo-code for the operations initialization step; for each item in C { current=current item of C; body; } postprocessing step; 11/11/2018

4.3 A Reusable Linked List Class(Cont’) int x = -MAXINT; // initialization statement for each item in C { current = current item of C; x = max(current, x); // body } return x; // postprocessing step Program 4.7 : Pseudo-code for computing maximum element 11/11/2018

4.3 A Reusable Linked List Class(Cont’) All operations have to be implemented as member functions of a particular container class drawbacks many operations do not make sense to certain object types too many operations in a class users have to learn how to traverse the container class ListIterator<Type> handles details of the linked list traversal retrieves elements stored in the list 11/11/2018

4.3 A Reusable Linked List Class(Cont’) enum Boolean { FALSE, TRUE}; template <class Type> class List; template <class Type> class ListIterator; template <class Type> class ListNode{ friend class List<Type>; friend class ListIterator<Type>; private: Type data; ListNode *link; }; template <class Type> class List{ friend class ListIterator<Type>; public: List() {first = 0;}; // List manipulation operations … private: ListNode<Type> *first; }; list first 11/11/2018

4.3 A Reusable Linked List Class(Cont’) template <class Type> class ListIterator{ public: ListIterator(const List<Type> &l): list(l), current(l.first) {}; Boolean NotNull(); Boolean NextNotNull(); Type* First(); Type* Next(); private: const List<Type> &list; // refers to an existing list ListNode<Type> *current; // points to a node in list }; Program 4.8 : Template definition of linked lists 11/11/2018

4.3 A Reusable Linked List Class(Cont’) template <class Type> // check that the current element in list is non-null Boolean ListIterator<Type>::NotNull(){ if(current) return TRUE; else return FALSE; } template <class Type> //check that the next element in list is non-null Boolean ListIterator<Type>::NextNotNull(){ if(current && current->link) return TRUE; 11/11/2018

4.3 A Reusable Linked List Class(Cont’) template <class Type> // return a pointer to the first element of list Type* ListIterator<Type>::First(){ if(list.first) return &list.first->data; else return 0; } template <class Type> // return a pointer to the next element of list Type* ListIterator<Type>::Next(){ if(current){ current = current->link; if (current) return &current->data; } else return 0; } Program 4.9 : List iterator functions 11/11/2018

4.3 A Reusable Linked List Class(Cont’) int sum(const List<int>& l) { Listiterator<int> li(l); // li is associated with list l if(!li.NotNull()) return 0; // empty list, return 0 int retvalue = *li.First(); // get first element while(li.NextNotNull()) // make sure that next element exists retvalue += *li.Next(); // get it, add it to the current total return retvalue; } Program 4.10 : Using iterators to compute the sum of elements 11/11/2018

4.3 A Reusable Linked List Class(Cont’) Function sum does not require access to the private data members of List<Type> or List node<Type> Listlterator current List List ListNode first 11/11/2018

4.3 A Reusable Linked List Class(Cont’) 4.3.3 Linked List Operations Operations included in most reusable classes constructors (including default and copy constructors) a destructor operator= operator== operators to input and output a class object (by overloading operator>> and operator<<) Operations in a linked list class insertion, deletion, other manipulations last : a private data member in List<Type> 11/11/2018

4.3 A Reusable Linked List Class(Cont’) template<class Type> void List<Type>::Attach(Type k) { ListNode<Type>* newnode = new ListNode<Type>(k); if ( first==0 ) first = last = newnode; else { last->link = newnode; last = newnode; } } Program 4.11 : Attaching a node to the end of a list 11/11/2018

4.3 A Reusable Linked List Class(Cont’) template <class Type> void List<Type>::Invert() // A chain x is inverted so that if x = (a1, ..., an), // then, after execution, x = (an, ..., a1). { ListNode<Type> *p = first, *q = 0; // q trails p while(p){ ListNode<Type> *r = q; q = p; // r trails q p = p->link; // p moves to next node q->link = r; // link q to preceding node } first = q; } Program 4.12 : Inverting a list 11/11/2018

4.3 A Reusable Linked List Class(Cont’) 1 st iteration q p 2 nd iteration r q p 11/11/2018

4.3 A Reusable Linked List Class(Cont’) template <class Type> void List<Type>::Concatenate(List<Type>b) // this = (a1, ..., am) and b = (b1, ..., bn), m, n≥0 // produces the new chain z = (a1, ..., am, b1, ..., bn) in this. { if (!first) { first = b.first; return; } if (b.first) for (ListNode<Type> *p = first; p->link; p = p->link); // no body p->link = b.first; } Program 4.13 : Concatenating two chains 11/11/2018

Figure 4.13 : A circular list 4.4 Circular Lists Circular list link field of the last node points to the first node in the list to check whether current points to the last node: current→link==first first BAT CAT EAT WAT Figure 4.13 : A circular list 11/11/2018

4.4 Circular Lists(Cont’) first x1 x2 x3 Data link Figure 4.14 : Example of a circular list last x1 x2 x3 Data link Figure 4.15 : Pointing to the last node of a circular list 11/11/2018

4.4 Circular Lists(Cont’) template <class Type> void CircList::InsertFront(ListNode <Type> *x) // Insert the node pointed at by x at the "front" of the circular // list this, where last points to the last node in the list. { if(!last){ // empty list last = x; x->link = x; } else { x->link = last->link; last->link = x; Program 4.14 : Inserting at the front 11/11/2018

4.4 Circular Lists(Cont’) last : the private data member that points to the last node a dummy head node : to avoid a case in which the empty list is handled specially first (a) first BAT CAT EAT WAT (b) Figure 4.16 : A circular list with a head node 11/11/2018

4.5 Linked Stacks and Queues Figure 4.17 : Linked stack and queue 11/11/2018

4.5 Linked Stacks and Queues(Cont’) class Stack; // forward declaration class StackNode { friend class Stack; private: int data; StackNode *link; StackNode(int d=0, StackNode *l=0): data(d), link(l) {}; // condtructor }; class Stack { public: Stack() {top=0;}; // constructor void Add(condt int); int* Delete(int&); StackNode *top; void StackEmpty(); Program 4.15 : Stack class definition 11/11/2018

4.5 Linked Stacks and Queues(Cont’) void Stack :: Add(const int y){ top = new stackNode(y, top); } Program 4.16 : Adding to a linked stack int* Stack :: Delete(int& retvalue) // delete top node from stack and return a pointer to its data { if (top==0){StackEmpty(); return 0;}// return null pointer constant StackNode *delnode = top; retvalue=top->data; // get data field of top node top=top->link; // remove top node delete delnode; // free the node return &retvalue; // return pointer to data } Program 4.17 : Deleting from a linked stack 11/11/2018

4.5 Linked Stacks and Queues(Cont’) void Queue :: Add(const int y) { if (front==0) front = rear = new QueueNode(y, 0); // empty queue else rear = rear->link = new QueueNode(y, 0); // attach node and update rear } Program 4.18 : Adding to a linked queue int* Queue :: Delete(int& retvalue) // delete top node in queue and return a pointer to its data { if (top==0){QueueEmpty(); return 0;} QueueNode *x = front; retvalue=front->data; // get data front=x->link; // delete front node delete x; // free the node return &retvalue; // return pointer to data } Program 4.19 : Deleting from a linked queue 11/11/2018

4.6 Polynomials 4.6.1 Polynomial Representation Polynomial class a polynomial is represented by a list Polynomial IS-IMPLEMENTED-BY List Definition a data object of Type A IS-IMPLEMENTED-BY a data object of Type B if the Type B object is central to the implementation of the Type A object Implementation linked list object poly is data member of Polynomial list template Type instatiation struct term 11/11/2018

4.6 Polynomials(Cont’) : polynode coef exp link term data : ListNode 11/11/2018

4.6 Polynomials(Cont’) Program 4.20 : Polynomial class definition struct Term // all members of Term are public by default { int coef; // coefficient int exp; // exponent void Init(int c, int e) coef = c; exp = e; ; }; class Polynomial { friend Polynomial operator + (const Polynomial&, const Polynomial&); private: List<Term> poly; }; Program 4.20 : Polynomial class definition 11/11/2018

4.6 Polynomials(Cont’) a.first 3 14 2 8 1 (a) b.first 8 14 -3 10 10 6 (a) b.first 8 14 -3 10 10 6 (b) Figure 4.18 : Polynomial representation of 3x14+2x8 + 1and 8x14-3x10 + 10x6 11/11/2018

4.6 Polynomials(Cont’) 4.6.2 Adding Polynomials Add polynomials a and b use list iterators Aiter and Biter to examine their terms two variables p and q are used to move along the terms of a and b if p→exp == q→exp coefficients are added a new term is created for the result polynomial c if the sum is not zero if p→exp < q→exp copy of the term in b is attached to c q is advanced if p→exp > q→exp similar action is taken on a 11/11/2018

4.6 Polynomials(Cont’) a 3 14 2 8 1 q p b 8 14 -3 10 10 6 c 11 14 q p b 8 14 -3 10 10 6 c 11 14 (i) p  exp == q  exp a 3 14 2 8 1 p q b 8 14 -3 10 10 6 c 11 14 -3 10 (ii) p  exp < q  exp 11/11/2018

Figure 4.19 : Generating the first three terms of c=a+b 4.6 Polynomials(Cont’) a 3 14 2 8 1 p q b 8 14 -3 10 10 6 c 11 14 -3 10 10 8 (iii) p  exp > q  exp Figure 4.19 : Generating the first three terms of c=a+b 11/11/2018

4.6 Polynomials(Cont’) Polynomial operator+(const Polynomial& a, const Polynomial& b){ // Polynomials a and b are added and the sum returned Term *p, *q, temp; ListIterator<Term> Aiter(a.poly); ListIterator<Term> Biter(b.poly); Polynomial c; p = Aiter.First(); q = Biter.First(); // get first node in a and b while (Aiter.NotNull() && Biter.NotNull()){ // current node is not null switch (compare(p->exp, q->exp)){ case '=': int x = p->coef + q->coef; temp.Init(x,q->exp); if (x) c.poly.Attach(temp); p = Aiter.Next(); q = Biter.Next(); // advance to next term break; case '<': temp.Init(q->coef,q->exp); c.poly.Attach(temp); q = Biter.Next(); // next term of b break; 11/11/2018

4.6 Polynomials(Cont’) Program 4.21 : Adding two polynomials case '>': temp.Init(p->coef,p->exp); c.poly.Attach(temp); p = Aiter.Next(); // next term of a } } while (Aiter.NotNull()){ // copy rest of a temp.Init(p->coef,p->exp); c.poly.Attach(temp); p = Aiter.Next(); } while (Biter.NotNull()){ // copy rest of b temp.Init(q->coef,q->exp); c.poly.Attach(temp); q = Biter.Next(); } return c; } Program 4.21 : Adding two polynomials 11/11/2018

4.6 Polynomials(Cont’) ListNode Type data; ListNode *Link List ListNode<Type> *first; ListIterator List<Type> &List; ListNode<Type> *current ListIterator(List<Type> &l) Term int coef; int exp; Polynomial List<Term> Poly; Operator+(Polynomial &a, Polynomal &b) Term *p, *q, temp; ListIterator<Term> Aiter(a.Poly); ListIterator<Term> Biter(b.Poly); Polynomial c; 11/11/2018

4.6 Polynomials(Cont’) Analysis of operator+( ) operations contributing to the computing time : coefficient additions exponent comparisons additions/deletions to available space creation for new nodes for c assume a and b have m and n terms 0 coefficients additions minm, n exponent comparisons < m+n the computing time is O(m+n) algorithm operator+( ) is optimal within a constant factor 11/11/2018

4.6 Polynomials(Cont’) 4.6.3 Erasing Polynomials Compute and print d(x)=a(x)*b(x)+c(x) Destructor ListNode<term> objects are not physically contained in List<term> objects the objects do not get automatically freed up destructor deletes all objects that are conceptually part of a class but not physically part of it void func(){ Polynomial a,b,c,d,t; cin >> a; // read and create polynomials cin >> b; cin >> c; t = a * b; d = t + c; cout << d; } 11/11/2018

List<Term> poly 4.6 Polynomials(Cont’) Polynomial List<Term> poly ListNode<Term> first (a) ListNode<Term> (b) Figure 4.20 : (a) and (b), respectively, show a polynomial object before and after it goes out of scope 11/11/2018

4.6 Polynomials(Cont’) Program 4.22 : Erasing a polynomial template <class Type> List<Type>::~List() // Free all nodes in the chain { ListNode<Type>* next; for (; first; first = next){ next = first->link; delete first; } } Program 4.22 : Erasing a polynomial 11/11/2018

Figure 4.21 : Circular list representation of 3x14 + 2x8 + 1 4.6 Polynomials(Cont’) Figure 4.21 : Circular list representation of 3x14 + 2x8 + 1 11/11/2018

Program 4.23 : Getting a node 4.6 Polynomials(Cont’) template<class Type> ListNode<Type>* CircList :: GetNode() // Provide a node for use. { ListNode<Type>* x; if (!av) x = new ListNode<Type>; else { x = av; av = av->link;} return x; } Program 4.23 : Getting a node 11/11/2018

4.6 Polynomials(Cont’) Program 4.24 : Returning a node template<class Type> void CircList<Type> :: RetNode(ListNode<Type>* x) // Free the node pointed to by x. { x->link = av; av = x; } Program 4.24 : Returning a node 11/11/2018

Program 4.25 : Erasing a circular list 4.6 Polynomials(Cont’) template<class KeyType> void CircList<Type> :: ~CircList() // Erase the circular list pointed by first. { if (first){ ListNode* second = first->link; // second node first->link = av; // first node linked to av av = second; // second node of list becomes front of av list first = 0; } Program 4.25 : Erasing a circular list 11/11/2018

4.6 Polynomials(Cont’) Figure 4.22 : Dashes indicate changes involved in erasing a circular list 11/11/2018

Figure 4.23 : Example polynomials 4.6 Polynomials(Cont’) Figure 4.23 : Example polynomials 11/11/2018

4.6 Polynomials(Cont’) Polynomial operator+ (const Polynomial& a, const Polynomial& b) { Term *p, *q, temp; CircListIterator<Temp> Aiter(a.poly); CircListIterator<Term> Biter(b.poly); Polynomial c; // assume the constructor creates a head node with exp = -1 p = Aiter.first(); q = Biter.First(); while(1) switch (compare(p->exp, q->exp)) { case ‘=’ : if (p->exp == -1) return c; else { int sum = p->coef + q->coef; c.poly.Attach(temp); } p = Aiter.Next(); q = Biter.Next(); break; 11/11/2018

Program 4.26 : Adding circularly represented polynomials 4.6 Polynomials(Cont’) case ‘<’ : temp.Init(q->coef, q->exp); c.poly.Attach(temp); q = Biter.Next(); break; case ‘>’ : temp.Init(p->coef, p->exp); p = Alter.Next(); } // end of switch and while } Program 4.26 : Adding circularly represented polynomials 11/11/2018

4.7 Equivalence Classes void equivalence() { initialize; while more pairs read the next pair (I, j); process this pair; } initialize for output; for (each object not yet output) output the equivalence class that contains this object; } // end of equivalence Program 4.27 : First pass at equivalence algorithm 11/11/2018

4.7 Equivalence Classes(Cont’) void equivalence() { read n; // read in number of objects initialize seq to 0 and out to FALSE; while more pairs // input pairs read the next pair (I, j); put j on the seq[i] list; put I on the seq[j] list; } for (i=0; i<n; i++) if (out[i] == FALSE) { out[i] = TRUE; output the equivalence class that contains this object i; } // end of equivalence Program 4.28 : A more detailed version of equivalence algorithm 11/11/2018

4.7 Equivalence Classes(Cont’) Figure 4.24 : Lists after pairs have been input 11/11/2018

4.7 Equivalence Classes(Cont’) enum Boolean {FALSE, TRUE}; class ListNode { friend void equivalence(); private: int data; ListNode *link; ListNode(int); }; typedef ListNode*ListNodePtr; // so we can create an array of pointers using new ListNode :: ListNode(int d) { data = d; link = 0; } 11/11/2018

4.7 Equivalence Classes(Cont’) void equivalence() // Input the equivalence pairs and output the equivalence classes { ifstream inFile(“equiv.in”, ios::in); // “equiv.in” is the input file if (!inFile) { cerr << “Cannot open input file” << endl; return; } int i, j, n; inFile >> n; // read number of objects // initialize seq and out ListNodePtr * seq = new ListNodePtr[n]; Boolean *out = new boolean[n]; for(i=0; i<n; i++){ seq[i] = 0; out[i] = FALSE; 11/11/2018

4.7 Equivalence Classes(Cont’) // Phase 1: input equivalence pairs inFile >> i>> j; while (inFile.good()) { // check end of file ListNode *x = new ListNode(j); x->link = seq[i]; seq[i] = x; // add j to seq[i] ListNode *x = new ListNode(j); x->link = seq[j]; seq[j] = x; // add j to seq[j] inFile >> i >>j; } // Phase 2:output equivalence classes for(i=0; i<n; i++) if(out[i] == FALSE) { // needs to be output cout << endl << “A new class: “ << i; out[i] = TRUE; ListNode *x = seq[i]; ListNode *top = 0; // init stack while(1) { // find rest of class while(x) { // process the list j = x -> data; 11/11/2018

4.7 Equivalence Classes(Cont’) if(out[j] == FALSE) { cout << “,” << j; out[j] = TRUE; ListNode *y = x -> link; x -> link = top; top = x; x = y; } else x = x -> link; } // end of while(x) if(!top) break; else { x = seq[top -> data]; top = top -> link; // unstack } // end of while(1) } // end of if(out[i] == FALSE) 11/11/2018

4.7 Equivalence Classes(Cont’) for(i=0; i<n; i++) while(seq[i]) { ListNode *delnode = seq[i]; seq[i] = delnode -> link; delete delnode; } delete [] seq; delete [] out; } // end of equivalence Program 4.29 : Algorithm to find equivalence classes 11/11/2018

Figure 4.25 : Node structure for sparse matrices 11/11/2018

4.8 Sparse Matrices(Cont’) Figure 4.26 : 6 × 7 sparse matrix A 11/11/2018

4.8 Sparse Matrices(Cont’) Figure 4.27 : Linked representation of the sparse matrix A of Figure 4.26 (the head data member of a node is not shown) 11/11/2018

4.8 Sparse Matrices(Cont’) Enum Boolean {FALSE, TRUE}; Struct Triple {int value, row, col;}; Class Matrix; // forward declaration Class MatrixNode { friend class Matrix; friend istream& operator >> (istream&, Matrix&); // for reading in a matrix private: MatrixNode *down, *right; Boolean head; union { // anonymous union MatrixNode *next; Triple triple; }; MatrixNode(Boolean, Triple *); // constructor 11/11/2018

4.8 Sparse Matrices(Cont’) MatrixNode::MatrixNode(Boolean b, Triple *t) // constructor { head = b; if(b) { right = next = down = this;} //row/column head node else triple = *t; // head node for list of headnodes OR element node } typedef MatrixNode *Matrix NodePtr; // to allow subsequent creation of array of pointers class Matrix friend istream& operator >> (istream&, Matrix&); public: ~Matrix(); // destructor private: MatrixNode *headnode; }; Program 4.30 : Class definition for sparse matrices 11/11/2018

4.8 Sparse Matrices(Cont’) istream& operator >> (istream& is, Matrix& matrix) // Read in a matrix and wet up its linked representation. // An auxiliary array head is used. { Triple s; int p; is >> s.row >> s.col >> s.value; // matrix dimensions if(s.row>s.col) p = s.row; else p=s.col; // set up headnode for list of head nodes. matrix.headnode = new MatrixNode(FALSE, &s); if(p == 0) {matrix.headnode -> right = matrix.headnode; return is; } // at least one row or column MatrixNodePtr *head = new MatrixNodePtr[p]; //initialize head nodes for(int i=0; i<p; i++) head[i] = new MatrixNode(TRUE,0); int CurrentRow = 0; MatrixNode *last = head[0]; // last node in current row 11/11/2018

4.8 Sparse Matrices(Cont’) for(i=0; i<s.value; i++) // input triples { Triple t; is >> t.row >> t.col >> t.value; if(t.row > CurrentRow) { //close current row last -> right = head[CurrentRow]; CurrentRow = t.row; last = head[CurrentRow]; } // end of if last = last - >right = new MatrixNode(FALSE, &t); // link new node into row list head[t.col] -> next = head[t.col] -> next - >dows = last; //link into column list } // end of for last -> right = head[CurrentRow]; // close last row for(i=0; i<s.col; i++) head[i] -> enxt -> down = head[i]; // close all column lists // link the head nodes together 11/11/2018

4.8 Sparse Matrices(Cont’) for(i=0; i<p-1; i++) head[i] -> next = head[i+1]; head[p-1] -> next = matrix.headnode; matrix.headnode -> right = head[0]; delete[] head; return is; } Program 4.31 : Reading in a sparse matrix 11/11/2018

4.8 Sparse Matrices(Cont’) Matrix::~Matrix() // Return all nodes to the av list. This list is a chain linked via the right // field. av is a global variable of type MatrixNode * and points to its first node. { if(!headnode) return; // no nodes to dispose MatrixNode *x = headnode -> right, *y; headnode -> right = av; av = headnode; // return headnode while(x != headnode) { // erase by rows y = x -> right; x -> right = av; av = y; x = x -> next; // next row } headnode = 0; Program 4.32 : Erasing a sparse matrix 11/11/2018

4.8 Sparse Matrices(Cont’) Figure 4.28 : Representation of matrix A of Figure 4.26 using the scheme of Exercise 6 11/11/2018

4.9 Doubly Linked Lists Problems with singly linked lists Node can move only in the direction of the links deletion requires knowing the preceding node Node at least three fields : data, llink(left link), rlink(right link) 11/11/2018

4.9 Doubly Linked Lists(Cont’) HeadNode LeftLink data RightLink Figure 4.29 : Doubly linked circular list with head node 11/11/2018

4.9 Doubly Linked Lists(Cont’) Head node convenient for algorithms data field usually contains no information Essential virtue one can go back and forth with equal ease p==p→llink→rlink==p→rlink→llink first Figure 4.30 : Empty doubly linked circular list with head node 11/11/2018

4.9 Doubly Linked Lists(Cont’) class DblList; class DblListNode{ friend class DblList; private: int data; DblListNode *llink, *rlink; }; class DblList{ public: // List manipulation operations private: DblListNode *first; // points to head node }; Program 4.33 : Class definition of a doubly linked list 11/11/2018

4.9 Doubly Linked Lists(Cont’) void DblList::Delete(DblListNode *x) { if ( x == first ){ cerr << "Deletion of headnode not permitted?<< endl; }else{ x->llink->rlink = x->rlink; x->rlink->llink = x->llink; delete x; } } Program 4.34 : Deletion from a doubly linked circular list 11/11/2018

4.9 Doubly Linked Lists(Cont’) x  llink x x  rlink Figure 4.31 : Deletion from a doubly linked circular list 11/11/2018

4.9 Doubly Linked Lists(Cont’) void DblList::Insert(DblListNode *p, DblListNode *x) // insert node p to the right of node x { p->llink = x; p->rlink = x->rlink; x->rlink->llink = p; x->rlink = p; } Program 4.35 : Insertion into a doubly linked circular list 11/11/2018

4.9 Doubly Linked Lists(Cont’) p x 11/11/2018

4.10 Generalized Lists Figure 4.32 : Representation of 3x2y 11/11/2018

4.10 Generalized Lists(Cont’) Figure 4.33 : Representation of P (x, y, z) 11/11/2018

4.10 Generalized Lists(Cont’) Figure 4.34 : Representation of lists (1) to (4) 11/11/2018

4.10 Generalized Lists(Cont’) // Driver void GenList::Copy(const GenList& l) { first = Copy(l.first); } // Workhorse GenListNode* GenList::Copy(GenListNode* p) { // Copy the nonrecursive list with no shared sublists pointed at by p GenListNode *q = 0; if(p) { q = new GenListNode; q -> tag = p -> tag; if (!p -> tag) q -> data = p -> data; else q -> dlink = Copy(p -> dlink); q -> link = Copy(p -> link); return q; Program 4.36 : Copying a list 11/11/2018

4.10 Generalized Lists(Cont’) Figure 4.35 : Linked representation for A 11/11/2018

4.10 Generalized Lists(Cont’) Figure 4.36 : Values of parameters in execution of GenList :: Copy (A) 11/11/2018

4.10 Generalized Lists(Cont’) // Driver – assumed to be a friend of GenList int operator == (const GenList& l, const GenList& m) { // l and m are non-recursive lists. // The function returns 1 if the two lists are identical and 0, otherwise. return equal(l.first, m.first); } // Workhorse – assumed to be a friend of GenListNode int equal(GenListNode* s, GenListNode *t) { int x; if ((!s) && (!t)) return 1; if (s && t && (s -> tag == t -> tag)){ if (!s -> tag) if (s -> data == t -> data) x =1; else x = 0; else x = equal(s -> dlink, t -> dlink); if (x) return equal(s -> link, t -> link); return 0; Program 4.37 : Determining if two lists are identical 11/11/2018

4.10 Generalized Lists(Cont’) // Driver int GenList::depth() P // Compute the depth of a non-recursive list return depth(first); } // Workhorse int GenList::depth(GenListNode *s) { if (!s) return 0; GenListNode *p = s; int m = 0; while(p) { if (p -> tag) { int n = depth(p -> dlink); if (m < n) m = n; p = p -> link; return m+1; Program 4.38 : Computing the depth of a list 11/11/2018

4.10 Generalized Lists(Cont’) Figure 4.37 : Structure with head nodes for lists (1) to (4) 11/11/2018

4.10 Generalized Lists(Cont’) Figure 4.38 : t = (3x4 + 5x3 + 7x)y3, u = (3x4 + 5x3 + 7x)y6 + (6x)y 11/11/2018

4.10 Generalized Lists(Cont’) // Driver GenList::~GenList() { // Each head node has a reference count. We assume first ≠ 0. Delete(first); first = 0; } // Workhorse void GenList::Delete(GenListNode* x) { x -> ref--; //decrement reference count of head node. if (!x -> ref) GenListNode *y = x; // y traverses top-level of x. while (y -> link) { y = y -> link; if ( y -> tag==1) Delete (y -> dlink);} y -> link = av; // attach top-level nodes to av list av = x; Program 4.39 : Erasing a list recursively 11/11/2018

4.10 Generalized Lists(Cont’) Figure 4.39 : Indirect recursion of lists A and B pointed to by program variables r and s 11/11/2018

4.11 Virtual Functions and Dynamic Binding in C++ Dynamic types consequence of public inheritance a pointer (reference) to a derived class type is implicitly converted to a pointer (reference) to its base class example Rectangle IS-A Polygon a pointer to a Polygon type can be assigned the address of a Rectangle object Rectangle r ; Polygon *s = &r; (derived) (base) (derived) supported by C++ virtual functions dynamically bound : the operation corresponding to the dynamic type of the object that invoked it, is used the dynamic type of s is Rectangle 11/11/2018

4.11 Virtual Functions and Dynamic Binding in C++(Cont’) class Polygon { public: int GetId(); // non-virtual member function virtual Boolean Concave(); // virtual member function virtual int Perimeter() = 0; // pure virtual member function protected: int id; }; 11/11/2018

4.11 Virtual Functions and Dynamic Binding in C++(Cont’) class Rectangle : public Polygon // Rectangle publicly inherits from Polygon { public: Boolean Concave(); // redefined in Rectangle int Perimeter; // defined in Rectangle // GetId() and id are inherited from Polygon // They, respectively, become public and protected members of Rectangle private: // additional data members required to specialize Rectangle int x1, y1, h, w; }; 11/11/2018

4.11 Virtual Functions and Dynamic Binding in C++(Cont’) // GetId() must never be redefined in a derived class int Polygon::GetId() { return id;} // Default implementation of Concave() in Polygon. A Polygon is // concave if it is possible to construct a line joining two points // in the polygon that does entirely lie within the polygon. Boolean Polygon::Concave(){ return TRUE;} // Rectangle must define Perimeter() because it is a pure virtual // function. int Rectangle::Perimeter{return 2*(h + w);} // The default implementation of Concave() does not apply to // rectangles. So, it has to be redefined. Boolean Rectangle::Concave{ return FALSE; } Program 4.40 : Public inheritance 11/11/2018

4.11 Virtual Functions and Dynamic Binding in C++(Cont’) Three types of member functions (a) Virtual member function its prototype is preceded by the keyword virtual if a virtual function, whose implementation is redefined in a derived class, is invoked by a base class, then the implementation corresponding to the current dynamic type of that base class object is used Rectangle r; . . // assume r is initialized at this point Polygon *s = &r; s->Concave(); // returns FALSE Program 4.41 : Virtual member function operation 11/11/2018

4.11 Virtual Functions and Dynamic Binding in C++(Cont’) (b) Non-virtual member function not preceded by the virtual keyword in the base class use non-virtual functions in base classes only if they will not be redefined in a derived class (if redefined, there is an inconsistency) Rectangle r; . . // assume r is initialized at this point Polygon *s = &r; s->GetId(); // uses the function implemented in Polygon Rectangle *t = &r; t->GetId(); // uses the function implemented in Rectangle Program 4.42 : Reimplementing a non-virtual function 11/11/2018

4.11 Virtual Functions and Dynamic Binding in C++(Cont’) (c) Pure virtual function it is not implemented by its class it is assigned value 0 to indicate that it is pure abstract class base class with pure virtual functions consequences not allowed to create instances of the abstract class Polygon p; // illegal Polygon *q; // legal Pure virtual function must be redefined in the derived class a base class must support a particular function, but the implementation requires additional information 11/11/2018

4.11 Virtual Functions and Dynamic Binding in C++(Cont’) Rectangle r; // assume r is initialized at this point Polygon *s = &r; s->Perimeter(); // returns perimeter of r Program 4.43 : Pure, virtual member function operation 11/11/2018

4.11 Virtual Functions and Dynamic Binding in C++(Cont’) struct Data { int id; // id = 0,1, or 2 if the node contains a char, an int, or float, respectively union { int i; char c; float f; }; class CombinedNode // use union to merge different node types into one class definition friend class List; friend clas ListIterator; private: Data data; CombinedNode *link; 11/11/2018

4.11 Virtual Functions and Dynamic Binding in C++(Cont’) class List { friend class ListIterator; public: // List manipulation operations follow . private: CombinedNode *first; }; // class ListIterator is defined as in Section 4.3, except that the return types // of First and Next are Data* Program 4.44 : Using union to implement a list of mixed nodes 11/11/2018

4.11 Virtual Functions and Dynamic Binding in C++(Cont’) // struct Data is assumed to be defined as in Program 4.44 class Node { friend class List; friend class ListIterator; protected: Node *link; virtual Data GetData() = 0; }; template<class Type> class DerivedNode : public Node { friend class List; friend class ListIterator; public: DerivedNode(Type item) : data(item) { link = 0; }; private: Type data; Data GetData(); 11/11/2018

4.11 Virtual Functions and Dynamic Binding in C++(Cont’) Data DerivedNode<char>::GetData() { Data t; t.id = 0; t.c = data; return t; } // The implementations of GetData() for DerivedNode<int> and DerivedNode<float> // are similar to that of DerivedNode<char>::GetData(). class List { friend class ListIterator; public: // List manipulation operations follow . private: Node *first; }; 11/11/2018

4.11 Virtual Functions and Dynamic Binding in C++(Cont’) class ListIterator { public: ListIterator(const List& l): list(l), current(l.first) {}; Data* First(); // minor change in homogeneous list implementation Data* Next(); // minor change in homogeneous list implementation Boolean NotNull(); // implemented as for homogeneous lists Boolean NextNotNull(); // implemented as for homogeneous lists private: const List& list; Node* current; Data temp; }; Data* ListIterator::First() { if(list.first) { temp = list.first -> GetData(); // use GetData to retrieve element return &temp; } return 0; Program 4.45 : Using public inheritance to implement a list of mixed nodes 11/11/2018