1 array vs. linked list array vs. linked list pointers & nodes pointers & nodes singly...

45
1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked list Circular linked lists Circular linked lists Header (dummy) node Header (dummy) node Implementing ADT’s Implementing ADT’s Stack Stack Queue Queue CSE 30331 Lecture 12 – Linked Lists

Upload: london-bunn

Post on 30-Mar-2015

363 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

1

Array vs. Linked ListArray vs. Linked List Pointers & NodesPointers & Nodes Singly linked listSingly linked list Doubly linked listDoubly linked list Circular linked listsCircular linked lists

Header (dummy) nodeHeader (dummy) node Implementing ADT’sImplementing ADT’s

StackStack QueueQueue

CSE 30331Lecture 12 – Linked Lists …

Page 2: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

2

Reading

Linked Lists Ford: Ch 9

Page 3: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

3

Array vs. Linked List Arrays (& STL vectors)

Direct access by index – O(1) Insertion & deletion requires shifting – O(n) Dynamically resizable only at one end

May require copying of all values Pop & push at end – O(1)

Unless resizing is involved Linked Lists ( & STL lists)

Sequential access – O(n) Insertion & deletion without shifting – O(1) Dynamically resizable anywhere –O(1) Pop & push at either end – O(1)

Page 4: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

4

Abstraction of a Linked List

fro n t b ack

front back

Singly Linked List

Doubly Linked List

Page 5: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

5

Linked List Nodes

Each Node is like a piece of a chain

In d iv id u al P iece P o p C h ain

To insert a new link, break the chain at the desired location and simply reconnect at both ends of the new piece.

D is c o nnec t

R ec o nnec t

Page 6: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

6

Linked List Nodes

Removal is like Insertion in reverse.

D is co n n ect

R eco n n ect

Page 7: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

7

Node Composition(singly linked list)

n o de Va lue

n ext

n o d eValu e n ext

An individual Node is composed of two parts a Data field containing the data stored by the node a Pointer field containing the address of the next

Node in the list.

Page 8: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

8

Inserting at the Front of an empty Singly Linked List

fro n t

fro n t

B efo re

(a)

it em

n ew N o d e

A ft er

b ack

Page 9: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

9

Inserting at the Front of a nonempty Singly Linked List

(b )

2 0

fro n t

B efo re

fro n t

5 5

2 0it em

fro n t

A ft er

fro n t

5 5

Page 10: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

10

Deleting From the Front of a Singly Linked List

front

//

front = NULL

Deleting front of a 1-node list

Page 11: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

11

Deleting From the Front of a Singly Linked List

front

Deleting front of a multi-node list

//

front = front->next

Page 12: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

12

Removing a Target Node

front

target

prev curr

// //next

Page 13: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

13

A stack as a NULL terminated singly linked list

D

C

B

to p

A

Stac k

D ABC

L inke d L is t

f ro nt

Page 14: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

14

Node data structure// forward declaration, just to keep the compiler happytemplate <typename T>class Stack;

template <typename T>class Node{ friend class Stack<T>; // let Stack access data & next public: Node(T value = T()) : data(value), next(NULL) { } private: T data; Node *next;};

Page 15: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

15

Stack as a Singly Linked List

template <typename T>class Stack{ public: Stack(); ~Stack(); bool empty(); // true or false, status of stack T top(); // return copy of top node’s value void pop(); // remove top node void push(T value); // create new top node with value void clear(); // remove all nodes from stack private: Node<T> *topNode;};

Page 16: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

16

Stack member functions

template <typename T>Stack<T>::Stack(): topNode(NULL){ }

template <typename T>Stack<T>::~Stack() { clear(); // make sure all memory is freed}

template <typename T>bool Stack<T>::empty() { return (NULL == topNode);}

Page 17: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

17

Stack member functionstemplate <typename T>T Stack<T>::top(){ if (empty()) throw(“in top() with Empty Stack”); return topNode->data;}

template <typename T>void Stack<T>::pop() { if (! empty()) { Node<T> *temp = topNode; // point to top node topNode = topNode->next; // point around to next node delete temp; // free node memory }}

Page 18: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

18

Stack member functions

template <typename T>

void Stack<T>::push(T value) {

Node<T> *temp = new Node<T>(value); // create new Node

temp->next = topNode; // new node points to top Node

topNode = temp; // now new node IS top Node

}

template <typename T>

void Stack<T>::clear()

{

while(! empty())

pop();

}

Page 19: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

19

Stack Tester#include "myStack.h"#include <string>#include <iostream>using namespace std;int main () { Stack<string> S; string name; cout << "Enter names ('done' to quit, 'purge' to clear)\n"; cin >> name; // get first name while (name != "done") { if (name == "purge") S.clear(); else S.push(name); cin >> name; // get another name } cout << "Names entered -- NOW reversed --\n"; while (! S.empty()) { cout << S.top() " "; S.pop(); } cout << endl; return 0;}

Page 20: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

20

Queue as a Null Terminated Singly Linked List

... //

i te m

ne wN o de

f ro nt

bac k

//

Need front and back pointers so we have access to both ends of list

Page 21: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

21

Node data structure(Queue version ~ same as Stack)

// forward declaration, just to keep the compiler happytemplate <typename T>class Queue;

template <typename T>class Node{ friend class Queue<T>; // let Queue access data & next public: Node(T value = T()) : data(value), next(NULL) { } private: T data; Node *next;};

Page 22: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

22

Queue as a Singly Linked List

template <typename T>class Queue{ public: Queue(); ~Queue(); bool empty(); // true or false, status of queue T front(); // return copy of first value void pop(); // remove first node void push(T value); // create new last node with value void clear(); // remove all nodes from queue private: Node<T> *first, *last;};

Page 23: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

23

Queue member functions

template <typename T>Queue<T>::Queue(): first(NULL), last(NULL){ }

template <typename T>Queue<T>::~Queue() { // same as Stack clear(); // make sure all memory is freed}

template <typename T>bool Queue<T>::empty() {// essentially same as Stack return (NULL == first);}

Page 24: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

24

Queue member functionstemplate <typename T>T Queue<T>::front(){ if (empty()) throw(“in front() with Empty Queue”); return first->data;}

template <typename T>void Queue<T>::pop() { if (! empty()) { Node<T> *temp = first; // point to first node first = first->next; // point around to next node delete temp; // free node memory }}

Page 25: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

25

Queue member functionstemplate <typename T>void Queue<T>::push(T value) { Node<T> *temp = new Node<T>(value); // create new Node if (empty()) first = temp; // new last node is also first node else last->next = temp; // new last node follows old last = temp; // now new node IS last Node}

template <typename T>void Queue<T>::clear(){ while(! empty()) pop();}

Page 26: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

26

Doubly Linked Lists

Singly linked list only allow easy traversal in one direction (forward)

Doubly linked lists allow easy traversal both directions (forward and backward)

The list can be linear Having NULL pointers at both ends

The list can be circular Having each end point back to the other Usually this is implemented with a header node

That contains no data That points to itself when list is empty

Page 27: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

27

Circular Doubly Linked Lists

A Watch Band provides a good Real Life analogue for this Data Structure

Firs t Ele m e n t

S e co n d Ele m e n t

L a s t Ele m e n t

Page 28: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

28

Circular Doubly Linked Lists

Implemented on a Computer it might look something like this.

head er

23 4 9

Page 29: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

29

Empty and Non Empty Doubly Linked List

p r e v n e x t

h ead er

B efo re In s ert : E m p t y lis t

p r e v n e x t

h ead er

n ew N o d e

A ft er Iin s ert : L is t w it h o n e elem en t

Page 30: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

30

Implementing a Circular Doubly Linked List// forward declaration, just to keep the compiler happytemplate <typename T>class LinkedList;

template <typename T>class Node{ friend class LinkedList<T>; // let LinkedList access data & next public: Node(T value = T()) : data(value), next(NULL), prev(NULL) { } private: T data; Node *next, *prev;};

Page 31: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

31

LinkedList (Circular and Doubly Linked)template <typename T>class LinkedList{ public: LinkedList(); ~LinkedList(); int size(); // number of nodes in list T get(int pos); // return copy of value at pos void erase(int pos); // remove first node void insert(T value, int pos); // create new node with value at pos void clear(); // remove all nodes from queue int find(T value); // return position of first node with value private: Node<T> *last, // indicate beginning and end of list *current; // indicates current node int numNodes, // number of nodes in list currentPos; // indicates current position void moveTo(int pos); // moves current to desired Node};

Page 32: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

32

LinkedList member functionstemplate <typename T>LinkedList<T>::LinkedList(): numNodes(0), currentPos(-1) { last = new Node<T>; last->next = last; last->prev = last; current = last; // point to the header}

template <typename T>LinkedList<T>::~LinkedList() { clear(); // make sure all Node memory is freed delete last; // free the header Node memory }

Page 33: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

33

LinkedList member functionstemplate <typename T>int LinkedList<T>::size() { return numNodes;}

template <typename T>void LinkedList<T>::clear(){ while(size() > 0) erase(0); // remove all nodes}

Page 34: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

34

LinkedList member functionstemplate <typename T>void LinkedList<T>::moveTo(int pos) { if ((pos < 0)|| (size() <= pos)) throw range_error(“LinkedList::moveTo() pos out of range”); while (currentPos < pos) // move forward along list { current = current->next; currentPos++; } while (currentPos > pos) // move backward along list { current = current->prev; currentPos--; }}

Page 35: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

35

LinkedList member functionstemplate <typename T>T LinkedList<T>::get(int pos) { try { moveTo(pos); // move to indicated position in list } catch (exception &e) { cerr << “Error from LinkedList::get()\n”; cerr << e.what(); exit 1; } return current->data; // return value of Node}

Page 36: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

36

LinkedList member functionstemplate <typename T>int LinkedList<T>::find(T value) { current = last->next; // point to first Node currentPos = 0; while (current != last) // move forward along list { if (current->data == value) break; current = current->next; currentPos++; } if (current == last) currentPos = -1; return currentPos;}

Page 37: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

37

Deleting a Node at a Position

pre v ne xt

s uc c N o de = c ur r->ne xt

1

2

//////

//

pre vN o de = c ur r->pre v c ur r

// unlink the node (*curr) from the list

curr->prev->next = curr->next;curr->next->prev = curr->prev;

delete curr;

Page 38: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

38

LinkedList member functionstemplate <typename T>void LinkedList<T>::erase(int pos) { try { moveTo(pos); // move to indicated position in list } catch (exception &e) { cerr << “Error from LinkedList::get()\n”; cerr << e.what(); exit 1; }

current->prev->next = current->next; // point around Node forward current->next->prev = current->prev; // point around Node backward delete current; // free Node memory}

Page 39: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

39

Inserting a Node at a Position

ne xt pre v

pre vN ode = c urr-> pre v

p r ev item n ex t

143 2 c ur r

n ew N o d e

// insert newNode before curr

newNode->prev = curr->prev;newNode->next = curr;curr->prev->next = newNode;curr->prev = newNode;

Page 40: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

40

LinkedList member functionstemplate <typename T>void LinkedList<T>::insert(T value, int pos) { try { moveTo(pos); // move to indicated position in list } catch (exception &e) { cerr << “Error from LinkedList::get()\n”; cerr << e.what(); exit 1; } Node<T> *newNode = new Node(value); // make a new Node with value newNode->prev = current->prev; // point back at previous Node newNode->next = current; // have it point to new Node current->prev->next = newNode; // point forward to next Node current->prev = newNode; // have it point to new Node}

Page 41: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

41

So what is missing?

Copy Constructor & Assignment Operator Need a deep copy Traverse source list

Copy each node Insert in destination list

Comparison Operator (==) Compare list lengths, and if equal … Traverse both lists

Compare corresponding nodes

Page 42: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

42

Copy Constructortemplate <typename T>LinkedList<T>::LinkedList(LinkedList<T>& theList) : numNodes(0), currentPos(-1) { last = new Node<T>; last->next = last; last->prev = last; current = last; // point to the header

int pos(0); // start at dummy node while (pos < theList.size()) // while nodes in theList { this->insert(theList.get(pos),pos)); // copy node and insert pos++; // move forward }}

Page 43: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

43

Assignment Operator (=)template <typename T>LinkedList<T>& LinkedList<T>::operator=(LinkedList<T>& theList){ if (this == &theList) return; // same lists, nothing to do

LinkedList<T> *newList;

int pos(0); // start at dummy node while (pos < theList.size()) // while nodes in theList { newList.insert(theList.get(pos),pos)); // copy node and insert pos++; // move forward } return newList;}

Page 44: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

44

Comparison (==)template <typename T>bool LinkedList<T>::operator==(LinkedList<T>& theList){ if (this == &theList) return true; // same lists, nothing to do if (this->size() != theList.size())

return false; // lists have different number of values bool same(true); // assume the same int pos(0); // start at first node while (same && (pos < size()) // while same and more nodes { if (this->get(pos) != theList.get(pos)) same = false; // nodes differ so lists do, too pos++; // move forward } return same;}

Page 45: 1 Array vs. Linked List Array vs. Linked List Pointers & Nodes Pointers & Nodes Singly linked list Singly linked list Doubly linked list Doubly linked

45

Comparison (==)(more efficient, without function calls)

template <typename T>bool LinkedList<T>::operator==(LinkedList<T>& theList){ if (this == &theList) return true; // same lists, nothing to do if (this->numNodes != theList.numNodes)

return false; // lists have different number of values bool same(true); // assume the same Node<T> *nodeThis(this->last->next); // start at first node Node<T> *nodeThat(theList.last->next); // start at first node while (same && (nodeThis != last) // while same and more nodes { if (nodeThis->data != nodeThat->data) same = false; // nodes differ so lists do, too nodeThis = nodeThis->next; // move forward nodeThat = nodeThat->next; // move forward } return same;}