lists - github pages

68
Lists Tiziana Ligorio 1

Upload: others

Post on 26-May-2022

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Lists - GitHub Pages

Lists

Tiziana Ligorio!1

Page 2: Lists - GitHub Pages

Today’s Plan

Lists

!2

Page 3: Lists - GitHub Pages

What makes a list?

E.g. PlayList?

Duplicates allowed or not is not a defining factor

List ADT

!3

Page 4: Lists - GitHub Pages

What makes a list?

E.g. PlayList?

Duplicates allowed or not is not a defining factor

ORDER!!!

List ADT

!4

Page 5: Lists - GitHub Pages

#ifndef LIST_H_ #define LIST_H_ template<typename ItemType> class List { public:

List(); // constructor List(const List<ItemType>& a_list); // copy constructor ~List(); // destructor bool isEmpty() const; size_t getLength() const; bool insert(size_t position, const ItemType& new_element);

//retains list order, position is 0 to n-1, if position > n-1, //it inserts at end

bool remove(size_t position);//retains list order ItemType getItem(size_t position) const; void clear();

private: //implementation details here

}; // end List#include "List.cpp" #endif // LIST_H_

!5

Unsigned integer type. Guaranteed to store the max size of objects of any type.

Page 6: Lists - GitHub Pages

Implementation

Array?

Linked Chain?

!6

Must preserve order No swapping tricks

Page 7: Lists - GitHub Pages

Array

!7

12 4 1 8 9 … 5 6

1 2 3 40 n-1

12 4 12 1 8 9 … 5 6

1 2 3 40 n-1

insert(2, 12)

n

Must shift n-position elements

Page 8: Lists - GitHub Pages

Array

!8

12 4 1 8 9 … 5 6

1 2 3 40 n-1

12 4 8 9 … … 5 6

1 2 3 40 n-2

remove(2)similarly

n-1

Must shift n-(position+1) elements

Page 9: Lists - GitHub Pages

Array Analysis

With Array both insert and remove are “Expensive”

Number of operations depends on size of List

Can we do better?

!9

Page 10: Lists - GitHub Pages

What makes a list?

Order is implied

!10

1 2 3 4first_ last_

Page 11: Lists - GitHub Pages

What makes a list?

Order is implied

Insertion and removal from middle retains order

!11

first_ last_ 1 2

3

54

Page 12: Lists - GitHub Pages

What makes a list?

Order is implied

Insertion and removal from middle retains order

!12

first_ last_ 1 2 3

Page 13: Lists - GitHub Pages

What’s the catch?

No random access

As opposed to arrays or vectors with direct indexing

“Expensive”: each insertion and removal must traverse position+1 nodes

Here too, umber of operations depends on size of List

!13

Page 14: Lists - GitHub Pages

Arrays Linked List

Random/direct access

Retain order with Insert and remove

At the back

Retain order with insert and remove

at front

Retain order with insert and remove

In the middle

Efficient, does not depend on # of items

Expensive, depends on # of items

Page 15: Lists - GitHub Pages

Arrays Linked List

Random/direct access

Retain order with Insert and remove

At the back

Retain order with insert and remove

at front

Retain order with insert and remove

In the middle

Efficient, does not depend on # of items

Expensive, depends on # of items

Page 16: Lists - GitHub Pages

Arrays Linked List

Random/direct access

Retain order with Insert and remove

At the back

Retain order with insert and remove

at front

Retain order with insert and remove

In the middle

Efficient, does not depend on # of items

Expensive, depends on # of items

Page 17: Lists - GitHub Pages

Arrays Linked List

Random/direct access

Retain order with Insert and remove

At the back

Retain order with insert and remove

at front

Retain order with insert and remove

In the middle

Efficient, does not depend on # of items

Expensive, depends on # of items

Page 18: Lists - GitHub Pages

Arrays Linked List

Random/direct access

Retain order with Insert and remove

At the back

Retain order with insert and remove

at front

Retain order with insert and remove

In the middle

No sifting but incurs cost of finding the node

to remove (call to getPointerTo)

Size

Efficient, does not depend on # of items

Expensive, depends on # of items

Page 19: Lists - GitHub Pages

Singly-Linked List

!19

Page 20: Lists - GitHub Pages

#ifndef LIST_H_ #define LIST_H_ template<typename ItemType> class List { public:

List();//constructor List(const List<ItemType>& a_list);//copy constructor ~List();//destructor bool isEmpty() const; size_t getLength() const; bool insert(size_t positio n, const ItemType&

new_element);//retains list order, position is //0 to n-1, if position > n-1 it inserts at end

bool remove(size_t position);//retains list order ItemType getItem(size_t position) const; void clear();

private://implementation details hereNode<ItemType>* getPointerTo(size_t position) const;

}; // end List#include "List.cpp" #endif // LIST_H_

!20

Page 21: Lists - GitHub Pages

!21

INSERT

REMOVE

Assuming you have this pointer you can insert with

“fixed” amount of work

Assuming you have this pointer you can remove with

“fixed” amount of work

void insert(size_t position, ItemType new_element);

void remove(size_t position);

Page 22: Lists - GitHub Pages

Caveat

Find the pointer to the node before inserting/removing —> traversal: high cost - depends on number of elements in list

!22

Page 23: Lists - GitHub Pages

!23

INSERT

REMOVE

Assuming you have this pointer you can insert with

“fixed” amount of work

Assuming you have this pointer you can remove with

“fixed” amount of work

void insert(size_t position, ItemType new_element);

void remove(size_t position);

What about this one?

Page 24: Lists - GitHub Pages

Lecture Activity

!24

REMOVE

Assuming you have this pointer you can remove with

“fixed” amount of work

void remove(size_t position);

What about this one?

Propose a solution to this problem: In English write a few sentences describing the changes you would make to the Linked-Chain implementation of the List ADT to remove from the middle

Design

Page 25: Lists - GitHub Pages

!25

REMOVE

Assuming you have this pointer you can remove

with “fixed” amount of work

void remove(size_t position); void getPointerTo(size_t position, Node<ItemType>*& pos_ptr, Node<ItemType>*& prev_ptr);

One possible solution

Page 26: Lists - GitHub Pages

Another Solution?

!26

Page 27: Lists - GitHub Pages

Doubly Linked List

!27

Page 28: Lists - GitHub Pages

#ifndef NODE_H_ #define NODE_H_ template<class ItemType> class Node {public:

Node(); Node(const ItemType& an_item); Node(const ItemType& an_item, Node<ItemType>* next_node_ptr); void setItem(const ItemType& an_item); void setNext(Node<ItemType>* next_node_ptr); void setPrevious(Node<ItemType>* prev_node_ptr); ItemType getItem() const; Node<ItemType>* getNext() const; Node<ItemType>* getPrevious() const;

private:

ItemType item; // A data item Node<ItemType>* next_; // Pointer to next node Node<ItemType>* previous_; // Pointer to previous node

}; // end Node#include "Node.cpp" #endif // NODE_H_

!28

Page 29: Lists - GitHub Pages

Doubly Linked List

!29

Page 30: Lists - GitHub Pages

#ifndef LIST_H_ #define LIST_H_ template<typename ItemType> class List { public:

List(); // constructor List(const List<ItemType>& a_list); // copy constructor ~List(); // destructor bool isEmpty() const; size_t getLength() const; bool insert(size_t position, const ItemType& new_element);//retains list order, position is 0 to n-1, if position > n-1

//it inserts at end bool remove(size_t position);//retains list order ItemType getItem(size_t position) const; void clear();

private:

Node<ItemType>* first_; // Pointer to first node Node<ItemType>* last_; // Pointer to last node size_t item_count; // number of items in the listNode<ItemType>* getPointerTo(size_t position) const;

}; // end List#include "List.cpp" #endif // LIST_H_

!30

Page 31: Lists - GitHub Pages

List::insert

!31

first_

last_

What are the different cases that should be considered?

Page 32: Lists - GitHub Pages

Lecture Activity

Write Pseudocode to insert a node at position 2 in a doubly-linked list (assume position follows classic indexing from 0 to item_count - 1)

first_

last_

Page 33: Lists - GitHub Pages

PseudocodeInstantiate new node

Obtain pointer

Connect new node to chain

Reconnect the relevant nodes

!33

. . .

Page 34: Lists - GitHub Pages

PseudocodeInstantiate new node

Obtain pointer

Connect new node to chain

Reconnect the relevant nodes

!34

. . .

. . .

. . .

. . .

Page 35: Lists - GitHub Pages

PseudocodeInstantiate new node to be inserted and set its value

Obtain pointer to node currently at position 2

Connect new node to chain by pointing its next pointer to the node currently at position and its previous pointer to the node at position->previous

Reconnect the relevant nodes in the chain by pointing position->previous->next to the new node and position->previous to the new node

!35

. . .

. . .

. . .

. . .Order Matters!

Page 36: Lists - GitHub Pages

More PseudocodeyInstantiate new node new_ptr = new Node() and new_ptr->setItem()

Obtain pointer position_ptr = getPointerTo(2)

Connect new node to chain new_ptr->next = position_ptr and new_ptr->previous = temp->previous

Reconnect the relevant nodes position_ptr->previous->next = new_ptr and position->previous = new_ptr

!36

. . .

. . .

. . .

. . .

Page 37: Lists - GitHub Pages

template<typename ItemType>bool List<ItemType>::insert(size_t position, const ItemType& new_element) {//Create a new node containing the new entry and get a pointer to position

Node<ItemType>* new_node_ptr = new Node<ItemType>(new_element);Node<ItemType>* pos_ptr = getPointerTo(position);

// Attach new node to chain

else if (pos_ptr == first_) { // Insert new node at head of chain new_node_ptr->setNext(first_); new_node_ptr->setPrevious(nullptr); first_->setPrevious(new_node_ptr); first_ = new_node_ptr;

}else if (pos_ptr == nullptr) {

//insert at end of list new_node_ptr->setNext(nullptr); new_node_ptr->setPrevious(last_); last_->setNext(new_node_ptr); last_ = new_node_ptr;

}else {

// Insert new node before node to which position pointsnew_node_ptr->setNext(pos_ptr);new_node_ptr->setPrevious(pos_ptr->getPrevious());pos_ptr->getPrevious()->setNext(new_node_ptr);pos_ptr->setPrevious(new_node_ptr);

}//end if

item_count_++; // Increase count of entries return true;}//end insert

List::insert

!37

if (first_ == nullptr){

// Insert first nodenew_node_ptr->setNext(nullptr);new_node_ptr->setPrevious(nullptr);first_ = new_node_ptr;

last_ = new_node_ptr;}

Always return true

Page 38: Lists - GitHub Pages

!38

if (first_ == nullptr) { // Insert first node new_node_ptr->setNext(nullptr); new_node_ptr->setPrevious(nullptr); first_ = new_node_ptr; last_ = new_node_ptr; }

first_

last_

Page 39: Lists - GitHub Pages

!39

else if (pos_ptr == first_) { // Insert new node at beginning of chain new_node_ptr->setNext(first_); new_node_ptr->setPrevious(nullptr); first_->setPrevious(new_node_ptr); first_ = new_node_ptr; }

pos_ptr

first_

last_

Page 40: Lists - GitHub Pages

else if (pos_ptr == first_) { // Insert new node at beginning of chain new_node_ptr->setNext(first_); new_node_ptr->setPrevious(nullptr); first_->setPrevious(new_node_ptr); first_ = new_node_ptr; }

!40

first_

last_new_node_ptrpos_ptr

Page 41: Lists - GitHub Pages

else if (pos_ptr == first_) { // Insert new node at beginning of chain new_node_ptr->setNext(first_); new_node_ptr->setPrevious(nullptr); first_->setPrevious(new_node_ptr); first_ = new_node_ptr; }

!41

first_

last_new_node_ptrpos_ptr

Page 42: Lists - GitHub Pages

else if (pos_ptr == first_) { // Insert new node at beginning of chain new_node_ptr->setNext(first_); new_node_ptr->setPrevious(nullptr); first_->setPrevious(new_node_ptr); first_ = new_node_ptr; }

!42

first_

last_new_node_ptrpos_ptr

Page 43: Lists - GitHub Pages

!43

else if (pos_ptr == nullptr) { //insert at end of list new_node_ptr->setNext(nullptr); new_node_ptr->setPrevious(last_); last_->setNext(new_node_ptr); last_ = new_node_ptr; }

pos_ptr

first_

last_

Page 44: Lists - GitHub Pages

else if (pos_ptr == nullptr) { //insert at end of list new_node_ptr->setNext(nullptr); new_node_ptr->setPrevious(last_); last_->setNext(new_node_ptr); last_ = new_node_ptr; }

!44

first_

last_

new_node_ptr

pos_ptr

Page 45: Lists - GitHub Pages

else if (pos_ptr == nullptr) { //insert at end of list new_node_ptr->setNext(nullptr); new_node_ptr->setPrevious(last_); last_->setNext(new_node_ptr); last_ = new_node_ptr; }

!45

first_

last_

new_node_ptr

pos_ptr

Page 46: Lists - GitHub Pages

else if (pos_ptr == nullptr) { //insert at end of list new_node_ptr->setNext(nullptr); new_node_ptr->setPrevious(last_); last_->setNext(new_node_ptr); last_ = new_node_ptr; }

!46

first_

last_

new_node_ptr

pos_ptr

Page 47: Lists - GitHub Pages

!47

else { // Insert new node before node to which position points new_node_ptr->setNext(pos_ptr); new_node_ptr->setPrevious(pos_ptr->getPrevious()); pos_ptr->getPrevious()->setNext(new_node_ptr); pos_ptr->setPrevious(new_node_ptr); } // end if

pos_ptr

first_

last_

Page 48: Lists - GitHub Pages

else { // Insert new node before node to which position points new_node_ptr->setNext(pos_ptr); new_node_ptr->setPrevious(pos_ptr->getPrevious()); pos_ptr->getPrevious()->setNext(new_node_ptr); pos_ptr->setPrevious(new_node_ptr); } // end if

!48

first_

last_

new_node_ptr

pos_ptr

Page 49: Lists - GitHub Pages

else { // Insert new node before node to which position points new_node_ptr->setNext(pos_ptr); new_node_ptr->setPrevious(pos_ptr->getPrevious()); pos_ptr->getPrevious()->setNext(new_node_ptr); pos_ptr->setPrevious(new_node_ptr); } // end if

!49

first_

last_

new_node_ptr

pos_ptr

Page 50: Lists - GitHub Pages

else { // Insert new node before node to which position points new_node_ptr->setNext(pos_ptr); new_node_ptr->setPrevious(pos_ptr->getPrevious()); pos_ptr->getPrevious()->setNext(new_node_ptr); pos_ptr->setPrevious(new_node_ptr); } // end if

!50

first_

last_

new_node_ptr

pos_ptr

Page 51: Lists - GitHub Pages

List::remove

!51

first_

last_

What are the different cases that should be considered?

Page 52: Lists - GitHub Pages

Lecture Activity

Write Pseudocode to remove the node at position 1 in a doubly-linked list (assume position follows classic indexing from 0 to item_count - 1, and there is a node at position 2)

first_

last_

Page 53: Lists - GitHub Pages

template<typename ItemType> bool List<T>::remove(size_t position) { // get pointer to position Node<ItemType>* pos_ptr = getPointerTo(position);

if (pos_ptr == nullptr) // no node at position return false; else {

// Remove node from chain

else if (pos_ptr == last_ ) {//remove last_ nodelast_ = pos_ptr->getPrevious();last_ ->setNext(nullptr);

// Return node to the system pos_ptr->setPrevious(nullptr);

delete pos_ptr;pos_ptr = nullptr;

}else {

//Remove from the middle pos_ptr->getPrevious()->setNext(pos_ptr->getNext()); pos_ptr->getNext()->setPrevious(pos_ptr->getPrevious()); // Return node to the system pos_ptr->setNext(nullptr); pos_ptr->setPrevious(nullptr); delete pos_ptr; pos_ptr = nullptr; } item_count--; return true; }} //end remove

List::Remove

!53

if (pos_ptr == first_) { // Remove first node first_ = pos_ptr->getNext(); first_->setPrevious(nullptr); // Return node to the system pos_ptr->setNext(nullptr); delete pos_ptr; pos_ptr = nullptr; }

Page 54: Lists - GitHub Pages

!54

first_

last_ pos_ptr

// Remove node from chain if (pos_ptr == first_) { // Remove first node first_ = pos_ptr->getNext(); first_->setPrevious(nullptr); // Return node to the system pos_ptr->setNext(nullptr); delete pos_ptr; pos_ptr = nullptr; }

Page 55: Lists - GitHub Pages

!55

first_

last_ pos_ptr

// Remove node from chain if (pos_ptr == first_) { // Remove first node first_ = pos_ptr->getNext(); first_->setPrevious(nullptr); // Return node to the system pos_ptr->setNext(nullptr); delete pos_ptr; pos_ptr = nullptr; }

Page 56: Lists - GitHub Pages

!56

first_

last_ pos_ptr

// Remove node from chain if (pos_ptr == first_) { // Remove first node first_ = pos_ptr->getNext(); first_->setPrevious(nullptr); // Return node to the system pos_ptr->setNext(nullptr); delete pos_ptr; pos_ptr = nullptr; }

Page 57: Lists - GitHub Pages

// Remove node from chain if (pos_ptr == first_) { // Remove first node first_ = pos_ptr->getNext(); first_->setPrevious(nullptr); // Return node to the system pos_ptr->setNext(nullptr); delete pos_ptr; pos_ptr = nullptr; }

!57

first_

last_ pos_ptr

Page 58: Lists - GitHub Pages

!58

first_ last_

pos_ptr

else if (pos_ptr == last_ ) { //remove last_ node last_ = pos_ptr->getPrevious(); last_ ->setNext(nullptr); // Return node to the system pos_ptr->setPrevious(nullptr); delete pos_ptr; pos_ptr = nullptr; }

Page 59: Lists - GitHub Pages

!59

first_ last_

pos_ptr

else if (pos_ptr == last_ ) { //remove last_ node last_ = pos_ptr->getPrevious(); last_ ->setNext(nullptr); // Return node to the system pos_ptr->setPrevious(nullptr); delete pos_ptr; pos_ptr = nullptr; }

Page 60: Lists - GitHub Pages

!60

first_ last_

pos_ptr

else if (pos_ptr == last_ ) { //remove last_ node last_ = pos_ptr->getPrevious(); last_ ->setNext(nullptr); // Return node to the system pos_ptr->setPrevious(nullptr); delete pos_ptr; pos_ptr = nullptr; }

Page 61: Lists - GitHub Pages

else if (pos_ptr == last_ ) { //remove last_ node last_ = pos_ptr->getPrevious(); last_ ->setNext(nullptr); // Return node to the system pos_ptr->setPrevious(nullptr); delete pos_ptr; pos_ptr = nullptr; }

!61

first_ last_

pos_ptr

Page 62: Lists - GitHub Pages

!62

first_ last_

pos_ptr

else if (pos_ptr != nullptr) { //Remove from the middle pos_ptr->getPrevious()->setNext(pos_ptr->getNext()); pos_ptr->getNext()->setPrevious(pos_ptr->getPrevious()); // Return node to the system pos_ptr->setNext(nullptr); pos_ptr->setPrevious(nullptr); delete pos_ptr; pos_ptr = nullptr; } // end if

Page 63: Lists - GitHub Pages

else if (pos_ptr != nullptr) { //Remove from the middle pos_ptr->getPrevious()->setNext(pos_ptr->getNext()); pos_ptr->getNext()->setPrevious(pos_ptr->getPrevious()); // Return node to the system pos_ptr->setNext(nullptr); pos_ptr->setPrevious(nullptr); delete pos_ptr; pos_ptr = nullptr; } // end if

!63

first_ last_

pos_ptr

Page 64: Lists - GitHub Pages

!64

first_ last_

pos_ptr

else if (pos_ptr != nullptr) { //Remove from the middle pos_ptr->getPrevious()->setNext(pos_ptr->getNext()); pos_ptr->getNext()->setPrevious(pos_ptr->getPrevious()); // Return node to the system pos_ptr->setNext(nullptr); pos_ptr->setPrevious(nullptr); delete pos_ptr; pos_ptr = nullptr; } // end if

Page 65: Lists - GitHub Pages

else if (pos_ptr != nullptr) { //Remove from the middle pos_ptr->getPrevious()->setNext(pos_ptr->getNext()); pos_ptr->getNext()->setPrevious(pos_ptr->getPrevious()); // Return node to the system pos_ptr->setNext(nullptr); pos_ptr->setPrevious(nullptr); delete pos_ptr; pos_ptr = nullptr; } // end if

!65

first_ last_

pos_ptr

Page 66: Lists - GitHub Pages

List::getPointerTotemplate<typename ItemType>Node<ItemType>* List<ItemType>::getPointerTo(size_t position) const{ Node<ItemType>* find_ptr = nullptr; // return nullptr if there is no node at position

if(position < item_count) {//there is a node at position find_ptr = first_; for(size_t i = 0; i < position; ++i) { find_ptr = find_ptr->getNext(); }

//find_ptr points to the node at position } return find_ptr;}//end getPointerTo

!66

Page 67: Lists - GitHub Pages

List::getItem

template<typename ItemType> ItemType List<ItemType>::getItem(size_t position) const { Node<ItemType>* pos_ptr = getPointerTo(position); if(pos_ptr != nullptr) return pos_ptr->getItem(); else

??? }

!67

Page 68: Lists - GitHub Pages

List::getItem

template<typename ItemType> ItemType List<ItemType>::getItem(size_t position) const { Node<ItemType>* pos_ptr = getPointerTo(position); if(pos_ptr != nullptr) return pos_ptr->getItem(); else

??? }

!68

Problem: return type is ItemType

There is no “default” or null valueto indicate

uninitialized object