590 likes | 666 Views
Chap 3 Linked Lists. Vocabulary. Linear List 线性表 Linked List 链表 Retrieval 检索 Traversal 遍历 Node 结点
E N D
Vocabulary • Linear List 线性表 • Linked List 链表 • Retrieval 检索 • Traversal 遍历 • Node 结点 • Circularly Linked Lists 循环链表 • Doubly Linked Lists 双向链表 • Multilinked Lists 多重链表
3.1 Linear List • Definition: A linear list is a list in which each element has a unique successor. Array is a typical linear list structure. • Property: sequential Element 1 Element 2 Element 3 Element4
Linear Lists • Classification General Restricted Unordered Ordered FIFO (queue) LIFO (stack)
10 20 30 Insertion Inserted Data 25 20 10 25 30 • Operation Insertion: Depending on the type of general list, an insertion can be made at the beginning of the list, in the middle of the list, or at the end of the list. If data is inserted into ordered lists, the ordering of the list must be maintained. Maintaining the order may require a search algorithm to determine where the data are to be placed. list data
Deletion: Deletion from a general list requires that the list be searched to locate the data being deleted. Any sequential search algorithm can be used to locate the data. When data are deleted from a random array, the data following the deleted item must be shifted to replace the empty element. Delete element identified search list green blue red yellow Deletion red blue green yellow
Retrieval: List retrieval requires that data be located in a list and presented to the calling module without changing the contents of the list. Retrieved element identified by search list cat zebra dog goldfish Retrieval dog dog goldfish cat zebra
Traversal: List traversal is a special case of retrieval in which all elements are retrieval in sequence. List traversal requires a looping algorithm rather than a search. Each execution of the loop processes one element in the list. The loop terminates when all elements have been processed.
3.2 Linked list • Definition: A linked list is an ordered collection of data in which each element contains the location of the next element; that is , each element contains two parts: data and link. The data part holds the useful information, the data to be processed. The link is used to chain the data together. It contains a pointer that identified the next element in the list. a singly linked list: a linked list contains only one link to a single successor.
data data link link • The major advantage of the linked list: the data of the linked list can be easily inserted and deleted. • Nodes: The elements in a linked list are called nodes. pHead data link A linked list with a head pointer: pHead pHead An empty linked list
metadata List count <integer> head <pointer> End List Node data <datatype> link <pointer> End Node count head Head structure data link Data node structure dataType key <keyType> field1 <…> field2 <…> … fieldN <…> End dataType • Linked List Data Structure Head Node Structure: It usually contains two parts: a pointer and metadata which are data about data in the list. Data Node Structure: The data type for the list depends entirely on the application. A typical data type is like:
list list ? 0 ? count count head head (a) before create (b) after create 3.3 Linked List Algorithms • Create List: it receives the head structure and initializes the metadata for the list. • The pseudocode algorithms: Algorithm createList(ref list <metadata>) Initializes metadata for a linked list. Pre list is metadata structure passed by reference Post metadata initialized 1 list.head = null 2 list.count = 0 3 return End createList list.head = null list.count = 0
Insert Node: 1.Allocate memory for the new node and insert data. 2.Point the new node to its successor. 3.Point the new node’s predecessor to the new node. We discuss four situation : insert into empty list insert at beginning insert in middle insert at end
75 0 head count pNew (a) before add 75 1 head count pNew (b) after add Insert into empty list: pNew->link = list.head Set link to null pointer List.head = pNew Point list to first node
Before add 75 1 head count 39 pNew After add 75 1 head count 39 pNew Logically,inserting into an empty list is the same as inserting at the beginning of a list. Insert at beginning: pNew->link = list.head List.head = pNew
Before add 39 75 2 head count 52 pNew pPre Insert in middle: pNew->link = pPre->link pPre->link = pNew After add 39 75 3 head count pPre 52 pNew
Before add 39 52 75 3 head count 134 pPre pNew After add 39 52 75 3 head count 134 pPre pNew Insert at end: pNew->link = pPre->link pPre->link = pNew
Insert data into a new node in the linked list Pre List is metadata structure to a valid list pPre is pointer to data’s logical predecessor dataIn contains data to be inserted Post data have been inserted in sequence Return true if successful , false is memory overflow • Algorithm insertNode (ref list < metadata >, • val pPre <node pointer>, • val dataIn <dataType>) • allocate(pNew) • if (memory overflow) • 1 return false • end if • pNew->data=dataIn • if (pPre null) • 1 pNew-.link =list.head • 2 list.head = new • else • 1 pNew->link = pPre->link • 2 pPre->link = pNew • end if • list.count = list.count+1 • Return ture • end insertNode Insert node algorithm:
Delete Node:this algorithm logically removes a node from the linked list by: 1. changing various link pointers and then 2. physically deleting the node from dynamic memory. We discuss two situation : delete first node (delete the only node in the list) general delete case (delete the middle or last node)
Before delete 39 75 134 3 head count pLoc pPre After delete 75 134 (Recyled) 2 head count pLoc pPre Delete first node: list.head = pLoc->link recycle(pLoc)
Before delete 39 75 134 3 count head pPre pLoc After delete 39 134 (Recycled) 3 count head pPre pLoc General delete case: pPre->link = pLoc->link recycle(pLoc)
Delete node algorithm: • Algorithm insertNode (ref list < metadata >, • val pPre <node pointer>, • val pLoc <node pointer>, • ref dataOut <dataType>) • Dataout = pLoc->data • if (pPre null) • 1 list.head = pLoc->link • else • 1 pPre->link = pLoc->link • 4 end if • 5 list.count = list.count - 1 • 6 recycle(pLoc) • 7 Return • end deleteNode Deletes data from a linked list and returns it to calling module. Pre List is metadata structure to a valid list pPre is pointer to predecessor node dataIn is variable to received deleted data Post data have been deleted and returned to caller
Searches list and passes back address of node containing target and its logical predecessor. Pre List is metadata structure to a valid list pPre is pointer to predecessor node pLoc is pointer variable for current node target is the being sought Post pLoc point to first node with equal /greater key -or- null if targer > key of last node pPre points to largest node smaller than key -or- null if targer < key of first node Return true if found , false if not found • Search list: it is used by several algorithms to locate data in a list. When we insert or delete or retrieve data from a list, we need to search the list and find the data. • Algorithm searchList (val list <metadata> • ref pPre <node pointer> • ref pLoc <node pointer> • ref target <key type> • pPre = null • 2 pLoc = list.head • Loop (pLoc not null AND target > pLoc->data.key) • 1 pPre =pLoc • 2 pLoc = pLoc->link • end loop • If (pLoc null) • 1 found = false • 6 else • 1 if (target equal pLoc->data.key) • 1 found = true • 2 else • 1 found = false • 3 end if • end if • return found • end searchList
Unordered List Search: The problem with unordered searches is that multiple elements often satisfy the search criteria. One simple solution is to return a list of all elements that satisfy the criteria. • Retrieve Node: 1. Use search algorithm to locate the data in the list. 2. If the data are found, move the data to the output area in the calling module and returns true. 3. If the data are not found, return false.
algorithm retrieveNode (val list < metadata >, • val key <key type>, • ref dataOut <dataType>) • found = searchList(List, pPre, pLoc, key) • If (found) • 1 dataOut = pLoc->data • End if • Return found • End retreiveNode • Empty list: Algorithm emtpyList (val list <metadata>) 1 return (list.count equal to zero) End emptyList
Algorithm fullList (val list <metatype>) • Allocate (pNew) • If (allocation successful) • 1 recycle (pNew) • 2 return false • End if • Return ture • End fullList • Full list: • List count: • Algorithm listCount (val list <metatype>) • Return (list.count) • End listCount
Traverse list:Algorithms of this kind start at the first node and examine each node in succession until the last node has been processed. Traverse list is used in changing a value in each node, printing the list, summing a field in the list and so on. step: 1. Set the walking pointer to the first node in the list. 2. Use a loop calling a process module and passes it the data and then advances the walking pointer to the next node. 3. When the last node is processed, the walking pointer becomes null and the loop terminates. pWalker = list.head Loop (pWalker not null) process(pWalker ->data) pWalker = pWalker ->link End loop
Count pos head N … 5 10 15 20 95 100 A approach in designing the traverse list in this approach, the user controls the loop, calling traverse to get next element in the list moredata = getNext (list, o, dataout) Loop (moredata true) process(dataout) moredata = getNext (list, o, dataout) End loop
Algorithm getNext ( ref list <metatype>, • val fromWhere <Boolean>, • ref dataOut <datatype> ) • If (fromwhere is 0) • 1 if (list.count is zero) • 1 success = false • 2 Else • 1 list.pos = list.head • 2 dataOut = list.pos->data • 3 success = true • 2 Else • 1 if (list.pos->link null) • 1 success = false • 2 else • 1 list.pos = list.pos->link • 2 dataOut = true • 3 end if • End if • Return success • End getNext Traverses a linked list, each call return the location of an element in the list Pre List is metadata structure to a valid list fromWhere is 0 start at the first element dataOut is variable to receive data Post dataOut contains data and true returned -or- if end of list returns false Return true if next element located , false if end of list
Destroy list: It deletes any nodes still in the list and recycles their memory, then sets the metadata to a null list condition.. • Algorithm destroyList (ref pList <metadata>) • Loop (list.count not zero) • 1 dltPtr = list.head • 2 list.head = dltPtr->link • 3 list.count = list.count – 1 • 4 recycle (dltPtr) • End loop • list.pos = null • Return • End destroyList Delete all data in list Pre List is metadata structure to a valid list Post All data deleted Return
3.4 Processing A Linked list LinkedList createList destroyList (+) (+) getData addNode removeNode printList menu searchList searchList getNext insertNode deleteNode
This program builds a linked list that can be modified or printed by the user. Algorithm buildLinkedList • Print (welcome to exploring linked lists.) • CrateList (list) • Loop (option not to quit) 1 option = menu () 2 if (option add) 1 dataIn = getData() 2 addNode (list, dataIn) 3 elseif (option delete) 1 print (Enter key of data to be deleted.) 2 read (deleteKey) 3 removeNode (list, deleteKey) 4 elseif (option print) 1 printList (list) 5 endif • End loop • DestroyList (list) • Print (Exploration complete. Thank you.) End buildLinkedList
Display a menu and read user option. Pre Nothing Return Valid choice Algorithm menu • Print (……MENU……) • Print (A: Add new data.) • Print (D: Delete data.) • Print (P: Print list.) 5 Print (Q: Quit.) • Valid = false • Loop ( valid false) 1 print ( Enter your choice:’’) 2 read (choice) 3 if (choice equal ‘A’ or ‘D’ or ‘P’ or ‘Q’) 1 valid = true 4 else 1 print ( Invalid choice. Choices are <A,D,P,Q> ) 5 endif • End loop 9 Return choice End menu
Algorithm addNode ( ref list <metadata>, val dataIn <dataType>) • Found = searchList (list, pPre, pLoc, dataIn.key) • If (found) 1 print (Error: Data already in the list. Not added.) • Else 1 success = insertNode (list, pPre, dataIn) 2 if (success false) 1 print (Error: Out of memory. Program quitting.) 2 abort algorithm 3 end if 4 Return End addNode Add data to a linked list Pre List is metadata structure to a valid list dataIn are data to be inserted into list Post Data have been inserted into list in key sequence
Algorithm removeNode (ref list <metadata>, val key <keyType>) • Found = searchList (list, pPre, pLoc, key) • If (found) 1 deleteNode (list, pPre, pLoc, deleteData) • Else 1 print (Error: Key not in list.) • End if • Return End removeNode This algorithm deletes a node from the linked list Pre List is metadata structure to a valid list key is the key to be located and deleted Post the node has been deleted -or- a warning message printed if not found
This algorithm traverses a linked list and prints the key in each node. Pre List is metadata structure to a valid list Post All key have been printed Algorithm printList ( val list <metadata> ) • If (emptyList (list)) 1 print (No data in list.) • Else 1 print (**** Begin Data Print ****) 2 count = 0 3 moreData = getNext (list, 0, dataPtr) 4 loop (moreData true) 1 count = count + 1 2 print (count, dataPtr->key) 3 moreData = getNext (list, 1, dataPtr) 5 end loop 3 End if • Return End printlist
5 5 5 5 10 15 20 25 27 5 17 12 12 7 27 22 5 10 15 20 25 7 17 22 count count count count head head head head pos pos pos pos 3.5 List Applications • Append Lists: list1 list2 Before Append list1 list2 After Append
Algorithm appendTwolists • Pirint (This program creates two lists and then appends them) • Print (Enter first file name) • Read (fileName) • Open (fileName) • Build (list1, fileName) • printList (list1) • Print (Enter secondt file name) • Read (fileName) • Open (fileName) • Build (list2, fileName) • printList (list2) • Append (list1, list2) • printList (list1) • Return • End appendTwoLists
Algorithm build ( ref list <metadata>, val file <data file>) • CreateList (list) • Loop (not end of file) 1 read (file into dataIn) 2 searchList (list, pPre, pLoc, dataIn.key) 3 insertNode (list, pPre, dataIn) • End loop • Return End build
Algorithm append ( ref list1 <metadata>, val list2 <metadata>) • If (list1.count zero) 1 list1.head = list2.head • Else 1 pLoc = list1.head 2 loop(pLoc->link not null) 1 pLoc = pLoc->link 3 end loop 4 pLoc->link = list2.head • End if • List1.count = list1.count + list2.count • Return End append
(count, pos, and head) • Array of lists
Algorithm arrayOf Lists • print (Begin array of linked lists) • Print (How many list do you want?) • Read (numLists) • buildArys (listArray, numLists) • printArys (listArray, numLists) • Print (End of arry of linked lists) End arryOfLists
Algorithm buildArrays (ref listArray <metadata>, val numLists <integer>) • row = 0 • Loop (row < numLists) 1 print (Enter file name) 2 read (fileName) 3 open (fileName) 4 build (listArray[row], fileName) 5 close (fileName) 6 row = row + 1 • End loop • Return End buildArrays
Algorithm printArys (val listArray <metadata>, val numLists <integer> ) • Row = 0 • Loop (row < numLists) 1 printList (listArray[row]) 2 row = row + 1 • End loop • Return End printAry
5 10 3.6Complex Linked List Structures • Circularly Linked Lists:In this structure, the last node’s link points to the first node of the list. • N 95 count pos rear link
The problem on searching doubly linked list: What is the target does not exit? • The solution: if we start at the fitst node, use the rear pointer; if we start at a middle node , we save the starting node’s address, use the address
head count rear List B F B F B F 5 10 95 • Doubly Linked:In this structure, each node has a pointer to both its successor and its predecessor. B: Backward pointer F: Forward pointer • Doubly Linked List Insertion: • Follow the basic patter. • Need to connect both the forward and backward pointers.
0 pPre 20 30 pNew pNew 3 2 40 40 20 20 30 1 20 After Before Insert into null list or before first node After Before Insert between two nodes
6 if (pPre->fore null) • 1 list.rear = pNew • 7 else • 1 pSucc->back = pNew • 8 end if • 9 pFore->fore = pNew • 10 list.count = list.count + 1 • 11 return (1) • End if • Return (2) • End insertDbl Algorithm insertDbl (ref list <metadata>, val dataIn <dataType>) • If (full list) 1 return 0 • End if • Found = searchList (list, Pre, pSucc, dataIn.key) • If (not found) 1 allocate (pNew) 2 pNew->data = dataIn 3 if (pPre is null) 1 pNew->back = null 2 pNew->fore = list.head 3 list.head = pNew 4 else 1 pNew->fore = pPre->fore 2 pNew->back = pPre 5 end if
pDlt pSucc pPred 3 3 Before delete 75 75 25 25 50 50 (Recycled) After deleting 50 • Doubly Linked List deletion: