1 / 16

Static Array

a. a. b. b. c. c. a. b. c. d. e. d. d. e. e. Chapter 4 Linked Lists. Recall that linked lists enable us to dynamically adjust the size of a list, eliminating the need to preallocate a specific amount of memory. Static Array. Dynamic Array. Linked List. Preallocation Required!

Download Presentation

Static Array

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. a a b b c c a b c d e d d e e Chapter 4 Linked Lists Recall that linked lists enable us to dynamically adjust the size of a list, eliminating the need to preallocate a specific amount of memory. Static Array Dynamic Array Linked List Preallocation Required! Wasteful if you allocate too much! Potentially fatal if you allocate too little! Determine the size of the list before allocating memory! Not dynamic enough – you can’t change the size once it’s been decided! Completely dynamic! No space is wasted due to excess allocation! Additional space is allocated as needed! Chapter 4 - Linked Lists

  2. Let’s review linked lists with a little example that also refreshes our memory (so to speak) about recursion. In this example, we’re going to read text from an input file, keeping track of how many times each word is used in the text. Each node in the linked list will require a string field (to hold the word), an integer field (to hold the count), and a pointer field (to point to the next node). string word ptr next int count Chapter 4 - Linked Lists

  3. “groovy” “oops” “yadda” “wassup” “wassup” “groovy” “groovy” “yadda” “yadda” “wassup” 4 3 2 4 1 4 3 3 3 3 When a word is inserted in the list, the list is traversed to see if the word’s already there... “groovy” If the word is found, its node is removed, its count is incremented, and the node is reinserted to preserve the count/alphabetical ordering... “oops” If the word isn’t found, a new node is created with a count of one, and inserted appropriately... Chapter 4 - Linked Lists

  4. Desired linked list functionality: Default Constructor Copy Constructor Destructor Make an empty list Make a deep copy list Delete all list nodes INSERT member function RETRIEVE member function GETNODE member function Insert a new(?) word Find a word’s count Create word/count node Input (>>) friend operator Output (<<) friend operator Read a text file Write word/count list Recursive Find function Recursive Insert function Recursive Output function Unpunctuate & upper-case function Find a word Insert a word Write a word/count Edit a word Chapter 4 - Linked Lists

  5. ///////////////////////////////////////// // Class definition file: linkedList.h // // // // Each node in a LinkedList will have // // two components: an elementType (a // // string representing a word and an // // integer counting that word's number // // of occurrences) and a pointer to // // the next node in the LinkedList. // ///////////////////////////////////////// #ifndef LINKED_LIST_H #include <string> using namespace std; struct elementType { string word; int count; }; struct node; typedef node *nodePtr; struct node { elementType item; nodePtr next; }; class LinkedList { public: // Constructors and destructor LinkedList(); LinkedList(const LinkedList &list); ~LinkedList(); // Member functions bool insert(string str); int retrieve(string str); friend istream& operator >> (istream &sourceFile, LinkedList &list); friend ostream& operator << (ostream &destFile, const LinkedList &list); private: // Data member nodePtr head; // Member function nodePtr getNode(string str, int ct); }; void recursiveOutput(ostream &outputFile, nodePtr ptr); nodePtr recursiveInsertPrep(string str, nodePtr prevPtr, nodePtr &currPtr); void recursiveInsert(nodePtr newPtr, nodePtr prevPtr, nodePtr &currPtr); void unpunctuate(string &str); #define LINKED_LIST_H #endif Chapter 4 - Linked Lists

  6. /////////////////////////////////////////////// // Class implementation file: linkedList.cpp // // // // In addition to standard constructor and // // destructor members, the LinkedList class // // has members for inserting a word into the // // list and determining a particular word's // // count. Friend input and output operators // // are also included. Non-member functions // // for enacting recursive output, insertion, // // and search have been implemented, as well // // as a function for removing punctuation // // from the beginning and ending of a word, // // and converting what's left to upper case. // /////////////////////////////////////////////// #include "linkedList.h" #include <iomanip> #include <cassert> using namespace std; // Default Constructor: Sets // // up empty LinkedList. // LinkedList::LinkedList() { head = NULL; } // Copy Constructor: Makes deep copy // // of the parameterized LinkedList. // LinkedList::LinkedList(const LinkedList &list) { nodePtr currPtr, thisCurrPtr, thisPrevPtr; if (list.head == NULL) head = NULL; else { head = getNode(list.head->item.word, list.head->item.count); thisPrevPtr = head; currPtr = list.head->next; while (currPtr != NULL) { thisCurrPtr = getNode(currPtr->item.word, currPtr->item.count); thisPrevPtr->next = thisCurrPtr; thisPrevPtr = thisCurrPtr; currPtr = currPtr->next; } } } // Destructor: Deletes every // // node in LinkedList. // LinkedList::~LinkedList() { nodePtr currPtr; while (head != NULL) { currPtr = head; head = head->next; currPtr->next = NULL; delete currPtr; } } Chapter 4 - Linked Lists

  7. // Member Function: insert // // // // This function searches the // // LinkedList for the parameterized // // word, removing the corresponding // // node and incrementing its count // // if it's found. Otherwise, a new // // node is created containing the // // word with a count of one. In // // any case, the function inserts // // the node into the list so that // // the words are sorted primarily // // by their count, and then in // // alphabetical order. A boolean // // is returned, based on the // // insertion's success. // bool LinkedList::insert(string str) { nodePtr insertPtr = recursiveInsertPrep(str, NULL, head); if (insertPtr == NULL) return false; recursiveInsert(insertPtr, NULL, head); return true; } // Member Function: retrieve // // // // This function locates the // // parameterized string in the // // LinkedList, returning the // // corresponding count for that // // word. Zero is returned if the // // string isn't found in the list. // int LinkedList::retrieve(string str) { nodePtr currPtr = head; while (currPtr != NULL) { if (currPtr->item.word == str) return currPtr->item.count; else currPtr = currPtr->next; } return 0; } Chapter 4 - Linked Lists

  8. ostream& operator << (ostream &destFile, const LinkedList &list) { recursiveOutput(destFile, list.head); return destFile; } // Member Function: getNode // // // // This function creates and returns // // a new nodePtr, pointing to a node // // with the parameterized string as // // its item's word, the parameterized // // integer as its item’s count, and // // NULL as its next pointer. // nodePtr LinkedList::getNode(string str, int ct) { nodePtr temp = new node; if (temp != NULL) { temp->item.word = str; temp->item.count = ct; temp->next = NULL; } return temp; } // Friend Input Operator: >> // // // // The input operator reads strings // // from the parameterized input stream, // // strips off all unnecessary punctua- // // tion, and inserts them into the // // parameterized LinkedList, until the // // input stream has been depleted. // istream& operator >> (istream &sourceFile, LinkedList &list) { string nextWord; sourceFile >> nextWord; while (!sourceFile.eof()) { unpunctuate(nextWord); list.insert(nextWord); sourceFile >> nextWord; } return sourceFile; } // Friend Output Operator: << // // // // The output operator outputs the // // values values in the LinkedList, // // each on a separate output line in // // the parameterized output stream, // // starting with the head element. // Chapter 4 - Linked Lists

  9. nodePtr recursiveInsertPrep(string str, nodePtr prevPtr,nodePtr &currPtr) { nodePtr temp; if (currPtr == NULL) { temp = new node; if (temp != NULL) { temp->item.word = str; temp->item.count = 1; temp->next = NULL; } return temp; } else if (currPtr->item.word == str) { temp = currPtr; if (prevPtr == NULL) currPtr = currPtr->next; else prevPtr->next = currPtr->next; temp->item.count++; temp->next = NULL; return temp; } else return recursiveInsertPrep(str, currPtr, currPtr->next); } // Non-Member Function: recursiveOutput // // // // This function recursively outputs the word // // counts to the parameterized output file, // // beginning with the node pointed to by the // // parameterized pointer, and traversing to // // the tail of the (implicit) linked list. // void recursiveOutput(ostream &outputFile, nodePtr ptr) { if (ptr != NULL) { outputFile << setw(20) << ptr->item.word << " (" << ptr->item.count << ")" << endl; recursiveOutput(outputFile, ptr->next); } return; } // Non-Member Function: recursiveInsertPrep // // Prepares list for insertion. // This function recursively locates the para- // // meterized word in the (implicit) linked list // // starting at the node to which the currPtr // // pointer is pointing. The prevPtr pointer is // // assumed to point to currPtr's predecessor in // // the list. If the desired string is located, // // its node is delinked from the list and its // // count is incremented by one. If the entire // // list is searched without success, then a new // // node containing the word (and a count of one) // // is created. In either case, a pointer to the // // node containing the desired word is returned. // Chapter 4 - Linked Lists

  10. // Non-Member Function: unpunctuate // // // // This function removes all non-alpha- // // numeric characters from the beginning // // and ending of the parameterized string, // // and then converts what's left of the // // string into upper-case. // void unpunctuate(string &str) { const string ALPHANUMERIC = (string)"ABCDEFGHIJKLMNOPQRSTUVWXYZ" + (string)"abcdefghijklmnopqrstuvwxyz" + (string)"0123456789"; while (str.find_first_not_of(ALPHANUMERIC) == 0) str = str.substr(1,str.size()-1); while ((str.size() > 0) && (str.find_last_of(ALPHANUMERIC) < str.size()-1)) str = str.substr(0,str.size()-1); for (int i = 0; i < str.size(); i++) str[i] = toupper(str[i]); } // Non-Member Function: recursiveInsert // // // // This function recursively traverses the list // // until the currPtr parameter points to the // // node whose contents should occur right after // // the contents of the node to which newPtr is // // pointing. Once this occurs, the newPtr node // // is inserted between currPtr's node and its // // predecessor (to which prevPtr is pointing). // void recursiveInsert(nodePtr newPtr, nodePtr prevPtr, nodePtr &currPtr) { if ((currPtr != NULL) && ((currPtr->item.count > newPtr->item.count) || ((currPtr->item.count == newPtr->item.count) && (currPtr->item.word < newPtr->item.word)))) recursiveInsert(newPtr,currPtr,currPtr->next); else if (prevPtr == NULL) { newPtr->next = currPtr; currPtr = newPtr; } else if (currPtr == NULL) prevPtr->next = newPtr; else { newPtr->next = currPtr; prevPtr->next = newPtr; } } Chapter 4 - Linked Lists

  11. ////////////////////////////////////////////////// // WordCountDriver.cpp // // // // Driver program to test the LinkedList class. // ////////////////////////////////////////////////// #include <iostream> #include <fstream> #include <string> #include "linkedList.h" using namespace std; ////////////////////////////////////////////////////////////////////////////////// // The main function uses text from a hard-coded input file to create a linked // // list of the distinct words in that file and how many times each word occurs. // // The function then outputs that list to a hard-coded output file. // ////////////////////////////////////////////////////////////////////////////////// void main() { LinkedList wordCountList; ifstream stringFile; ofstream resultFile; stringFile.open("essay.txt"); resultFile.open("count.txt"); stringFile >> wordCountList; resultFile << wordCountList << endl; return; } Chapter 4 - Linked Lists

  12. IBM announced today that researchers are testing the Linux operating system on a prototype wristwatch device in an attempt to prove that Linux can be used as the basic software on even the smallest devices. “Designed to communicate wirelessly with PCs, cell phones and other wireless-enabled devices, the ‘smart watch’ will have the ability to view condensed e-mail messages and directly receive pager-like messages,” IBM said in a statement. However, IBM does not have plans to commercialize the Linux watch itself, a spokeswoman said. “This is just a research prototype,” said Takako Yamakura. “Some say Linux cannot be scaled down. This is just to show Linux is capable of doing this.” The Linux operating system is seen as an alternative to Microsoft Corp.’s Windows operating system, and is popular with programmers for its open source code, which allows programmers to develop and tinker with programs. “Several benefits accrue from the use of Linux in small pervasive devices,” IBM said in the statement. “The availability of source code and a well-understood application programming environment makes it easy for students, researchers, and software companies to add new features and develop applications.” Linux, which was developed by Finnish programmer Linus Torvalds, is used for many basic functions of Web sites, but is not yet considered mature enough for heavier business tasks. IBM has been working to develop the system for everything from the wrist watch to supercomputers. “With Linux rapidly becoming an industry standard, it’s important that developers be able to create new applications across all platforms, including pervasive devices, and the intent of IBM’s research is to further that work,” IBM said. Input File: "essay.txt" Chapter 4 - Linked Lists

  13. THE (13) TO (12) LINUX (9) AND (8) IS (8) IBM (6) A (5) FOR (5) OF (5) DEVICES (4) IN (4) SAID (4) SYSTEM (4) THAT (4) WITH (4) AN (3) BE (3) DEVELOP (3) OPERATING (3) THIS (3) WATCH (3) APPLICATIONS (2) AS (2) BASIC (2) CODE (2) FROM (2) HAVE (2) JUST (2) MESSAGES (2) NEW (2) NOT (2) ON (2) PERVASIVE (2) PROGRAMMERS (2) PROTOTYPE (2) RESEARCH (2) RESEARCHERS (2) SOFTWARE (2) SOURCE (2) STATEMENT (2) USED (2) WHICH (2) ABILITY (1) ABLE (1) ACCRUE (1) ACROSS (1) ADD (1) ALL (1) ALLOWS (1) ALTERNATIVE (1) ANNOUNCED (1) APPLICATION (1) ARE (1) ATTEMPT (1) AVAILABILITY (1) BECOMING (1) BEEN (1) BENEFITS (1) BUSINESS (1) BUT (1) BY (1) CAN (1) CANNOT (1) CAPABLE (1) CELL (1) COMMERCIALIZE (1) COMMUNICATE (1) COMPANIES (1) CONDENSED (1) CONSIDERED (1) CORP.’S (1) CREATE (1) DESIGNED (1) DEVELOPED (1) DEVELOPERS (1) DEVICE (1) DIRECTLY (1) DOES (1) DOING (1) DOWN (1) E-MAIL (1) EASY (1) ENOUGH (1) ENVIRONMENT (1) EVEN (1) EVERYTHING (1) FEATURES (1) FINNISH (1) FUNCTIONS (1) FURTHER (1) HAS (1) HEAVIER (1) HOWEVER (1) IBM’S (1) IMPORTANT (1) INCLUDING (1) INDUSTRY (1) INTENT (1) IT (1) ITS (1) ITSELF (1) IT’S (1) LINUS (1) MAKES (1) MANY (1) MATURE (1) MICROSOFT (1) OPEN (1) OTHER (1) PAGER-LIKE (1) PCS (1) PHONES (1) PLANS (1) PLATFORMS (1) POPULAR (1) PROGRAMMER (1) PROGRAMMING (1) PROGRAMS (1) PROVE (1) RAPIDLY (1) RECEIVE (1) SAY (1) SCALED (1) SEEN (1) SEVERAL (1) SHOW (1) SITES (1) SMALL (1) SMALLEST (1) SMART (1) SOME (1) SPOKESWOMAN (1) STANDARD (1) STUDENTS (1) SUPERCOMPUTERS (1) TAKAKO (1) TASKS (1) TESTING (1) TINKER (1) TODAY (1) TORVALDS (1) USE (1) VIEW (1) WAS (1) WEB (1) WELL-UNDERSTOOD (1) WILL (1) WINDOWS (1) WIRELESS-ENABLED (1) WIRELESSLY (1) WORK (1) WORKING (1) WRIST (1) WRISTWATCH (1) YAMAKURA (1) YET (1) Output File: "count.txt" Chapter 4 - Linked Lists

  14. Standard Linked Lists • List has definite beginning and end. • NULL pointer used to indicate empty list. • Head and tail must be treated as special cases. • Complicated “previous” pointer needed for insertion and removal. Circular Linked Lists • Nice for applications requiring cycling through list. • Pointer used to keep track of current position in list. • No actual “head” or “tail” in list, so watch out for infinite loops! • “Previous” pointer still needed for insertion and removal. Chapter 4 - Linked Lists

  15. Dummy Head Node Linked Lists • Dummy head node always exists, no special “head” case. • Head node’s “next” pointer is NULL when list is empty. • Wasteful use of node; its “data” field is usually vacuous. • “Previous” pointer still needed for insertion and removal. Doubly Linked Lists • Eliminates need for keeping track of previous node during traversal. • Improves efficiency when used with circularity & dummy head node. • Rather complex maintenance of predecessor & successor pointers. • Like all of the linked list variations, linear search is inefficient! Chapter 4 - Linked Lists

  16. Skip Lists One possibility for improving the efficiency of list traversals is the idea of a “skip list”. Assume that the “values” of the data held in the list are evenly distributed between some value  and some value , and assume that there will be approximately N values in the list. Each node has a “data” field and an array of at most n “next” pointers, where n is log2 N. When a new value is inserted, randomly assign it k “next” pointers in such a way that half of the time, the node gets 1 “next” pointer, a quarter of the time it gets 2 “next” pointers, and so on up to (1/2n-1)th of the time it gets either n-1 or n pointers. Yes, it’s pretty complicated, but it essentially enables you to search a linked list in logarithmic time (rather than that awful linear time)!. Chapter 4 - Linked Lists

More Related