Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ics212-27-linked-data-structures

 ics212-27-linked-data-structures

William Albritton

November 12, 2015
Tweet

More Decks by William Albritton

Other Decks in Programming

Transcript

  1. Data Encapsulation  Data encapsulation is hiding the details of

    how a class works by restricting access to data members, which can only be manipulated by member functions  In other words, the implementation details of a class are hidden within the classes themselves  Also called “data hiding” or “information hiding”
  2. Interfaces  Classes must interact with one another through well-defined

    interfaces  Hiding the details, while supplying an interface is an important underlying theme behind classes (user-defined data types)  An interface of a class is a list of function prototypes, so the user does not have access to the body (code) of the member functions
  3. Software Engineering  Inheritance can be used to customize existing

    software  A derived class inherits the data members and member functions of a base class, and then additional data members and member functions are added  In C++, you only need the base class object code and the base class header file, which has the class interface (the list of function prototypes)
  4. Software Engineering  A software vender can develop classes for

    sale  If the user has the object code and header files, then the user can create new software to suit their own needs  The vender’s source code is never revealed
  5. Self-Referential Class (Data Type)  Contains a pointer that points

    to another object (variable) of the same type  Self-referential objects link together to form data structures class Node{ string data; Node *next; };
  6. C++ String Class  C++ has a string class (note

    “s” is lowercase)  For now, we will only declare, pass strings to functions, and output strings  See example program at: strings.cpp #include <string> //code . . . string greeting = “Aloha!\n”; cout<<greeting; //Aloha!
  7. Header File  A header file has the class interface

    (list of function prototypes)  See example header file at: node.h
  8. Header File If Statements  When we have many classes,

    the same header files are often included at the top of several files  To prevent multiple inclusions of the header file in the final executable file, the header file has these if statements #ifndef NODE_H #define NODE_H //code . . . #endif
  9. Header File Class Name  The header file has the

    class name, curly brackets, and semicolon class Node{ //code . . . };
  10. Header File Member Functions  The header file contains a

    list of the prototypes of the member functions of the class public: Node(string, Node *); string getData() const; void setData(string); Node *getNext() const; void setNext(Node *);
  11. Header File Member Functions  The header file has the

    data members of the class private: string data; Node *next;
  12. Function Definitions  The function definitions, with the body of

    the functions, are in a separate file from the header file with the function prototypes and data members  See function definitions at: node.cpp  The header file is included at the top of the file #include “node.h”
  13. Constructor  Each member function has the class name and

    scope resolution operator (::) before the function name, so the compiler knows which class the function belongs to Node::Node(string data2, Node *next2){ data = data2; next = next2; }
  14. Set() and Get() Functions  Note that “Node::” attaches to

    each function’s name void Node::setData(string data2){ data = data2; } string Node::getData() const{ return data; }
  15. The Next Node  Functions to set and get the

    address of the next node void Node::setNext(Node *next2){ next = next2; } Node *Node::getNext() const{ return next; }
  16. Global Friend Function  The friend function is global, so

    no need “Node::” in front of function name  Overloading operator<<(), so that the data member “data” is displayed for that node ostream &operator<<(ostream & output, const Node & node){ output<<node.data; return output; }
  17. Program in Memory 1. Data segment contains global data 2.

    Code segment contains the program code 3. Stack segment contains runtime stack and heap Data Segment Code Segment Stack Segment
  18.  Top of stack segment contains runtime stack storing local

    environment of functions  Bottom of stack segment contains heap storing data using “new” and “delete” Data Segment Code Segment runtime stack heap Stack Segment Stack Segment
  19. Runtime Stack  Implicit (automatic) allocation and deallocation  Each

    function call creates a local environment (return address, arguments, local variables, return value)  Function call: push stack frame  Function exit: pop stack frame  Grows from top of stack segment downwards
  20. Heap  Memory explicitly allocated and deallocated by the programmer

    using keywords “new” and “delete”  At bottom of stack segment and grows upwards  When the runtime stack and the heap meet, your program is out of memory, which may occur if you don’t use “delete” to deallocate memory
  21. Dynamic Memory Allocation  Ability of a program to use

    memory on the heap at execution time (while program is running)  Create and store new nodes  Use keyword “new” to allocate memory on the heap  Returns a pointer to the place in memory on the heap Node *node1 = new Node("apple", NULL);
  22. Where Are Things Stored?  The variable “node1” is stored

    on the runtime stack  The address of “new Node” object is stored in “node1”  The “new Node” object is stored on the heap cout<<&node1; //0xffbffa34 cout<<node1; //0x23798 cout<<node1->getData(); //"apple" cout<<node1->getNext(); //0 (NULL)
  23. Runtime Stack and Heap  The runtime stack with variable

    “node1” with the address to a Node object on the heap  The heap with a Node object with data members data and next runtime stack heap "apple" NULL data next 0x23798 node1 0xffbffa34
  24. Driver Program  The driver program is used to test

    the class  See driver program at: node-driver.cpp  The header file is included at the top of the file #include “node.h”
  25. Linking Nodes  Using function setNext(), we can link nodes

    together Node *node1 = new Node("apple", NULL); Node *node2 = new Node("banana", NULL); node1->setNext(node2); cout<<node1->getNext(); //0x237a8 cout<<node2; //0x237a8
  26. Runtime Stack and Heap  The runtime stack with variables

    “node1” and “node2” with address to objects on the heap  The heap with the new Nodes pointing from the first to second node "apple" 0x237a8 data next 0x23798 node1 0xffbffa34 0x237a8 node2 0xffbffa1c “banana" NULL data next
  27. Pointing to Nodes  Now that nodes are linked, we

    can take a pointer and move from one node to the next Node *pointer = node1; cout<<*pointer; //“apple” pointer = pointer->getNext(); cout<<*pointer; //“banana”
  28. Runtime Stack and Heap  Variable “pointer” on the runtime

    stack is pointing to 1st node object on the heap Node *pointer = node1; "apple" 0x237a8 data next 0x23798 node1 0xffbffa34 0x237a8 node2 0xffbffa1c “banana" NULL data next 0x23798 pointer 0xffbffa18
  29. Runtime Stack and Heap  Variable “pointer” on the runtime

    stack is pointing to 2nd node object on the heap pointer = pointer->getNext(); "apple" 0x237a8 data next 0x23798 node1 0xffbffa34 0x237a8 node2 0xffbffa1c “banana" NULL data next 0x237a8 pointer 0xffbffa18
  30. Looping through Nodes  After we link more nodes together

    (node-driver.cpp), we can now loop through all the nodes from the first node to the last node, which has NULL for next Node *i = NULL; for(i=node1; i!=NULL; i=i->getNext()){ cout<<*i<<endl; }
  31. makefile  We have several C++ program files to compile

    and link together, so the makefile is a little more complicated  The C++ program files are:  node-driver.cpp, node.cpp, and node.h  The makefile is:  makefile-node
  32. makefile program: node-driver.o node.o g++ node-driver.o node.o -o program node-driver.o:

    node-driver.cpp node.h g++ -c node-driver.cpp node.o: node.cpp node.h g++ -c node.cpp
  33. Dynamic Memory De-Allocation  The drawback with dynamic memory allocation

    is that you can fill up the heap, so your program should release space no longer needed  Use keyword “delete” to deallocate memory  Deallocates the memory on the heap referred to by the pointer so the memory can be reused delete node1;
  34. Stacks  Collection of nodes (self-referential objects) that are connected

    by links (pointer to next node)  Pointer points to (has address of) the first node  Next pointer refers to (has address of) next node  Last node has a NULL next pointer  Insert and delete only at the top of the linked list
  35. Stack Example Program  Program that implements a stack of

    strings  See header file with interface (function prototypes): stack.h  See function definitions: stack.cpp  See driver (test) program: stack-driver.cpp  See makefile: stack-makefile
  36. Stack Header File  For the data members, all we

    need is a pointer to the first Node on the Stack (see stack.h) class Stack { //code . . . protected: Node *top; };
  37. Stack Constructor  Initializes the top to NULL, because if

    the Stack is empty, the top is NULL Stack::Stack(){ top = NULL; // }
  38. Function push()  Create a new Node on heap that

    points to current top Node, and point the “top” data member to this node void Stack::push(string data){ //new Node on heap points to top Node *newTop = new Node(data, top); //top points to new Node top = newTop; }
  39. Function pop()  Removes Node at top of stack and

    returns Node’s data string Stack::pop(){ if(!empty()){ Node *temp = top; string dataOnTop = top->getData(); top = top->getNext(); delete temp; //remove Node from heap return dataOnTop; } return “”;}
  40. Function peek()  Returns, but does not remove, data from

    top Node string Stack::peek() const{ if(!empty()){ return top->getData(); } return “”; }
  41. Overloaded Assignment Operator  Makes a second, independent copy of

    the stack const Stack &Stack::operator=(const Stack &stack2){ //code . . . top = new Node(stack2.top>getData(),NULL); Node *i = stack2.top; Node *j = top; i = i->getNext();
  42. Overloaded Assignment Operator  While loop makes a copy of

    each node while(i!=NULL){ Node *temp = new Node(i->getData(), NULL); j->setNext(temp); j = temp; i=i->getNext(); } } return *this; } //this object
  43. Destructor  Destructor removes each node from the heap Stack::~Stack(){

    Node *i = top; Node *temp = NULL; while(i != NULL){ temp = i; i = i->getNext(); delete temp; //remove Node from heap } }
  44. Stack Driver and makefile  The stack driver program checks

    all of the functions and makes sure they are working properly  In particular, we tested the overloaded assignment operator=() to make sure it makes an independent copy of the stack  See driver (test) program: stack-driver.cpp  Compile and like all the files with: makefile-stack