660 likes | 902 Views
Advance Data Structure Review of Chapter 4. 張啟中. Overview of Chapter 4. Type of List 4.1 Singly Linked Lists 4.2 Representing Lists in C++ 4.3 Reusable Linked List Class 4.4 Circular Lists 4.9 Doubly Linked Lists 4.10 Generalized Lists 4.12 Heterogeneous Lists Example
E N D
Overview of Chapter 4 • Type of List • 4.1 Singly Linked Lists • 4.2 Representing Lists in C++ • 4.3 Reusable Linked List Class • 4.4 Circular Lists • 4.9 Doubly Linked Lists • 4.10 Generalized Lists • 4.12 Heterogeneous Lists • Example • 4.5 Linked Stacks and Queues • 4.6 Polynomials • 4.7 Equivalence Classes • 4.8 Sparse Matrices
Array-Based Ordered List • 優點 • 可隨意存取任何節點 O(1) • 缺點 • 儲存空間固定,而且必須事先指定。 • 插入與刪除需較多的時間 O(n) 如何改進?
0 1 2 k-1 MaxSize -1 k 12 3 19 10 18 ? ? 0 1 2 k MaxSizre -1 k+1 12 3 5 10 18 ? 0 1 2 k MaxSize -1 k+1 12 3 44 5 10 18 ? Array-Based Ordered List: Insert Insert (2, 44)
Delete 0 1 2 k-1 MaxSize -1 k 12 3 19 10 18 ? ? 0 1 2 k-1 MaxSize -1 k 12 3 10 18 ? ? 0 1 2 k-2 k-1 MaxSize -1 k-1 12 3 34 18 ? ? ? Array-Based Ordered List: Delete Delete(2)
HAT 15 CAT 4 EAT 9 WAT 0 BAT 3 FAT 1 VAT 7 … … Linked List data link 1 2 3 4 5 6 7 8 9 10 11
Linked List 的優缺點 • 資料不一定要以連續的記憶體儲存,可以任意的放置。 • 儲存空間不受限制,且不需事先指定 • 資料新增與刪除,不需搬移其餘資料 • 新增與刪除操作時間為 O(1) • 由於資料可能放置在記體位置,所以存取資料必須一個一個的循序操作,無法隨意存取。 • 存取資料需 O(n)
first BAT CAT EAT WAT first BAT CAT EAT WAT 0 Singly Linked Lists Circular Lists
Doubly Linked Lists Head Node LeftLink data RightLink - BAT CAT EAT F A T T 0 0 F B F C 0 Generalized Lists P
first BAT 123 John 50.2 0 170 58 Heterogeneous Lists
x GAT 0 Singly Linked Lists: Insert first BAT CAT EAT FAT HAT 0 (3) (2) (1)
x Singly Linked Lists: Delete (2) (3) first BAT CAT EAT FAT HAT 0 (1)
Implementing Node of Linked Lists • The Node of Linked list include: • Data field: 儲存資料 • Link field: 指向下一個 node • 根據需求,定義出 List Node 的 class • Example: class ThreeLetterNode { private: char data[3]; ThreeLetterNode *link; };
Implementing Linked Lists • 依據 List Node 的定義,設計 Lists,可能有以下三種的設計方法: • Design Attempt 1 • Use a global variable which is a pointer of ListNode • Example: ThreeLetterNode *first; • Unable to access to private data members: data and link. • Design Attempt 2 • Make public member functions in class ListNode. • Defeat the purpose of data encapsulation. • Design Attempt 3 • Composition Class (HAS-A) • Friend Classes. • Nested Classes. • Inheritance with private
Composition by Friend Classed //forward delcarion class ThreeLetterList; class ThreeLetterNode { friend class ThreeLetterList; private: char data[3]; ThreeLetterNode * link; }; class ThreeLetterList { public: //List Manipulation operations . private: ThreeLetterNode *first; }; Design Attempt 3: Composition Classes • Composition by Nested Classed class ThreeLetterList { public: //List Manipulation operations . . private: //nested class class ThreeLetterNode { public: char data[3]; ThreeLetterNode *link; }; ThreeLetterNode *first; };
first first BAT BAT CAT CAT EAT EAT WAT WAT 0 0 Design Attempt 3: Composition Classes List Manipulation operations == interface 概念圖 ThreeLetterNode ThreeLetterList 實體圖 ThreeLetterNode
Design Attempt 3: Composition Classes • Linked Lists 的所有節點資料完全隱藏,外界無法直接操作或存取節點資料,達成封裝(Encapsulation)的目的。 • Linked Lists 的成員函式(member functions)可以自由存取 Linked Lists Node 的資料。 • 外界程式必須透過 Liked List 的成員函式來操作並存取節點資料。 • Linked Lists Node 必須依實際需求重新設計,連帶 Linked Lists 的操作也需要修正!不夠完美,如何改進?
Design Attempt 3: Composition Classes 改進方式 • Linked Lists Node 要能夠應付不同的資料型態,如何辦到? • 用 C++ 的 template 機制! • Linked Lists 的成員函式必須要能夠操作不同資料型態的 Linked List Node • 設計一個新的 iterators class,負責去指向要操作的資料節點,Linked List 成員函式則利用 iterators來存取節點資料。
Design Linked Lists with Template template <classType> classList ; //forward declaration template <classType> classListNode { friendclassList<Type>; private: Typedata; ListNode *link; }; template <classType> classList { public: List() { first = 0;} //constructor initializing first to 0 // List manipulation operations …… private: ListNode<Type> *first; };
Container and Iterators • Containers (容器) • A container class is a class that represents a data structure that stores a number of data objects. (see book p121) • Iterators (迭代器) • An iterator is an object that is used to traverse all the elements of a container class.
Linked Lists Iterators template <classType> classListIterator { public: ListIterator(const List<Type> &l):list(l),current(l.first){}; boolNotNull(); boolNextNotNull(); Type* First(); Type* Next(); private: constList<Type>& list; // refers to an existing list ListNode<Type>* current; // points to a node in list } ; Member function: see book p180. Program 4.9
Linked Lists Iterators Member Function template <classType> //check that the current element in list is non-null BooleanListIterator <Type>::NotNull() { if (current) returnTRUE ; elsereturnFALSE ; } template <class Type> //check that the next element in list is non-null BooleanListIterator <Type>::NextNotNull() { if (current && current->link) returnTRUE ; elsereturnFALSE ; }
Linked Lists Iterators Member Function template <classType> //return a pointer to the first element of list Type* ListIterator <Type>::First() { if (list.first) return &list.first->data ; elsereturn 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 ¤t->data ; } elsereturn 0 ; }
Design Linked Lists with Template List Node template <classType> classList ; //forward declaration template <classType> classListNode { friendclassList<Type>; friend class ListIterator <Type>; private: Typedata; ListNode *link; }; Lists template <classType> classList { friend class ListIterator <Type>; public: List() { first = 0;}//constructor initializing first to 0 //List manipulation operations …… private: ListNode<Type> *first; };
Reusing the Linked Lists Class • 在大部分的應用中,我們會採取前面所設計的一般化的 Linked Lists Class 來解決問題。 • 但有些情況,我們則必須直接設計新的 Linked Lists class,例如: • 考量執行效率。 • stacks 與 queues 的實作 • 問題較複雜且有特別的需求時。 • 找出 equivalence class 。
last BAT CAT EAT WAT first BAT CAT EAT WAT Circular Lists Check Last Node:current->link == first; Use thelast nodeinstead ofthefirst node
first - first - BAT CAT EAT WAT Circular Lists with dummy head node Empty List
Deconstruct a Linked Lists • 由於 Linked Lists 的 Node 是透過 new 配置的,所以必須於解構子中以 delete 收回,以避免 memory leak 的問題。 • 二個方法 • 直接刪除 • 必須依序將每一個節點刪除,切不可以直接 delete first. • Free Pool • 不刪除節點,將這些欲收回的節點組織成一個 available-space list or av list (資料成員 static ListNode<Type> *av) • 往後新增節點時,先檢查 Free Pool,若 Free Pool不為空,則從 Free Pool 取出一個節點配置出去,反之,若 Free Pool 為空,才 new 一個新的空節點或停止配置空間。 • Free Pool 使 Liked Lists的解構動作於常數時間完成。
Deconstruct a Linked Lists • 直接刪除節點 template <class Type> List<Type>::~List() //Free all nodes in the chain { ListNode<Type>* next; for (; first; first = next) { next = first->link; delete first; } } Time Complexity O(n)
av = second second Deconstruct a Linked Lists • Free Pool (4) (3) (1) first = 0 (2) av 0
Doubly Linked Lists • 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 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 };
Doubly Linked Lists first LeftLink data RightLink - BAT CAT EAT p->llink->rlink == p == p->rlink->llink first - Empty doubly linked circular list with head node
void DblList::Delete(DblListNode *x) { if (x==first) cerr<<“Deletion of head node not permitted”<<endl; else { x->llink->rlink = x->rlink; x->rlink->llink = x->llink; } } Doubly Linked Lists: Delete first - x CAT
Doubly Linked Lists: Insert first - p x 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; }
Generalized List • Generalized List • A generalized list, A, is a finite sequence of n>= 0 elements, a0,…,an-1, where ai is either an atom or a list. • The elementsai, 0≦i≦n-1, that are not atoms are said to be sublists of A. • Examples • D=() • A= (a, (b, c)) • B= (A, A, ()) • C= (a, C) • Consequences • Lists may be empty (Example D) • lists may be shared by other lists (Example B) • lists may be recursive (Example C)
Generalized List • D=() • A= (a, (b, c)) • B= (A, A, ()) • C= (a, C) D=0 A F a T 0 F b F c 0 B T T T 0 0 C F a T 0
Important Generalized List Functions • List Copy • See textbook pp225-227 • Program 4.36 • List Equality • See textbook pp228 • Program 4.37 • List Depth • See textbook pp229 • Program 4.38
Lists Copy • 串列有兩種拷貝的方式: • 淺拷貝(shallow copy):不拷貝資料項目 • 深拷貝(deep copy):拷貝資料項目 L 淺拷貝 20 45 51 76 L’ L 20 45 51 76 深拷貝 L’ 20 45 51 76
List Copy with Recursive Algorithms • Indirect Recursive • A recursive algorithm consists of two components: • The recursive function (the workhorse); • Declared as a private function • A second function that invokes the recursive function at the top level (the driver); • declared as a public function.
List Copy Driver void GenList::Copy(const GenList& l) { first = Copy(l.first); } 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; } Workhorse O(M)
Example: List Copy A (Generalized Lists) A r b t t 0 t u v s f a f b 0 t f e 0 w x f c f d 0 A((a,b),((c,d),e))
Example: List Copy A (Generalized Lists) GenList::Copy(A)
List Depth • The Depth of list is defined as follows. • An empty list has depth 0.
Heterogeneous list • A heterogeneous list is one that contains nodes of different types. • If merging nodes by using union, then each node is allocated for the largest node type. This would waste space. • Use of public inheritance and virtual functions can resolve this issue. • Let S(x) denote the space occupied by an object of type x, then S(CombinedNode)=S(Data)+S(CombineNode *) =S(int) + max(S(char), S(int), S(float)) + S(CombineNode *)
Heterogeneous list with union struct Data { // id = 0, 1, or 2 if the node contains a char, an int, ora float int id; union { int i; char c; float f; }; }; class CombinedNode //Use union to merge different node types into one class definition { friendclass List; friendclass ListIterator; private: Data data; CombinedNode *link; }; Space allocation is based on the largest data type, which is float.
Heterogeneous list with union class list { friendclass ListIterator; public: // List manipulation operations follow . private: CombinedNode *first; }; //the return type of class ListIterator is Data*
Heterogeneous list with Public Inheritance class Node { friend class List; friend class ListIterator; protected: Node *link; virtual Data GetData() = 0; }; template<class Type> class DerivedNode: public Node { friendclass List; friend class ListIterator; public: DerivedNode(Type item): data(item) {link = 0;}; private: Type data; Data GetData(); }; Data DerivedNode<char>::GetData() { Data t; t.id = 0; t.c = data; return t; }
Heterogeneous list with Public Inheritance class List { friendclass ListIterator; public: Node *first; }; 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; };
Heterogeneous list with Public Inheritance • Key point • using the dynamic typing through public inheritance, a pointer to a Node* may be used to point to nodes of type • DerivedNode<char> • DerivedNode<int> • DerivedNode<float>. • This eliminates the problem that necessitated the artificial union of the different node types