Download presentation
Presentation is loading. Please wait.
Published byEustace Carter Modified over 9 years ago
2
Lists
3
ADT (brief intro): Abstract Data Type A DESCRIPTION of a data type The data type can be anything: lists, sets, trees, stacks, etc. What we want to do at the ADT level is describe what it is and what it should do We don’t worry about HOW it does it There’s no definite rule for what operations must be supported for each type Use what makes sense.
4
Lists: Things we know about lists: The items have an order One comes after another - this doesn’t mean they’re “ordered” in any purposeful way, but there’s a built in order to the elements in a list The list has a size (n elements in the list) Data in a list can be duplicated All elements in the list are of the same data type
5
List operations we might want: push(x)-add to end of list insert(x,k) adds item x to list at kth position remove (Node *node) – removes a node from the list removekth(int kth) – removes the node at the kth position from the list pop() – removes the last element from the list size() - gives you number of elements in list isEmpty() – returns true iff the list is empty find(x) – return the position of x in the list (usually -1 if not in list) findkth(k) – return the item at the kth position in the list printList() – you figure it out … I’m sure there are other things you’d want to be able to do with a list.
6
Linked List (versus Array): Every element in a linked list consists of at a minimum 2 parts: The data A pointer to (aka the address of ) the element coming next in the list No fixed size (no limit on the number of elements in the list) No “wasted space” No empty spaces in between elements in the list Sequential access (as opposed to random access, like an array) 3 7 4 2 NULL Nodes in a linked list
7
Node implementation: class Node { friend class LL; // allows another class to access privage members of the Node class int data; Node *next; public: Node(int x); ~Node(); }; //Node Node::Node(int x){ data = x; next = NULL; } //Constructor Node::~Node() { if (next != NULL) { cout << “deleting may cause memory leak.” << endl; } //if } //destuctor
8
A list class (A list of nodes): #include "Node.hpp“ class LL { Node *first; int currsize; public: LL(); ~LL(); void push(); void insert(x,k); void remove (int pos); int pop(); int size(); bool isEmpty(); int find(x); Node * findkth(k); };
9
Push: //adds node to end of list If the list is empty? Create the new node Set the first pointer to point to the new node Set the currsize to 1 void LL::push() { int x = rand()%10; if (first == NULL) { first = new Node(x); } //if currsize=1; } //push class LL { Node *first; int currsize; public: … void push(); … }; 7 NULL first
10
Push: //adds node to end of list If List is not empty? class LL { Node *first; int currsize; public: … void push(); … }; first 7 4 3 NULL temp NULL 8 new Node(8) Node *temp = first; while (temp->next != NULL) { //Why isn’t the condition while (temp != NULL) { ? temp = temp->next; } //while temp->next = new Node(x); currsize++; How many steps to push onto the list? Is there a more efficient way? (Hint: yes, there is!!!)
11
Adding a last node pointer: When we start list: last = first; When we’re pushing onto the end of an existing list: last->next = new Node(8); last = last->next; Now what is the count for push()? 7 NULL first NULL first 7 4 3 8 NULL last class LL { Node *first; Node *last; int currsize; public: … void push(); … };
12
7 4 3 8 NULL 9 void insert(x,k); Inserting node with data, x= 9 at k = 2; last first How do we get to the kth position in the list? Loop! Do we loop to the kth position or the k-1th position? Why? Is there a better way? What if we did this with an array? Node *n = new Node(9); n->next = node4->next; node4->next = n;
13
insert(x,k) bool LLC::insert(int x, int k) { if (k > currsize) { //illegal insert return false; } //if else { // inserting a new node NodeC *n = new NodeC(x); if (k == 0) { //inserting at front of list if (first == NULL) { //empty list last = n; } //if else { n->next = first; } //else first = n; }// if else if (k != 0){ NodeC *temp = first; for (int j = 0; j < k-1; j++) { temp = temp->next; } //for n->next = temp->next; temp->next = n; if (k == currsize) { //inserting at end of list last = temp->next; } //if } // else if } //else currsize++; return true; } //insert
14
Problems with Linked List (as we’ve seen so far…) We can insert a node only after a node we have a pointer to. We can remove a node only if we have a pointer to its predecessor node We can traverse the list in only the forward direction Solution?
15
Stack Subset of list Only 2 operations: push() and pop() Stick something on the end of the stack, or take something off the end of the stack Last-in, first-out (LIFO) Think of a pile of … almost anything at all … you can’t take anything off the BOTTOM of the pile, only off the top. Equally, you can’t add to the pile at the bottom, only at the top. Applications: Reversing a word The “undo” option Backgracking in a maze Memory for functions (the easiest way to visualize this is recursion) Linked list or array?? Hint: oh please…
16
Pop() How do we implement pop? How many steps? Now pop again… Where is the last pointer still pointing? Is there a better way? What about arrays – will that work better? first 7 4 3 NULL 8 last
17
Doubly-linked list Now what do we need to do? Node *temp = last; last = last->prev; delete temp; last->next = NULL; Now how many steps? class Node { friend class LL; int data; Node *next; Node *prev; public: Node(int x); ~Node(); }; //Node first 7 4 3 NULL 8 last NULL temp NULL
18
Doubly-linked list: Disadvantages: A bit more memory (now we’ve got that prev pointer space for each node) Must manage more pointers when performing operations on the linked list (e.g., insert, remove, etc.) Advantages: Makes pop() easier (O(1)) Makes traversing the list in reverse order easier Reversing the list is easy now Can go backwards and forwards from a node in a list We may need surrounding nodes We may need data that occurred “close to” a node with certain data What about inserting into an ordered list?
19
Inserting 6 into the ordered list: Node *temp = first; while (temp->data < 6) { // left out check for end of list temp = temp->next; } Node *n = new Node(6); n->prev = temp->prev; temp->prev->next = n; n->next = temp; Easier with a doubly-linked list? first 2 4 7 NULL 8 last NULL 6 temp n
20
Circular List Can be singly or doubly linked list Make the “last” node’s next pointer point to the first node. No NULL pointers Don’t have to worry about “falling off the end” of the list Can hit all items in the list, even if we start looking in the middle tail->next = head; head->prev = tail; // if doubly-linked Do we still need a head and tail pointer? first 7 4 3 8 last
21
Circular linked lists: Works nicely with queues: FIFO (or LILO) First in, first out Think of the check-out line in a store To-do lists The printing jobs coming into a printer Now to insert new job: Node *n = new Node(20); n->next = last->next; last->next = n; To remove a job: Node *n = last->next; last->next = last->next->next; delete n; What if there’s only one node in the list? What about searching for a particular node in the list? What if the node isn’t in the list?
22
How about Find in a linked list? Find 3 in the list Find 6 in the list O(n) Is there a better way? Binary search tree! 7 4 3 8 NULL last first
23
23 Tree (new ADT) Terminology: A tree is a collection of elements (nodes) Each node may have 0 or more successors (called children) How many does a list have? Each node has exactly one predecessor (called the parent) Except the starting node, called the root Links from node to its successors are called branches Nodes with same parent are siblings Nodes with no children are called leaves
24
24 Tree We also use words like ancestor and descendent Pets is the parent of Dogs and Cats Poodle and Beagle are the children of Dogs Poodle, Beagle, Persian, and Siamese are descendents of Pets, Pets is the ancestor of Poodle, Beagle, Persian, and Siamese
25
25 Tree Terminology Subtree of a node: A tree whose root is a child of that node Depth of a node: A measure of its distance from the root: Depth of the root = 0 Depth of other nodes = 1 + depth of parent 2 1 3 4
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.