1 / 63

Chap 4

Chap 4. Linked Lists. Previously introduced data structures, including array, queue, and stack, they all have the property that successive nodes of data object were stored a fixed distance apart.

janine
Download Presentation

Chap 4

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. Chap 4 Linked Lists

  2. Previously introduced data structures, including array, queue, and stack, they all have the property that successive nodes of data object were stored a fixed distance apart. The drawback of sequential mapping for ordered lists is that operations such as insertion and deletion become expensive. Also sequential representation tends to have less space efficiency when handling multiple various sizes of ordered lists. Review of Sequential Representations

  3. A better solutions to resolve the aforementioned issues of sequential representations is linked lists. Elements in a linked list are not stored in sequential in memory. Instead, they are stored all over the memory. They form a list by recording the address of next element for each element in the list. Therefore, the list is linked together. A linked list has a head pointer that points to the first element of the list. By following the links, you can traverse the linked list and visit each element in the list one by one. Linked List

  4. To insert an element into the three letter linked list: Get a node that is currently unused; let its address be x. Set the data field of this node to GAT. Set the link field of x to point to the node after FAT, which contains HAT. Set the link field of the node cotaining FAT to x. Linked List Insertion

  5. Linked List Insertion And Deletion first CAT BAT EAT FAT HAT GAT first CAT BAT EAT FAT GAT HAT

  6. Design Attempt 1: Use a global variable first which is a pointer of ThreeLetterNode. Unable to access to private data members: data and link. Design Attempt 2: Make member functions public. Defeat the purpose of data encapsulation. Design Attempt 3: Use of two classes. Create a class that represents the linked list. The class contains the items of another objects of another class. Designing a List in C++

  7. class ThreeLetterList; // forward delcarion 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

  8. The Three Letter List problem can also use nested classes to represent its structure. class ThreeLetterList { public: // List Manipulation operations . . private: class ThreeLetterNode { // nested class public: char data[3]; ThreeLetterNode *link; }; ThreeLetterNode *first; }; Nested Classes

  9. x a y b Pointer Manipulation in C++ • Addition of integers to pointer variable is permitted in C++ but sometimes it has no logical meaning. • Two pointer variables of the same type can be compared. • x == y, x != y, x == 0 x a b x y b b y x = y *x = * y

  10. A linked list is a container class, so its implementation is a good template candidate. Member functions of a linked list should be general that can be applied to all types of objects. When some operations are missing in the original linked list definition, users should not be forced to add these into the original class design. Users should be shielded from the detailed implementation of a linked list while be able to traverse the linked list. Solution => Use of ListIterator Define A Linked List Template

  11. A list iterator is an object that is used to traverse all the elements of a container class. ListIterator<Type> is delcared as a friendof both List<Type> and ListNode<Type>. A ListIterator<Type> object is initialized with the name of a List<Type> object l with which it will be associated. The ListIterator<Type> object contains a private data member current of type ListNode<Type> *. At all times, current points to a node of list l. The ListIterator<Type> object defines public member functions NotNull(), NextNotNull(), First(), and Next() to perform various tests on and to retrieve elements of l. List Iterator

  12. 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; }; Template of Linked Lists

  13. 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 }; Template of Linked Lists (Cont.)

  14. Template <class Type> Void List<Type>::InsertBack(Type k) { ListNode<Type>*newnode = new ListNode<Type>(k); if (first == 0) first = last =newnode; else { last->link = newnode; last = newnode; } }; Attaching A Node To The End Of A List

  15. Template <class Type> void List<Type>:: Concatenate(List<Type> b) // this = (a1, …, am) and b = (b1, …, bn) m, n ≥ , // 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; } } Concatenating Two Chains

  16. Reversing a list Template <class Type> void List<Type>:: Reverse( ) // List is reversed so that (a1, …, am) becomes (am, …, a1) . { ListNode <Type> *current = first; *previous = 0; //previous trails current while (current) { ListNode <Type> *r = previous; previous = current; current = current -> link; previous->link = r; } first = previous; }

  17. If efficiency becomes a problem when reuse one class to implement another class. If the operations required by the application are complex and specialized, and therefore not offered by the class. When Not To Reuse A Class

  18. By having the link of the last node points to the first node, we have a circular list. Need to make sure when current is pointing to the last node by checking for current->link == first. Insertion and deletion must make sure that the circular structure is not broken, especially the link between last node and first node. Circular Lists

  19. Diagram of A Circular List first last

  20. Linked Stacks and Queues top front rear 0 Linked Queue 0 Linked Stack

  21. 1 a.first 14 0 8 3 0 2 6 10 b.first 14 0 8 10 -3 Revisit Polynomials

  22. struct Term // all members of Terms 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; }; Polynomial Class Definition

  23. With linked lists, it is much easier to perform operations on polynomials such as adding and deleting. E.g., adding two polynomials a and b Operating On Polynomials a.first 1 0 14 0 8 3 2 p 6 10 14 0 8 b.first 10 -3 q (i) p->exp == q->exp c.first 0 14 11

  24. Operating On Polynomials a.first 1 0 14 0 8 3 2 p 6 10 14 0 8 b.first 10 -3 q c.first 0 14 0 11 10 -3 (ii) p->exp < q->exp

  25. 0 14 11 Operating On Polynomials a.first 1 0 14 0 8 3 2 p 6 10 14 0 8 b.first 10 -3 q c.first 10 -3 0 8 2 (iii) p->exp > q->exp

  26. When polynomials are created for computation and then later on out of the program scope, all the memory occupied by these polynomials is supposed to return to system. But that is not the case. Since ListNode<Term> objects are not physically contained in List<Term> objects, the memory they occupy is lost to the program and is not returned to the system. This is called memory leak. Memory leak will eventually occupy all system memory and causes system to crash. To handle the memory leak problem, a destructor is needed to properly recycle the memory and return it back to the system. Memory Leak

  27. Template <class Type> List<Type>::~List() // Free all nodes in the chain { ListNode<Type>* next; for (; first; first = next) { next = first->link; delete first; } } List Destructor

  28. When items are created and deleted constantly, it is more efficient to have a circular list to contain all available items. When an item is needed, the free pool is checked to see if there is any item available. If yes, then an item is retrieved and assigned for use. If the list is empty, then either we stop allocating new items or use new to create more items for use. Free Pool

  29. By using circular lists for polynomials and free pool mechanism, the deleting of a polynomial can be done in a fixed amount of time independent of the number of terms in the polynomial. Using Circular Lists For Polynomials

  30. Deleting A Polynomial with a Circular List Structure av 3 a.first 1 0 14 8 3 2 1 second 2 av

  31. For any polygon x, x ≡ x. Thus, ≡ is reflexive. For any two polygons x and y, if x ≡ y, then y ≡ x. Thus, the relation ≡ is symetric. For any three polygons x, y, and z, if x ≡ y and y ≡ z, then x ≡ z. The relation ≡ is transitive. Equivalence Class

  32. Definition: A relation ≡ over a set S, is said to be an equivalence relation over S iff it is symmetric, reflexive, and transitive over S. Example: Supposed 12 polygons 0 ≡ 4, 3 ≡ 1, 6 ≡ 10, 8 ≡ 9, 7 ≡ 4, 6 ≡ 8, 3 ≡ 5, 2 ≡ 11, and 11 ≡ 0. Then they are partitioned into three equivalence classes: {0, 2, 4, 7, 11}; {1 , 3, 5}; {6, 8, 9 , 10} Equivalence

  33. Two phases to determine equivalence In the first phase the equivalence pairs (i, j) are read in and stored. In phase two, we begin at 0 and find all pairs of the form (0, j). Continue until the entire equivalence class containing 0 has been found, marked, and printed. Next find another object not yet output, and repeat the above process. Equivalence (Cont.)

  34. If a Boolean array pairs[n][n] is used to hold the input pairs, then it might waste a lot of space and its initialization requires complexity Θ(n2) . The use of linked list is more efficient on the memory usage and has less complexity, Θ(m+n) . Equivalence Classes (Cont.)

  35. Linked List Representation [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] data 11 3 11 5 7 3 8 4 6 8 6 0 link 0 0 0 0 0 0 data 4 1 0 10 9 2 link 0 0 0 0 0 0

  36. Sequential representation of sparse matrix suffered from the same inadequacies as the similar representation of Polynomial. Circular linked list representation of a sparse matrix has two types of nodes: head node: tag, down, right, and next entry node: tag, down, row, col, right, value Head node i is the head node for both row i and column i. Each head node is belonged to three lists: a row list, a column list, and a head node list. For an nxm sparse matrix with r nonzero terms, the number of nodes needed is max{n, m} + r + 1. Linked List for Sparse Matrix

  37. Node Structure for Sparse Matrices down tag right down tag row col right f i j next value Head node Typical node Setup for aij A 4x4 sparse matrix

  38. 4 0 1 3 4 2 0 3 Linked Representation of A Sparse Matrix H1 H3 H2 H0 Matrix head H0 11 H1 12 2 1 H2 -4 H3 -15

  39. Assume the first line consists of the number of rows, the number of columns, and the number of nonzero terms. Then followed by num-terms lines of input, each of which is of the form: row, column, and value. Initially, the next field of head node i is to keep track of the last node in column i. Then the column field of head nodes are linked together after all nodes has been read in. Reading In A Sparse Matrix

  40. Input complexity: O(max{n, m} + r) = O(n + m + r) Complexity of ~Maxtrix(): Since each node is in only one row list, it is sufficient to return all the row lists of a matrix. Each row is circularly linked, so they can be erased in a constant amount of time. The complexity is O(m+n). Complexity Analysis

  41. The problem of a singly linked list is that supposed we want to find the node precedes a node ptr, we have to start from the beginning of the list and search until find the node whose link field contains ptr. To efficiently delete a node, we need to know its preceding node. Therefore, doubly linked list is useful. A node in a doubly linked list has at least three fields: left link field (llink), a data field (item), and a right link field (rlink). Doubly Linked Lists

  42. A head node is also used in a doubly linked list to allow us to implement our operations more easily. Doubly Linked List rlink item llink Head Node rlink item llink Empty List

  43. Deletion From A Doubly Linked Circular List rlink item llink Head Node x -> left -> right = x -> right x -> right -> left = x -> left

  44. Insertion Into An Empty Doubly Linked Circular List node node x x p newnode p p -> left = x; p -> right = x -> right; x -> right -> left = p; x -> right = p;

  45. Definition: A generalized list, A, is a finite sequence of n ≥ 0 elements, α0, α1, α2, …, αn-1, where αi, is either an atom or a list. The elements αi,0≤ i ≤ n – 1, that are not atoms are said to be the sublists of A. A list A is written as A = (α0, …, αn-1 ), and the length of the list is n. Conventionally, a capital letter is used to represent a list and a lower case letter is to represent an atom. The α0 is the head of list A and the rest (α1, …, αn-1) is the tail of list A. Generalized Lists

  46. D = ( ): the null, or empty, list; its length is zero. A = (a, (b, c)): a list of length of two; its first element is the atom a, and its second element is the linear list (b, c). B = (A, A, ( )): A list of length of three whose first two elements are the list A, and the third element is the null list D. C = (a,C): is a recursive list of length two;Ccorresponds to the infinite listC = (a, (a, (a, …))). Generalized List Examples

  47. head(A) = ‘a’ and tail(A) = (b, c), head(tail(A) ) = (b, c) and tail(tail(A)) = (). Lists may be shared by other lists Lists may be recursive. Generalized Lists

  48. Generalized List Application Example • Consider the polynomial P(x, y, z) with various variables. It is obvious the sequential representation is not suitable to this. • What if a linear list is used? • The size of the node will vary in size, causing problems in storage management. • Let’s try the generalized list.

  49. Generalized List Application Example • P(x, y, z) can be rewritten as follows: • The above can be written as Cz2 + Dz. Both C and D are polynomials themselves but with variables x and y only. • If we look at polynomial C only, it is actually of the form Ey3 + Fy2, where E and F are polynomial of x only. • Continuing this way, every polynomial consists of a variable plus coefficient-exponent pairs. Each coefficient is itself a polynomial.

  50. enum Triple{ var, ptr, no }; class PolyNode { PolyNode *link; int exp; Triple trio; union { char vble; PolyNode *dlink; int coef; }; }; PolyNode Class in C++

More Related