#delete middle node doubly linked list
Explore tagged Tumblr posts
bmharwani · 7 years ago
Photo
Tumblr media
Video tutorial explains a C program to delete a node from doubly linked list. You will learn to delete first node, middle node as well as last node ffrom the doubly linked list. Doubly linked list is also known as two-way linked list. The C program is explained using step by step approach along with figures at each step. Entire source code is explained statement wise. In this tutorial, you will learn   double link list deletion, delete the first node of doubly linked list and delete node at given position in doubly linked list. This online data structures and algorithms tutorial teaches, data structures in c, data structures interview questions and answers and data structures along with data structure programs. By the end of the vide you will be knowing, data structures and algorithms lectures, data structures tutorial videos and online data structures training. Complete coding is explained with figures at each step, you will understand, delete node at given position, data structures interview questions and previous pointer along with linked list using c. If you are looking for, delete a node from linked list, how to delete a node in doubly linked list and algorithm to delete a node from doubly linked list, then this video is for you. For code of deleting a node from doubly linked list, click the following link: http://bmharwani.com/deletefromdoubly.c For more video tutorials on data structures and algorithms, visit: https://www.youtube.com/watch?v=-XXsmBys2DQ&t=0s&list=PLuDr_vb2LpAxVWIk-po5nL5Ct2pHpndLR&index=6 To get notification for new videos, subscribe to my channel: https://youtube.com/c/bintuharwani To see more videos on different computer subjects, visit: http://bmharwani.com
2 notes · View notes
courseforfree · 4 years ago
Link
Data Structures and Algorithms from Zero to Hero and Crack Top Companies 100+ Interview questions (Java Coding)
What you’ll learn
Java Data Structures and Algorithms Masterclass
Learn, implement, and use different Data Structures
Learn, implement and use different Algorithms
Become a better developer by mastering computer science fundamentals
Learn everything you need to ace difficult coding interviews
Cracking the Coding Interview with 100+ questions with explanations
Time and Space Complexity of Data Structures and Algorithms
Recursion
Big O
Dynamic Programming
Divide and Conquer Algorithms
Graph Algorithms
Greedy Algorithms
Requirements
Basic Java Programming skills
Description
Welcome to the Java Data Structures and Algorithms Masterclass, the most modern, and the most complete Data Structures and Algorithms in Java course on the internet.
At 44+ hours, this is the most comprehensive course online to help you ace your coding interviews and learn about Data Structures and Algorithms in Java. You will see 100+ Interview Questions done at the top technology companies such as Apple, Amazon, Google, and Microsoft and how-to face Interviews with comprehensive visual explanatory video materials which will bring you closer to landing the tech job of your dreams!
Learning Java is one of the fastest ways to improve your career prospects as it is one of the most in-demand tech skills! This course will help you in better understanding every detail of Data Structures and how algorithms are implemented in high-level programming languages.
We’ll take you step-by-step through engaging video tutorials and teach you everything you need to succeed as a professional programmer.
After finishing this course, you will be able to:
Learn basic algorithmic techniques such as greedy algorithms, binary search, sorting, and dynamic programming to solve programming challenges.
Learn the strengths and weaknesses of a variety of data structures, so you can choose the best data structure for your data and applications
Learn many of the algorithms commonly used to sort data, so your applications will perform efficiently when sorting large datasets
Learn how to apply graph and string algorithms to solve real-world challenges: finding shortest paths on huge maps and assembling genomes from millions of pieces.
Why this course is so special and different from any other resource available online?
This course will take you from the very beginning to very complex and advanced topics in understanding Data Structures and Algorithms!
You will get video lectures explaining concepts clearly with comprehensive visual explanations throughout the course.
You will also see Interview Questions done at the top technology companies such as Apple, Amazon, Google, and Microsoft.
I cover everything you need to know about the technical interview process!
So whether you are interested in learning the top programming language in the world in-depth and interested in learning the fundamental Algorithms, Data Structures, and performance analysis that make up the core foundational skillset of every accomplished programmer/designer or software architect and is excited to ace your next technical interview this is the course for you!
And this is what you get by signing up today:
Lifetime access to 44+ hours of HD quality videos. No monthly subscription. Learn at your own pace, whenever you want
Friendly and fast support in the course Q&A whenever you have questions or get stuck
FULL money-back guarantee for 30 days!
This course is designed to help you to achieve your career goals. Whether you are looking to get more into Data Structures and Algorithms, increase your earning potential, or just want a job with more freedom, this is the right course for you!
The topics that are covered in this course.
Section 1 – Introduction
What are Data Structures?
What is an algorithm?
Why are Data Structures And Algorithms important?
Types of Data Structures
Types of Algorithms
Section 2 – Recursion
What is Recursion?
Why do we need recursion?
How does Recursion work?
Recursive vs Iterative Solutions
When to use/avoid Recursion?
How to write Recursion in 3 steps?
How to find Fibonacci numbers using Recursion?
Section 3 – Cracking Recursion Interview Questions
Question 1 – Sum of Digits
Question 2 – Power
Question 3 – Greatest Common Divisor
Question 4 – Decimal To Binary
Section 4 – Bonus CHALLENGING Recursion Problems (Exercises)
power
factorial
products array
recursiveRange
fib
reverse
palindrome
some recursive
flatten
capitalize first
nestedEvenSum
capitalize words
stringifyNumbers
collects things
Section 5 – Big O Notation
Analogy and Time Complexity
Big O, Big Theta, and Big Omega
Time complexity examples
Space Complexity
Drop the Constants and the nondominant terms
Add vs Multiply
How to measure the codes using Big O?
How to find time complexity for Recursive calls?
How to measure Recursive Algorithms that make multiple calls?
Section 6 – Top 10 Big O Interview Questions (Amazon, Facebook, Apple, and Microsoft)
Product and Sum
Print Pairs
Print Unordered Pairs
Print Unordered Pairs 2 Arrays
Print Unordered Pairs 2 Arrays 100000 Units
Reverse
O(N)  Equivalents
Factorial Complexity
Fibonacci Complexity
Powers of 2
Section 7 – Arrays
What is an Array?
Types of Array
Arrays in Memory
Create an Array
Insertion Operation
Traversal Operation
Accessing an element of Array
Searching for an element in Array
Deleting an element from Array
Time and Space complexity of One Dimensional Array
One Dimensional Array Practice
Create Two Dimensional Array
Insertion – Two Dimensional Array
Accessing an element of Two Dimensional Array
Traversal – Two Dimensional Array
Searching for an element in Two Dimensional Array
Deletion – Two Dimensional Array
Time and Space complexity of Two Dimensional Array
When to use/avoid array
Section 8 – Cracking Array Interview Questions (Amazon, Facebook, Apple, and Microsoft)
Question 1 – Missing Number
Question 2 – Pairs
Question 3 – Finding a number in an Array
Question 4 – Max product of two int
Question 5 – Is Unique
Question 6 – Permutation
Question 7 – Rotate Matrix
Section 9 – CHALLENGING Array Problems (Exercises)
Middle Function
2D Lists
Best Score
Missing Number
Duplicate Number
Pairs
Section 10 – Linked List
What is a Linked List?
Linked List vs Arrays
Types of Linked List
Linked List in the Memory
Creation of Singly Linked List
Insertion in Singly Linked List in Memory
Insertion in Singly Linked List Algorithm
Insertion Method in Singly Linked List
Traversal of Singly Linked List
Search for a value in Single Linked List
Deletion of a node from Singly Linked List
Deletion Method in Singly Linked List
Deletion of entire Singly Linked List
Time and Space Complexity of Singly Linked List
Section 11 – Circular Singly Linked List
Creation of Circular Singly Linked List
Insertion in Circular Singly Linked List
Insertion Algorithm in Circular Singly Linked List
Insertion method in Circular Singly Linked List
Traversal of Circular Singly Linked List
Searching a node in Circular Singly Linked List
Deletion of a node from Circular Singly Linked List
Deletion Algorithm in Circular Singly Linked List
A method in Circular Singly Linked List
Deletion of entire Circular Singly Linked List
Time and Space Complexity of Circular Singly Linked List
Section 12 – Doubly Linked List
Creation of Doubly Linked List
Insertion in Doubly Linked List
Insertion Algorithm in Doubly Linked List
Insertion Method in Doubly Linked List
Traversal of Doubly Linked List
Reverse Traversal of Doubly Linked List
Searching for a node in Doubly Linked List
Deletion of a node in Doubly Linked List
Deletion Algorithm in Doubly Linked List
Deletion Method in Doubly Linked List
Deletion of entire Doubly Linked List
Time and Space Complexity of Doubly Linked List
Section 13 – Circular Doubly Linked List
Creation of Circular Doubly Linked List
Insertion in Circular Doubly Linked List
Insertion Algorithm in Circular Doubly Linked List
Insertion Method in Circular Doubly Linked List
Traversal of Circular Doubly Linked List
Reverse Traversal of Circular Doubly Linked List
Search for a node in Circular Doubly Linked List
Delete a node from Circular Doubly Linked List
Deletion Algorithm in Circular Doubly Linked List
Deletion Method in Circular Doubly Linked List
Entire Circular Doubly Linked List
Time and Space Complexity of Circular Doubly Linked List
Time Complexity of Linked List vs Arrays
Section 14 – Cracking Linked List Interview Questions (Amazon, Facebook, Apple, and Microsoft)
Linked List Class
Question 1 – Remove Dups
Question 2 – Return Kth to Last
Question 3 – Partition
Question 4 – Sum Linked Lists
Question 5 – Intersection
Section 15 – Stack
What is a Stack?
What and Why of Stack?
Stack Operations
Stack using Array vs Linked List
Stack Operations using Array (Create, isEmpty, isFull)
Stack Operations using Array (Push, Pop, Peek, Delete)
Time and Space Complexity of Stack using Array
Stack Operations using Linked List
Stack methods – Push, Pop, Peek, Delete, and isEmpty using Linked List
Time and Space Complexity of Stack using Linked List
When to Use/Avoid Stack
Stack Quiz
Section 16 – Queue
What is a Queue?
Linear Queue Operations using Array
Create, isFull, isEmpty, and enQueue methods using Linear Queue Array
Dequeue, Peek and Delete Methods using Linear Queue Array
Time and Space Complexity of Linear Queue using Array
Why Circular Queue?
Circular Queue Operations using Array
Create, Enqueue, isFull and isEmpty Methods in Circular Queue using Array
Dequeue, Peek and Delete Methods in Circular Queue using Array
Time and Space Complexity of Circular Queue using Array
Queue Operations using Linked List
Create, Enqueue and isEmpty Methods in Queue using Linked List
Dequeue, Peek and Delete Methods in Queue using Linked List
Time and Space Complexity of Queue using Linked List
Array vs Linked List Implementation
When to Use/Avoid Queue?
Section 17 – Cracking Stack and Queue Interview Questions (Amazon, Facebook, Apple, Microsoft)
Question 1 – Three in One
Question 2 – Stack Minimum
Question 3 – Stack of Plates
Question 4 – Queue via Stacks
Question 5 – Animal Shelter
Section 18 – Tree / Binary Tree
What is a Tree?
Why Tree?
Tree Terminology
How to create a basic tree in Java?
Binary Tree
Types of Binary Tree
Binary Tree Representation
Create Binary Tree (Linked List)
PreOrder Traversal Binary Tree (Linked List)
InOrder Traversal Binary Tree (Linked List)
PostOrder Traversal Binary Tree (Linked List)
LevelOrder Traversal Binary Tree (Linked List)
Searching for a node in Binary Tree (Linked List)
Inserting a node in Binary Tree (Linked List)
Delete a node from Binary Tree (Linked List)
Delete entire Binary Tree (Linked List)
Create Binary Tree (Array)
Insert a value Binary Tree (Array)
Search for a node in Binary Tree (Array)
PreOrder Traversal Binary Tree (Array)
InOrder Traversal Binary Tree (Array)
PostOrder Traversal Binary Tree (Array)
Level Order Traversal Binary Tree (Array)
Delete a node from Binary Tree (Array)
Entire Binary Tree (Array)
Linked List vs Python List Binary Tree
Section 19 – Binary Search Tree
What is a Binary Search Tree? Why do we need it?
Create a Binary Search Tree
Insert a node to BST
Traverse BST
Search in BST
Delete a node from BST
Delete entire BST
Time and Space complexity of BST
Section 20 – AVL Tree
What is an AVL Tree?
Why AVL Tree?
Common Operations on AVL Trees
Insert a node in AVL (Left Left Condition)
Insert a node in AVL (Left-Right Condition)
Insert a node in AVL (Right Right Condition)
Insert a node in AVL (Right Left Condition)
Insert a node in AVL (all together)
Insert a node in AVL (method)
Delete a node from AVL (LL, LR, RR, RL)
Delete a node from AVL (all together)
Delete a node from AVL (method)
Delete entire AVL
Time and Space complexity of AVL Tree
Section 21 – Binary Heap
What is Binary Heap? Why do we need it?
Common operations (Creation, Peek, sizeofheap) on Binary Heap
Insert a node in Binary Heap
Extract a node from Binary Heap
Delete entire Binary Heap
Time and space complexity of Binary Heap
Section 22 – Trie
What is a Trie? Why do we need it?
Common Operations on Trie (Creation)
Insert a string in Trie
Search for a string in Trie
Delete a string from Trie
Practical use of Trie
Section 23 – Hashing
What is Hashing? Why do we need it?
Hashing Terminology
Hash Functions
Types of Collision Resolution Techniques
Hash Table is Full
Pros and Cons of Resolution Techniques
Practical Use of Hashing
Hashing vs Other Data structures
Section 24 – Sort Algorithms
What is Sorting?
Types of Sorting
Sorting Terminologies
Bubble Sort
Selection Sort
Insertion Sort
Bucket Sort
Merge Sort
Quick Sort
Heap Sort
Comparison of Sorting Algorithms
Section 25 – Searching Algorithms
Introduction to Searching Algorithms
Linear Search
Linear Search in Python
Binary Search
Binary Search in Python
Time Complexity of Binary Search
Section 26 – Graph Algorithms
What is a Graph? Why Graph?
Graph Terminology
Types of Graph
Graph Representation
The graph in Java using Adjacency Matrix
The graph in Java using Adjacency List
Section 27 – Graph Traversal
Breadth-First Search Algorithm (BFS)
Breadth-First Search Algorithm (BFS) in Java – Adjacency Matrix
Breadth-First Search Algorithm (BFS) in Java – Adjacency List
Time Complexity of Breadth-First Search (BFS) Algorithm
Depth First Search (DFS) Algorithm
Depth First Search (DFS) Algorithm in Java – Adjacency List
Depth First Search (DFS) Algorithm in Java – Adjacency Matrix
Time Complexity of Depth First Search (DFS) Algorithm
BFS Traversal vs DFS Traversal
Section 28 – Topological Sort
What is Topological Sort?
Topological Sort Algorithm
Topological Sort using Adjacency List
Topological Sort using Adjacency Matrix
Time and Space Complexity of Topological Sort
Section 29 – Single Source Shortest Path Problem
what is Single Source Shortest Path Problem?
Breadth-First Search (BFS) for Single Source Shortest Path Problem (SSSPP)
BFS for SSSPP in Java using Adjacency List
BFS for SSSPP in Java using Adjacency Matrix
Time and Space Complexity of BFS for SSSPP
Why does BFS not work with Weighted Graph?
Why does DFS not work for SSSP?
Section 30 – Dijkstra’s Algorithm
Dijkstra’s Algorithm for SSSPP
Dijkstra’s Algorithm in Java – 1
Dijkstra’s Algorithm in Java – 2
Dijkstra’s Algorithm with Negative Cycle
Section 31 – Bellman-Ford Algorithm
Bellman-Ford Algorithm
Bellman-Ford Algorithm with negative cycle
Why does Bellman-Ford run V-1 times?
Bellman-Ford in Python
BFS vs Dijkstra vs Bellman Ford
Section 32 – All Pairs Shortest Path Problem
All pairs shortest path problem
Dry run for All pair shortest path
Section 33 – Floyd Warshall
Floyd Warshall Algorithm
Why Floyd Warshall?
Floyd Warshall with negative cycle,
Floyd Warshall in Java,
BFS vs Dijkstra vs Bellman Ford vs Floyd Warshall,
Section 34 – Minimum Spanning Tree
Minimum Spanning Tree,
Disjoint Set,
Disjoint Set in Java,
Section 35 – Kruskal’s and Prim’s Algorithms
Kruskal Algorithm,
Kruskal Algorithm in Python,
Prim’s Algorithm,
Prim’s Algorithm in Python,
Prim’s vs Kruskal
Section 36 – Cracking Graph and Tree Interview Questions (Amazon, Facebook, Apple, Microsoft)
Section 37 – Greedy Algorithms
What is a Greedy Algorithm?
Well known Greedy Algorithms
Activity Selection Problem
Activity Selection Problem in Python
Coin Change Problem
Coin Change Problem in Python
Fractional Knapsack Problem
Fractional Knapsack Problem in Python
Section 38 – Divide and Conquer Algorithms
What is a Divide and Conquer Algorithm?
Common Divide and Conquer algorithms
How to solve the Fibonacci series using the Divide and Conquer approach?
Number Factor
Number Factor in Java
House Robber
House Robber Problem in Java
Convert one string to another
Convert One String to another in Java
Zero One Knapsack problem
Zero One Knapsack problem in Java
Longest Common Sequence Problem
Longest Common Subsequence in Java
Longest Palindromic Subsequence Problem
Longest Palindromic Subsequence in Java
Minimum cost to reach the Last cell problem
Minimum Cost to reach the Last Cell in 2D array using Java
Number of Ways to reach the Last Cell with given Cost
Number of Ways to reach the Last Cell with given Cost in Java
Section 39 – Dynamic Programming
What is Dynamic Programming? (Overlapping property)
Where does the name of DC come from?
Top-Down with Memoization
Bottom-Up with Tabulation
Top-Down vs Bottom Up
Is Merge Sort Dynamic Programming?
Number Factor Problem using Dynamic Programming
Number Factor: Top-Down and Bottom-Up
House Robber Problem using Dynamic Programming
House Robber: Top-Down and Bottom-Up
Convert one string to another using Dynamic Programming
Convert String using Bottom Up
Zero One Knapsack using Dynamic Programming
Zero One Knapsack – Top Down
Zero One Knapsack – Bottom Up
Section 40 – CHALLENGING Dynamic Programming Problems
Longest repeated Subsequence Length problem
Longest Common Subsequence Length problem
Longest Common Subsequence  problem
Diff Utility
Shortest Common Subsequence  problem
Length of Longest Palindromic Subsequence
Subset Sum Problem
Egg Dropping Puzzle
Maximum Length Chain of Pairs
Section 41 – A Recipe for Problem Solving
Introduction
Step 1 – Understand the problem
Step 2 – Examples
Step 3 – Break it Down
Step 4 – Solve or Simplify
Step 5 – Look Back and Refactor
Section 41 – Wild West
Download
To download more paid courses for free visit course catalog where  1000+ paid courses available for free. You can get the full course into your device with just a single click. Follow the link above to download this course for free. 
3 notes · View notes
tonkibasic · 3 years ago
Text
Linked list stack implememntation using two queues 261
Tumblr media
Linked list stack implememntation using two queues 261 code#
Fortunately, JavaScript arrays implement this for us in the form of the length property. algorithms (sorting, using stacks and queues, tree exploration algorithms, etc.). A common additional operation for collection data structures is the size, as it allows you to safely iterate the elements and find out if there are any more elements present in the data structure. Data structures: Abstract data types (ADTs), vector, deque, list, queue. Again, it doesn't change the index of the other items in the array, so it is O(1). Similarly, on pop, we simply pop the last value from the array. As it doesn't change the index of the current items, this is O(1). On push, we simply push the new item into the array. Therefore, we can simply implement the operations of this data structure using an array. Fortunately, in JavaScript implementations, array functions that do not require any changes to the index of the current items have an average runtime of O(1). First node have null in link field and second node link have first node address in link field and so on and last node address in. which is head of the stack where pushing and popping items happens at the head of the list. In stack Implementation, a stack contains a top pointer. You will use only one C file (stackfromqueue.c)containing all the functions to design the entire interface. The objective is to implement these push and pop operations such that they operate in O(1) time. A stack can be easily implemented using the linked list. Part 3: Linked List Stack Implementation Using Two Queues Inthis part, you will use two instances of Queue ADT to implement aStack ADT. This fact can be modeled into the type system by using a union of T and undefined. If there are no more items, we can return an out-of-bound value, for example, undefined. The other key operation pops an item from the stack, again in O(1). The first one is push, which adds an item in O(1). StdOut.java A list implemented with a doubly linked list. js is the open source HTML5 audio player. The stack data structure has two key operations. js, a JavaScript library with the goal of making coding accessible to artists, designers, educators, and beginners. We can model this easily in TypeScript using the generic class for items of type T. Using Python, create an implementation of Deque (double-ended queue) with linked list nodes.
Linked list stack implememntation using two queues 261 code#
So deleting of the middle element can be done in O(1) if we just pop the element from the front of the deque.A stack is a last-in/first-out data structure with key operations having a time complexity of O(1). I encountered this question as I am preparing for my code interview. The stack functions worked on from Worksheet 17 were re-implemented using the queue functions worked on from Worksheet 18. Overview: This program is an implementation of a stack using two instances of a queue. Here each new node will be dynamically allocated, so overflow is not possible unless memory is exhausted. Using an array will restrict the maximum capacity of the array, which can lead to stack overflow. You must use only standard operations of a queue - which means only push to back, peek/pop from front, size, and is empty operations are valid. The advantage of using a linked list over arrays is that it is possible to implement a stack that can grow or shrink as much as needed. empty () - Return whether the stack is empty. We will see that the middle element is always the front element of the deque. Stack With Two Queues (Linked List) Zedrimar. pop () - Removes the element on top of the stack. If after the pop operation, the size of the deque is less than the size of the stack, we pop an element from the top of the stack and insert it back into the front of the deque so that size of the deque is not less than the stack. The pop operation on myStack will remove an element from the back of the deque. The number of elements in the deque stays 1 more or equal to that in the stack, however, whenever the number of elements present in the deque exceeds the number of elements in the stack by more than 1 we pop an element from the front of the deque and push it into the stack. Insert operation on myStack will add an element into the back of the deque. We will use a standard stack to store half of the elements and the other half of the elements which were added recently will be present in the deque. Method 2: Using a standard stack and a deque ISRO CS Syllabus for Scientist/Engineer Exam.ISRO CS Original Papers and Official Keys.GATE CS Original Papers and Official Keys.
Tumblr media
0 notes
felord · 6 years ago
Text
cop3503 Project 1 – Templated Linked List Solved
Overview
The purpose of this assignment is for you to write a data structure called a Linked List, which utilizes templates (similar to Java’s generics), in order to store any type of data. In addition, the nature of a Linked List will give you some experience dealing with non-contiguous memory organization. This will also give you more experience using pointers and memory management. Pointers, memory allocation, and understand how data is stored in memory will serve you well in a variety of situations, not just for an assignment like this.
Background
Remember Memory? Variables, functions, pointers—everything takes up SOME space in memory. Sometimes that memory is occupied for only a short duration (a temporary variable in a function), sometimes that memory is allocated at the start of a program and hangs around for the lifetime of that program. Visualizing memory can be difficult sometimes, but very helpful. You may see diagrams of memory like this:
Tumblr media
Or, you may see diagrams like these:
Tumblr media
If you are trying to draw out some representation of memory to help you solve a problem, any of these (or some alternative that makes sense to you) will be fine.
Arrays
Arrays are stored in what is called contiguous memory. A contiguous memory block is one that is not interrupted by anything else (i.e. any other memory block). So if you created an array of 5 integers, each of those integers would be located one after the other in memory, with nothing else occupying memory between them. This is true for all arrays, of any data type.  
Tumblr media
All of the data in an application is not guaranteed to be contiguous, nor does it need to be. Arrays are typically the simplest and fastest way to store data, but they have a grand total of zero features. You allocate one contiguous block, but you can’t resize it, removing elements is a pain (and slow), etc. Consider the previous array. What if you wanted to add another element to that block of memory? If the surrounding memory is occupied, you can’t simply overwrite that with your new data element and expect good results.  
Tumblr media
someArray = 12; // #badIdea                This will almost certainly break. Other Memory   In this scenario, in order to store one more element you would have to: Create another array that was large enough to store all of the old elements plus the new one Copy over all of the data elements one at a time (including the new element, at the end) Free up the old array—no point in having two copies of the data  
Tumblr media
Other Memory Newly available memory Someone else’s memory 10 12 This process has to be repeated each time you want to add to the array (either at the end, or insert in the middle), or remove anything from the array. It can quite costly, in terms of performance, to delete/rebuild an entire array every time you want to make a single change. Cue the Linked List!
Linked List
The basic concept behind a Linked List is simple: It’s a container that stores its elements in a non-contiguous fashion Each element knows about the location of the element which comes after it (and possibly before, more on that later) So instead of a contiguous array, where element 4 comes after element 3, which comes after element 2, etc… you might have something like this:
Tumblr media
Each element in the Linked List (typically referred to as a “node”) stores some data, and then stores a reference (a pointer, in C++), so the node which should come next. The First node knows only about the Second node. The Second node knows only about the Third, etc. The Fourth node has a null pointer as its “next” node, indicating that we’ve reached the end of the data. A real-world example can be helpful as well. Think about a line of people, with one person at the front of the line. That person might know about the person who is next in line, but no further than that (beyond him or herself, the person at the front doesn’t need to know or care). The second person in line might know about the third person in line, but no further. Continuing on this way, the last person in line knows that there is no one else that follows, so that must be the end. Since no one is behind that person, we must be at the end of the line.  
Tumblr media
So… What are the advantages of storing data like this? When inserting elements to an array, the entire array has to be reallocated. With a Linked List, only a small number of elements are affected. Only elements surrounding the changed element need to be updated, and all other elements can remain unaffected. This makes the Linked List much more efficient when it comes to adding or removing elements. Now, imagine one person wants to step out of line. If this were an array, all of the data would have to be reconstructed elsewhere. In a Linked List, only three nodes are affected: 1) The person leaving, 2) the person in front of that person, and 3) the person behind that person. Imagine you are the person at the front of the line. You don’t really need to know or care what happens 10 people behind you, as that has no impact on you whatsoever.
Tumblr media
If the 5th person in line leaves, the only parts of the line that should be impacted are the 4th, 5th, and 6th spaces. Person 4 has a new “next” Person: whomever was behind the person behind them (Person 6). Person 5 has to be removed from the list. Person 6… actually does nothing. In this example, a Person only cares about whomever comes after them. Since Person 5 was before Person 6, Person 6 is unaffected. (A Linked List could be implemented with two-way information between nodes—more on that later). The same thought-process can be applied if someone stepped into line (maybe a friend was holding their place):
Tumblr media
In this case, Person 2 would change their “next” person from Person 3, to the new Person being added. New Guy would have his “next” pointer set to whomever Person 2 was previously keeping track of, Person 3. Because of the ordering process, Person 3 would remain unchanged, as would anyone else in the list (aside from being a bit irritated at the New Guy for cutting in line). So that’s the concept behind a Linked List. A series of “nodes” which are connected via pointer to one another, and inserting/deleting nodes is a faster process than deleting and reconstructing the entire collection of data. Now, how to go about creating that?
Terminology
Node The fundamental building block of a Linked List. A node contains the data actually being stored in the list, as well as 1 or more pointers to other nodes. This is typically implemented as a nested class (see below). Singly-linked A Linked List would be singly-linked if each node only has a single pointer to another node, typically a “next” pointer. This only allows for uni-directional traversal of the data—from beginning to end. Doubly-linked Each node contains 2 pointers: a “next” pointer and a “previous” pointer. This allows for bi-directional traversal of the data—either from front-to-back or backto-front. Head A pointer to the first node in the list, akin to index 0 of an array. Tail A pointer to the last node in the list. May or may not be used, depending on the implementation of the list.  
Nested Classes
The purpose of writing a class is to group data and functionality. The purpose of a nested class is the same—the only difference is where we declare a nested class. We declare a nested class like this: class MyClass { public: // Nested class    class NestedClass { int x, y, z;       NestedClass();       ~NestedClass();       int SomeFunction(); }; private: // Data for "MyClass" NestedClass myData;    NestedClass *somePtr;    float values; MyClass(); // Etc… }; // To create nested classes… // Use the Scope Resolution Operator MyClass::NestedClass someVariable;   // With a class template… TemplateClass foo; TemplateClass::Nested bar;   /* NOTE: You can make nested classes private if you wish, to prevent access to them outside of the encapsulating class. */ Additional reading: http://en.cppreference.com/w/cpp/language/nested_types The nature of the Linked List is that each piece of information knows about the information which follows (or precedes) it. It would make sense, then, to create some nested class to group all of that information together.  
Benefits and Drawbacks
All data structures in programming (C++ or otherwise) have advantages and disadvantages. There is no “one size fits all” data structure. Some are faster (in some cases), some have smaller memory footprints, and some are more flexible in their functionality, which can make life easier for the programmer. Linked List versus Array – Who Wins? Array Linked List Fast access of individual elements as well as iteration over the entire array Changing the Linked List is fast – nodes can be inserted/removed very quickly Random access – You can quickly “jump” to the appropriate memory location of an element Less affected by memory fragmentation, nodes can fit anywhere in memory Changing the array is slow – Have to rebuild the entire array when adding/removing elements No random access, slow iteration Memory fragmentation can be an issue for arrays—need a single, contiguous block large enough for all of the data Extra memory overhead for nodes/pointers Slow to access individual elements
Code Structure
As shown above, the Linked List class itself stores very little data: Pointers to the first and last nodes, and a count. In some implementations, you might only have a pointer to the first node, and that’s it. In addition to those data members, your Linked List class must conform to the following interface:                
Function Reference
Accessors PrintForward Iterator through all of the nodes and print out their values, one a time. PrintReverse Exactly the same as PrintForward, except completely the opposite. NodeCount Wait, we’re storing how many things in this list? FindAll Find all nodes which match the passed in parameter value, and store a pointer to that node in the passed in vector. Use of a parameter like this (passing a something in by reference, and storing data for later use) is called an output parameter. Find Find the first node with a data value matching the passed in parameter, returning a pointer to that node. Returns null if no matching node found. const and nonconst versions. GetNode Given an index, return a pointer to the node at that index. Throws an exception if the index is out of range. Const and non-const versions. Head Returns the head pointer. Const and non-const versions. Tail Returns the tail pointer. Const and non-const versions. Insertion Operations AddHead Create a new Node at the front of the list to store the passed in parameter. AddTail Create a new Node at the end of the list to store the passed in parameter. AddNodesHead Given an array of values, insert a node for each of those at the beginning of the list, maintaining the original order. AddNodesTail Ditto, except adding to the end of the list. InsertAfter Given a pointer to a node, create a new node to store the passed in value, after the indicated node. InsertBefore Ditto, except insert the new node before the indicated node. InsertAt Inserts a new Node to store the first parameter, at the index-th location. So if you specified 4 as the index, the new Node should have 3 Nodes before it. Throws an exception if given an invalid index. Removal Operations RemoveHead Deletes the first Node in the list. Returns whether or not the operation was successful. RemoveTail Deletes the last Node, returning whether or not the operation was successful. Remove Remove ALL Nodes containing values matching that of the passed-in parameter. Returns how many instances were removed. RemoveAt Deletes the index-th Node from the list, returning whether or not the operation was successful. Clear Deletes all Nodes. Don’t forget the node count! Operators operator Overloaded brackets operator. Takes an index, and returns the index-th node. Throws an exception if given an invalid index. Const and non-const versions. operator= After listA = listB, listA == listB is true. operator== Overloaded equality operator. Given listA and listB, is listA equal to listB? What would make one Linked List equal to another? If each of its nodes were equal to the corresponding node of the other. (Similar to comparing two arrays, just with non-contiguous data). Construction / Destruction LinkedList() Default constructor. A head, a tail, and a node counter walk into a bar… and get initialized? Wait, that’s not how that one goes… How many nodes in an empty list? What is head pointing to? What is tail pointing to? Copy Constructor Sets “this” to a copy of the passed in LinkedList. Other list has 10 nodes, with values of 1-10? “this” should too. ~LinkedList() The usual. Clean up your mess. (Delete all the nodes created by the list.)  
Tips
A few tips for this assignment: Remember the "Big Three" or the “Rule of Three” o If you define one of the three special functions (copy constructor, assignment operator, or destructor), you should define the other two Start small, work one bit of functionality at a time. Work on things like Add() and PrintForward() first, as well as accessors (brackets operator, Head()/Tail(), etc). You can’t really test anything else unless those are working. Refer back to the recommended chapters in your textbook as well as lecture videos for an explanation of the details of dynamic memory allocation o There are a lot of things to remember when memory allocation The debugger is your friend! (You have learned how to use it, right?) Make charts, diagrams, sketches of the problem. Memory is inherently difficult to visualize, find a way that works for you. Don’t forget your node count! Read the full article
0 notes
felord · 6 years ago
Text
cop3503 Project 1 – Templated Linked List Solved
Overview
The purpose of this assignment is for you to write a data structure called a Linked List, which utilizes templates (similar to Java’s generics), in order to store any type of data. In addition, the nature of a Linked List will give you some experience dealing with non-contiguous memory organization. This will also give you more experience using pointers and memory management. Pointers, memory allocation, and understand how data is stored in memory will serve you well in a variety of situations, not just for an assignment like this.
Background
Remember Memory? Variables, functions, pointers—everything takes up SOME space in memory. Sometimes that memory is occupied for only a short duration (a temporary variable in a function), sometimes that memory is allocated at the start of a program and hangs around for the lifetime of that program. Visualizing memory can be difficult sometimes, but very helpful. You may see diagrams of memory like this:
Tumblr media
Or, you may see diagrams like these:
Tumblr media
If you are trying to draw out some representation of memory to help you solve a problem, any of these (or some alternative that makes sense to you) will be fine.
Arrays
Arrays are stored in what is called contiguous memory. A contiguous memory block is one that is not interrupted by anything else (i.e. any other memory block). So if you created an array of 5 integers, each of those integers would be located one after the other in memory, with nothing else occupying memory between them. This is true for all arrays, of any data type.  
Tumblr media
All of the data in an application is not guaranteed to be contiguous, nor does it need to be. Arrays are typically the simplest and fastest way to store data, but they have a grand total of zero features. You allocate one contiguous block, but you can’t resize it, removing elements is a pain (and slow), etc. Consider the previous array. What if you wanted to add another element to that block of memory? If the surrounding memory is occupied, you can’t simply overwrite that with your new data element and expect good results.  
Tumblr media
someArray = 12; // #badIdea                This will almost certainly break. Other Memory   In this scenario, in order to store one more element you would have to: Create another array that was large enough to store all of the old elements plus the new one Copy over all of the data elements one at a time (including the new element, at the end) Free up the old array—no point in having two copies of the data  
Tumblr media
Other Memory Newly available memory Someone else’s memory 10 12 This process has to be repeated each time you want to add to the array (either at the end, or insert in the middle), or remove anything from the array. It can quite costly, in terms of performance, to delete/rebuild an entire array every time you want to make a single change. Cue the Linked List!
Linked List
The basic concept behind a Linked List is simple: It’s a container that stores its elements in a non-contiguous fashion Each element knows about the location of the element which comes after it (and possibly before, more on that later) So instead of a contiguous array, where element 4 comes after element 3, which comes after element 2, etc… you might have something like this:
Tumblr media
Each element in the Linked List (typically referred to as a “node”) stores some data, and then stores a reference (a pointer, in C++), so the node which should come next. The First node knows only about the Second node. The Second node knows only about the Third, etc. The Fourth node has a null pointer as its “next” node, indicating that we’ve reached the end of the data. A real-world example can be helpful as well. Think about a line of people, with one person at the front of the line. That person might know about the person who is next in line, but no further than that (beyond him or herself, the person at the front doesn’t need to know or care). The second person in line might know about the third person in line, but no further. Continuing on this way, the last person in line knows that there is no one else that follows, so that must be the end. Since no one is behind that person, we must be at the end of the line.  
Tumblr media
So… What are the advantages of storing data like this? When inserting elements to an array, the entire array has to be reallocated. With a Linked List, only a small number of elements are affected. Only elements surrounding the changed element need to be updated, and all other elements can remain unaffected. This makes the Linked List much more efficient when it comes to adding or removing elements. Now, imagine one person wants to step out of line. If this were an array, all of the data would have to be reconstructed elsewhere. In a Linked List, only three nodes are affected: 1) The person leaving, 2) the person in front of that person, and 3) the person behind that person. Imagine you are the person at the front of the line. You don’t really need to know or care what happens 10 people behind you, as that has no impact on you whatsoever.
Tumblr media
If the 5th person in line leaves, the only parts of the line that should be impacted are the 4th, 5th, and 6th spaces. Person 4 has a new “next” Person: whomever was behind the person behind them (Person 6). Person 5 has to be removed from the list. Person 6… actually does nothing. In this example, a Person only cares about whomever comes after them. Since Person 5 was before Person 6, Person 6 is unaffected. (A Linked List could be implemented with two-way information between nodes—more on that later). The same thought-process can be applied if someone stepped into line (maybe a friend was holding their place):
Tumblr media
In this case, Person 2 would change their “next” person from Person 3, to the new Person being added. New Guy would have his “next” pointer set to whomever Person 2 was previously keeping track of, Person 3. Because of the ordering process, Person 3 would remain unchanged, as would anyone else in the list (aside from being a bit irritated at the New Guy for cutting in line). So that’s the concept behind a Linked List. A series of “nodes” which are connected via pointer to one another, and inserting/deleting nodes is a faster process than deleting and reconstructing the entire collection of data. Now, how to go about creating that?
Terminology
Node The fundamental building block of a Linked List. A node contains the data actually being stored in the list, as well as 1 or more pointers to other nodes. This is typically implemented as a nested class (see below). Singly-linked A Linked List would be singly-linked if each node only has a single pointer to another node, typically a “next” pointer. This only allows for uni-directional traversal of the data—from beginning to end. Doubly-linked Each node contains 2 pointers: a “next” pointer and a “previous” pointer. This allows for bi-directional traversal of the data—either from front-to-back or backto-front. Head A pointer to the first node in the list, akin to index 0 of an array. Tail A pointer to the last node in the list. May or may not be used, depending on the implementation of the list.  
Nested Classes
The purpose of writing a class is to group data and functionality. The purpose of a nested class is the same—the only difference is where we declare a nested class. We declare a nested class like this: class MyClass { public: // Nested class    class NestedClass { int x, y, z;       NestedClass();       ~NestedClass();       int SomeFunction(); }; private: // Data for "MyClass" NestedClass myData;    NestedClass *somePtr;    float values; MyClass(); // Etc… }; // To create nested classes… // Use the Scope Resolution Operator MyClass::NestedClass someVariable;   // With a class template… TemplateClass foo; TemplateClass::Nested bar;   /* NOTE: You can make nested classes private if you wish, to prevent access to them outside of the encapsulating class. */ Additional reading: http://en.cppreference.com/w/cpp/language/nested_types The nature of the Linked List is that each piece of information knows about the information which follows (or precedes) it. It would make sense, then, to create some nested class to group all of that information together.  
Benefits and Drawbacks
All data structures in programming (C++ or otherwise) have advantages and disadvantages. There is no “one size fits all” data structure. Some are faster (in some cases), some have smaller memory footprints, and some are more flexible in their functionality, which can make life easier for the programmer. Linked List versus Array – Who Wins? Array Linked List Fast access of individual elements as well as iteration over the entire array Changing the Linked List is fast – nodes can be inserted/removed very quickly Random access – You can quickly “jump” to the appropriate memory location of an element Less affected by memory fragmentation, nodes can fit anywhere in memory Changing the array is slow – Have to rebuild the entire array when adding/removing elements No random access, slow iteration Memory fragmentation can be an issue for arrays—need a single, contiguous block large enough for all of the data Extra memory overhead for nodes/pointers Slow to access individual elements
Code Structure
As shown above, the Linked List class itself stores very little data: Pointers to the first and last nodes, and a count. In some implementations, you might only have a pointer to the first node, and that’s it. In addition to those data members, your Linked List class must conform to the following interface:                
Function Reference
Accessors PrintForward Iterator through all of the nodes and print out their values, one a time. PrintReverse Exactly the same as PrintForward, except completely the opposite. NodeCount Wait, we’re storing how many things in this list? FindAll Find all nodes which match the passed in parameter value, and store a pointer to that node in the passed in vector. Use of a parameter like this (passing a something in by reference, and storing data for later use) is called an output parameter. Find Find the first node with a data value matching the passed in parameter, returning a pointer to that node. Returns null if no matching node found. const and nonconst versions. GetNode Given an index, return a pointer to the node at that index. Throws an exception if the index is out of range. Const and non-const versions. Head Returns the head pointer. Const and non-const versions. Tail Returns the tail pointer. Const and non-const versions. Insertion Operations AddHead Create a new Node at the front of the list to store the passed in parameter. AddTail Create a new Node at the end of the list to store the passed in parameter. AddNodesHead Given an array of values, insert a node for each of those at the beginning of the list, maintaining the original order. AddNodesTail Ditto, except adding to the end of the list. InsertAfter Given a pointer to a node, create a new node to store the passed in value, after the indicated node. InsertBefore Ditto, except insert the new node before the indicated node. InsertAt Inserts a new Node to store the first parameter, at the index-th location. So if you specified 4 as the index, the new Node should have 3 Nodes before it. Throws an exception if given an invalid index. Removal Operations RemoveHead Deletes the first Node in the list. Returns whether or not the operation was successful. RemoveTail Deletes the last Node, returning whether or not the operation was successful. Remove Remove ALL Nodes containing values matching that of the passed-in parameter. Returns how many instances were removed. RemoveAt Deletes the index-th Node from the list, returning whether or not the operation was successful. Clear Deletes all Nodes. Don’t forget the node count! Operators operator Overloaded brackets operator. Takes an index, and returns the index-th node. Throws an exception if given an invalid index. Const and non-const versions. operator= After listA = listB, listA == listB is true. operator== Overloaded equality operator. Given listA and listB, is listA equal to listB? What would make one Linked List equal to another? If each of its nodes were equal to the corresponding node of the other. (Similar to comparing two arrays, just with non-contiguous data). Construction / Destruction LinkedList() Default constructor. A head, a tail, and a node counter walk into a bar… and get initialized? Wait, that’s not how that one goes… How many nodes in an empty list? What is head pointing to? What is tail pointing to? Copy Constructor Sets “this” to a copy of the passed in LinkedList. Other list has 10 nodes, with values of 1-10? “this” should too. ~LinkedList() The usual. Clean up your mess. (Delete all the nodes created by the list.)  
Tips
A few tips for this assignment: Remember the "Big Three" or the “Rule of Three” o If you define one of the three special functions (copy constructor, assignment operator, or destructor), you should define the other two Start small, work one bit of functionality at a time. Work on things like Add() and PrintForward() first, as well as accessors (brackets operator, Head()/Tail(), etc). You can’t really test anything else unless those are working. Refer back to the recommended chapters in your textbook as well as lecture videos for an explanation of the details of dynamic memory allocation o There are a lot of things to remember when memory allocation The debugger is your friend! (You have learned how to use it, right?) Make charts, diagrams, sketches of the problem. Memory is inherently difficult to visualize, find a way that works for you. Don’t forget your node count! Read the full article
0 notes
felord · 6 years ago
Text
cop3503 Project 1 – Templated Linked List Solved
Overview
The purpose of this assignment is for you to write a data structure called a Linked List, which utilizes templates (similar to Java’s generics), in order to store any type of data. In addition, the nature of a Linked List will give you some experience dealing with non-contiguous memory organization. This will also give you more experience using pointers and memory management. Pointers, memory allocation, and understand how data is stored in memory will serve you well in a variety of situations, not just for an assignment like this.
Background
Remember Memory? Variables, functions, pointers—everything takes up SOME space in memory. Sometimes that memory is occupied for only a short duration (a temporary variable in a function), sometimes that memory is allocated at the start of a program and hangs around for the lifetime of that program. Visualizing memory can be difficult sometimes, but very helpful. You may see diagrams of memory like this:
Tumblr media
Or, you may see diagrams like these:
Tumblr media
If you are trying to draw out some representation of memory to help you solve a problem, any of these (or some alternative that makes sense to you) will be fine.
Arrays
Arrays are stored in what is called contiguous memory. A contiguous memory block is one that is not interrupted by anything else (i.e. any other memory block). So if you created an array of 5 integers, each of those integers would be located one after the other in memory, with nothing else occupying memory between them. This is true for all arrays, of any data type.  
Tumblr media
All of the data in an application is not guaranteed to be contiguous, nor does it need to be. Arrays are typically the simplest and fastest way to store data, but they have a grand total of zero features. You allocate one contiguous block, but you can’t resize it, removing elements is a pain (and slow), etc. Consider the previous array. What if you wanted to add another element to that block of memory? If the surrounding memory is occupied, you can’t simply overwrite that with your new data element and expect good results.  
Tumblr media
someArray = 12; // #badIdea                This will almost certainly break. Other Memory   In this scenario, in order to store one more element you would have to: Create another array that was large enough to store all of the old elements plus the new one Copy over all of the data elements one at a time (including the new element, at the end) Free up the old array—no point in having two copies of the data  
Tumblr media
Other Memory Newly available memory Someone else’s memory 10 12 This process has to be repeated each time you want to add to the array (either at the end, or insert in the middle), or remove anything from the array. It can quite costly, in terms of performance, to delete/rebuild an entire array every time you want to make a single change. Cue the Linked List!
Linked List
The basic concept behind a Linked List is simple: It’s a container that stores its elements in a non-contiguous fashion Each element knows about the location of the element which comes after it (and possibly before, more on that later) So instead of a contiguous array, where element 4 comes after element 3, which comes after element 2, etc… you might have something like this:
Tumblr media
Each element in the Linked List (typically referred to as a “node”) stores some data, and then stores a reference (a pointer, in C++), so the node which should come next. The First node knows only about the Second node. The Second node knows only about the Third, etc. The Fourth node has a null pointer as its “next” node, indicating that we’ve reached the end of the data. A real-world example can be helpful as well. Think about a line of people, with one person at the front of the line. That person might know about the person who is next in line, but no further than that (beyond him or herself, the person at the front doesn’t need to know or care). The second person in line might know about the third person in line, but no further. Continuing on this way, the last person in line knows that there is no one else that follows, so that must be the end. Since no one is behind that person, we must be at the end of the line.  
Tumblr media
So… What are the advantages of storing data like this? When inserting elements to an array, the entire array has to be reallocated. With a Linked List, only a small number of elements are affected. Only elements surrounding the changed element need to be updated, and all other elements can remain unaffected. This makes the Linked List much more efficient when it comes to adding or removing elements. Now, imagine one person wants to step out of line. If this were an array, all of the data would have to be reconstructed elsewhere. In a Linked List, only three nodes are affected: 1) The person leaving, 2) the person in front of that person, and 3) the person behind that person. Imagine you are the person at the front of the line. You don’t really need to know or care what happens 10 people behind you, as that has no impact on you whatsoever.
Tumblr media
If the 5th person in line leaves, the only parts of the line that should be impacted are the 4th, 5th, and 6th spaces. Person 4 has a new “next” Person: whomever was behind the person behind them (Person 6). Person 5 has to be removed from the list. Person 6… actually does nothing. In this example, a Person only cares about whomever comes after them. Since Person 5 was before Person 6, Person 6 is unaffected. (A Linked List could be implemented with two-way information between nodes—more on that later). The same thought-process can be applied if someone stepped into line (maybe a friend was holding their place):
Tumblr media
In this case, Person 2 would change their “next” person from Person 3, to the new Person being added. New Guy would have his “next” pointer set to whomever Person 2 was previously keeping track of, Person 3. Because of the ordering process, Person 3 would remain unchanged, as would anyone else in the list (aside from being a bit irritated at the New Guy for cutting in line). So that’s the concept behind a Linked List. A series of “nodes” which are connected via pointer to one another, and inserting/deleting nodes is a faster process than deleting and reconstructing the entire collection of data. Now, how to go about creating that?
Terminology
Node The fundamental building block of a Linked List. A node contains the data actually being stored in the list, as well as 1 or more pointers to other nodes. This is typically implemented as a nested class (see below). Singly-linked A Linked List would be singly-linked if each node only has a single pointer to another node, typically a “next” pointer. This only allows for uni-directional traversal of the data—from beginning to end. Doubly-linked Each node contains 2 pointers: a “next” pointer and a “previous” pointer. This allows for bi-directional traversal of the data—either from front-to-back or backto-front. Head A pointer to the first node in the list, akin to index 0 of an array. Tail A pointer to the last node in the list. May or may not be used, depending on the implementation of the list.  
Nested Classes
The purpose of writing a class is to group data and functionality. The purpose of a nested class is the same—the only difference is where we declare a nested class. We declare a nested class like this: class MyClass { public: // Nested class    class NestedClass { int x, y, z;       NestedClass();       ~NestedClass();       int SomeFunction(); }; private: // Data for "MyClass" NestedClass myData;    NestedClass *somePtr;    float values; MyClass(); // Etc… }; // To create nested classes… // Use the Scope Resolution Operator MyClass::NestedClass someVariable;   // With a class template… TemplateClass foo; TemplateClass::Nested bar;   /* NOTE: You can make nested classes private if you wish, to prevent access to them outside of the encapsulating class. */ Additional reading: http://en.cppreference.com/w/cpp/language/nested_types The nature of the Linked List is that each piece of information knows about the information which follows (or precedes) it. It would make sense, then, to create some nested class to group all of that information together.  
Benefits and Drawbacks
All data structures in programming (C++ or otherwise) have advantages and disadvantages. There is no “one size fits all” data structure. Some are faster (in some cases), some have smaller memory footprints, and some are more flexible in their functionality, which can make life easier for the programmer. Linked List versus Array – Who Wins? Array Linked List Fast access of individual elements as well as iteration over the entire array Changing the Linked List is fast – nodes can be inserted/removed very quickly Random access – You can quickly “jump” to the appropriate memory location of an element Less affected by memory fragmentation, nodes can fit anywhere in memory Changing the array is slow – Have to rebuild the entire array when adding/removing elements No random access, slow iteration Memory fragmentation can be an issue for arrays—need a single, contiguous block large enough for all of the data Extra memory overhead for nodes/pointers Slow to access individual elements
Code Structure
As shown above, the Linked List class itself stores very little data: Pointers to the first and last nodes, and a count. In some implementations, you might only have a pointer to the first node, and that’s it. In addition to those data members, your Linked List class must conform to the following interface:                
Function Reference
Accessors PrintForward Iterator through all of the nodes and print out their values, one a time. PrintReverse Exactly the same as PrintForward, except completely the opposite. NodeCount Wait, we’re storing how many things in this list? FindAll Find all nodes which match the passed in parameter value, and store a pointer to that node in the passed in vector. Use of a parameter like this (passing a something in by reference, and storing data for later use) is called an output parameter. Find Find the first node with a data value matching the passed in parameter, returning a pointer to that node. Returns null if no matching node found. const and nonconst versions. GetNode Given an index, return a pointer to the node at that index. Throws an exception if the index is out of range. Const and non-const versions. Head Returns the head pointer. Const and non-const versions. Tail Returns the tail pointer. Const and non-const versions. Insertion Operations AddHead Create a new Node at the front of the list to store the passed in parameter. AddTail Create a new Node at the end of the list to store the passed in parameter. AddNodesHead Given an array of values, insert a node for each of those at the beginning of the list, maintaining the original order. AddNodesTail Ditto, except adding to the end of the list. InsertAfter Given a pointer to a node, create a new node to store the passed in value, after the indicated node. InsertBefore Ditto, except insert the new node before the indicated node. InsertAt Inserts a new Node to store the first parameter, at the index-th location. So if you specified 4 as the index, the new Node should have 3 Nodes before it. Throws an exception if given an invalid index. Removal Operations RemoveHead Deletes the first Node in the list. Returns whether or not the operation was successful. RemoveTail Deletes the last Node, returning whether or not the operation was successful. Remove Remove ALL Nodes containing values matching that of the passed-in parameter. Returns how many instances were removed. RemoveAt Deletes the index-th Node from the list, returning whether or not the operation was successful. Clear Deletes all Nodes. Don’t forget the node count! Operators operator Overloaded brackets operator. Takes an index, and returns the index-th node. Throws an exception if given an invalid index. Const and non-const versions. operator= After listA = listB, listA == listB is true. operator== Overloaded equality operator. Given listA and listB, is listA equal to listB? What would make one Linked List equal to another? If each of its nodes were equal to the corresponding node of the other. (Similar to comparing two arrays, just with non-contiguous data). Construction / Destruction LinkedList() Default constructor. A head, a tail, and a node counter walk into a bar… and get initialized? Wait, that’s not how that one goes… How many nodes in an empty list? What is head pointing to? What is tail pointing to? Copy Constructor Sets “this” to a copy of the passed in LinkedList. Other list has 10 nodes, with values of 1-10? “this” should too. ~LinkedList() The usual. Clean up your mess. (Delete all the nodes created by the list.)  
Tips
A few tips for this assignment: Remember the "Big Three" or the “Rule of Three” o If you define one of the three special functions (copy constructor, assignment operator, or destructor), you should define the other two Start small, work one bit of functionality at a time. Work on things like Add() and PrintForward() first, as well as accessors (brackets operator, Head()/Tail(), etc). You can’t really test anything else unless those are working. Refer back to the recommended chapters in your textbook as well as lecture videos for an explanation of the details of dynamic memory allocation o There are a lot of things to remember when memory allocation The debugger is your friend! (You have learned how to use it, right?) Make charts, diagrams, sketches of the problem. Memory is inherently difficult to visualize, find a way that works for you. Don’t forget your node count! Read the full article
0 notes
felord · 6 years ago
Text
cop3503 Project 1 – Templated Linked List Solved
Overview
The purpose of this assignment is for you to write a data structure called a Linked List, which utilizes templates (similar to Java’s generics), in order to store any type of data. In addition, the nature of a Linked List will give you some experience dealing with non-contiguous memory organization. This will also give you more experience using pointers and memory management. Pointers, memory allocation, and understand how data is stored in memory will serve you well in a variety of situations, not just for an assignment like this.
Background
Remember Memory? Variables, functions, pointers—everything takes up SOME space in memory. Sometimes that memory is occupied for only a short duration (a temporary variable in a function), sometimes that memory is allocated at the start of a program and hangs around for the lifetime of that program. Visualizing memory can be difficult sometimes, but very helpful. You may see diagrams of memory like this:
Tumblr media
Or, you may see diagrams like these:
Tumblr media
If you are trying to draw out some representation of memory to help you solve a problem, any of these (or some alternative that makes sense to you) will be fine.
Arrays
Arrays are stored in what is called contiguous memory. A contiguous memory block is one that is not interrupted by anything else (i.e. any other memory block). So if you created an array of 5 integers, each of those integers would be located one after the other in memory, with nothing else occupying memory between them. This is true for all arrays, of any data type.  
Tumblr media
All of the data in an application is not guaranteed to be contiguous, nor does it need to be. Arrays are typically the simplest and fastest way to store data, but they have a grand total of zero features. You allocate one contiguous block, but you can’t resize it, removing elements is a pain (and slow), etc. Consider the previous array. What if you wanted to add another element to that block of memory? If the surrounding memory is occupied, you can’t simply overwrite that with your new data element and expect good results.  
Tumblr media
someArray = 12; // #badIdea                This will almost certainly break. Other Memory   In this scenario, in order to store one more element you would have to: Create another array that was large enough to store all of the old elements plus the new one Copy over all of the data elements one at a time (including the new element, at the end) Free up the old array—no point in having two copies of the data  
Tumblr media
Other Memory Newly available memory Someone else’s memory 10 12 This process has to be repeated each time you want to add to the array (either at the end, or insert in the middle), or remove anything from the array. It can quite costly, in terms of performance, to delete/rebuild an entire array every time you want to make a single change. Cue the Linked List!
Linked List
The basic concept behind a Linked List is simple: It’s a container that stores its elements in a non-contiguous fashion Each element knows about the location of the element which comes after it (and possibly before, more on that later) So instead of a contiguous array, where element 4 comes after element 3, which comes after element 2, etc… you might have something like this:
Tumblr media
Each element in the Linked List (typically referred to as a “node”) stores some data, and then stores a reference (a pointer, in C++), so the node which should come next. The First node knows only about the Second node. The Second node knows only about the Third, etc. The Fourth node has a null pointer as its “next” node, indicating that we’ve reached the end of the data. A real-world example can be helpful as well. Think about a line of people, with one person at the front of the line. That person might know about the person who is next in line, but no further than that (beyond him or herself, the person at the front doesn’t need to know or care). The second person in line might know about the third person in line, but no further. Continuing on this way, the last person in line knows that there is no one else that follows, so that must be the end. Since no one is behind that person, we must be at the end of the line.  
Tumblr media
So… What are the advantages of storing data like this? When inserting elements to an array, the entire array has to be reallocated. With a Linked List, only a small number of elements are affected. Only elements surrounding the changed element need to be updated, and all other elements can remain unaffected. This makes the Linked List much more efficient when it comes to adding or removing elements. Now, imagine one person wants to step out of line. If this were an array, all of the data would have to be reconstructed elsewhere. In a Linked List, only three nodes are affected: 1) The person leaving, 2) the person in front of that person, and 3) the person behind that person. Imagine you are the person at the front of the line. You don’t really need to know or care what happens 10 people behind you, as that has no impact on you whatsoever.
Tumblr media
If the 5th person in line leaves, the only parts of the line that should be impacted are the 4th, 5th, and 6th spaces. Person 4 has a new “next” Person: whomever was behind the person behind them (Person 6). Person 5 has to be removed from the list. Person 6… actually does nothing. In this example, a Person only cares about whomever comes after them. Since Person 5 was before Person 6, Person 6 is unaffected. (A Linked List could be implemented with two-way information between nodes—more on that later). The same thought-process can be applied if someone stepped into line (maybe a friend was holding their place):
Tumblr media
In this case, Person 2 would change their “next” person from Person 3, to the new Person being added. New Guy would have his “next” pointer set to whomever Person 2 was previously keeping track of, Person 3. Because of the ordering process, Person 3 would remain unchanged, as would anyone else in the list (aside from being a bit irritated at the New Guy for cutting in line). So that’s the concept behind a Linked List. A series of “nodes” which are connected via pointer to one another, and inserting/deleting nodes is a faster process than deleting and reconstructing the entire collection of data. Now, how to go about creating that?
Terminology
Node The fundamental building block of a Linked List. A node contains the data actually being stored in the list, as well as 1 or more pointers to other nodes. This is typically implemented as a nested class (see below). Singly-linked A Linked List would be singly-linked if each node only has a single pointer to another node, typically a “next” pointer. This only allows for uni-directional traversal of the data—from beginning to end. Doubly-linked Each node contains 2 pointers: a “next” pointer and a “previous” pointer. This allows for bi-directional traversal of the data—either from front-to-back or backto-front. Head A pointer to the first node in the list, akin to index 0 of an array. Tail A pointer to the last node in the list. May or may not be used, depending on the implementation of the list.  
Nested Classes
The purpose of writing a class is to group data and functionality. The purpose of a nested class is the same—the only difference is where we declare a nested class. We declare a nested class like this: class MyClass { public: // Nested class    class NestedClass { int x, y, z;       NestedClass();       ~NestedClass();       int SomeFunction(); }; private: // Data for "MyClass" NestedClass myData;    NestedClass *somePtr;    float values; MyClass(); // Etc… }; // To create nested classes… // Use the Scope Resolution Operator MyClass::NestedClass someVariable;   // With a class template… TemplateClass foo; TemplateClass::Nested bar;   /* NOTE: You can make nested classes private if you wish, to prevent access to them outside of the encapsulating class. */ Additional reading: http://en.cppreference.com/w/cpp/language/nested_types The nature of the Linked List is that each piece of information knows about the information which follows (or precedes) it. It would make sense, then, to create some nested class to group all of that information together.  
Benefits and Drawbacks
All data structures in programming (C++ or otherwise) have advantages and disadvantages. There is no “one size fits all” data structure. Some are faster (in some cases), some have smaller memory footprints, and some are more flexible in their functionality, which can make life easier for the programmer. Linked List versus Array – Who Wins? Array Linked List Fast access of individual elements as well as iteration over the entire array Changing the Linked List is fast – nodes can be inserted/removed very quickly Random access – You can quickly “jump” to the appropriate memory location of an element Less affected by memory fragmentation, nodes can fit anywhere in memory Changing the array is slow – Have to rebuild the entire array when adding/removing elements No random access, slow iteration Memory fragmentation can be an issue for arrays—need a single, contiguous block large enough for all of the data Extra memory overhead for nodes/pointers Slow to access individual elements
Code Structure
As shown above, the Linked List class itself stores very little data: Pointers to the first and last nodes, and a count. In some implementations, you might only have a pointer to the first node, and that’s it. In addition to those data members, your Linked List class must conform to the following interface:                
Function Reference
Accessors PrintForward Iterator through all of the nodes and print out their values, one a time. PrintReverse Exactly the same as PrintForward, except completely the opposite. NodeCount Wait, we’re storing how many things in this list? FindAll Find all nodes which match the passed in parameter value, and store a pointer to that node in the passed in vector. Use of a parameter like this (passing a something in by reference, and storing data for later use) is called an output parameter. Find Find the first node with a data value matching the passed in parameter, returning a pointer to that node. Returns null if no matching node found. const and nonconst versions. GetNode Given an index, return a pointer to the node at that index. Throws an exception if the index is out of range. Const and non-const versions. Head Returns the head pointer. Const and non-const versions. Tail Returns the tail pointer. Const and non-const versions. Insertion Operations AddHead Create a new Node at the front of the list to store the passed in parameter. AddTail Create a new Node at the end of the list to store the passed in parameter. AddNodesHead Given an array of values, insert a node for each of those at the beginning of the list, maintaining the original order. AddNodesTail Ditto, except adding to the end of the list. InsertAfter Given a pointer to a node, create a new node to store the passed in value, after the indicated node. InsertBefore Ditto, except insert the new node before the indicated node. InsertAt Inserts a new Node to store the first parameter, at the index-th location. So if you specified 4 as the index, the new Node should have 3 Nodes before it. Throws an exception if given an invalid index. Removal Operations RemoveHead Deletes the first Node in the list. Returns whether or not the operation was successful. RemoveTail Deletes the last Node, returning whether or not the operation was successful. Remove Remove ALL Nodes containing values matching that of the passed-in parameter. Returns how many instances were removed. RemoveAt Deletes the index-th Node from the list, returning whether or not the operation was successful. Clear Deletes all Nodes. Don’t forget the node count! Operators operator Overloaded brackets operator. Takes an index, and returns the index-th node. Throws an exception if given an invalid index. Const and non-const versions. operator= After listA = listB, listA == listB is true. operator== Overloaded equality operator. Given listA and listB, is listA equal to listB? What would make one Linked List equal to another? If each of its nodes were equal to the corresponding node of the other. (Similar to comparing two arrays, just with non-contiguous data). Construction / Destruction LinkedList() Default constructor. A head, a tail, and a node counter walk into a bar… and get initialized? Wait, that’s not how that one goes… How many nodes in an empty list? What is head pointing to? What is tail pointing to? Copy Constructor Sets “this” to a copy of the passed in LinkedList. Other list has 10 nodes, with values of 1-10? “this” should too. ~LinkedList() The usual. Clean up your mess. (Delete all the nodes created by the list.)  
Tips
A few tips for this assignment: Remember the "Big Three" or the “Rule of Three” o If you define one of the three special functions (copy constructor, assignment operator, or destructor), you should define the other two Start small, work one bit of functionality at a time. Work on things like Add() and PrintForward() first, as well as accessors (brackets operator, Head()/Tail(), etc). You can’t really test anything else unless those are working. Refer back to the recommended chapters in your textbook as well as lecture videos for an explanation of the details of dynamic memory allocation o There are a lot of things to remember when memory allocation The debugger is your friend! (You have learned how to use it, right?) Make charts, diagrams, sketches of the problem. Memory is inherently difficult to visualize, find a way that works for you. Don’t forget your node count! Read the full article
0 notes
felord · 6 years ago
Text
cop3503 Project 1 – Templated Linked List Solved
Overview
The purpose of this assignment is for you to write a data structure called a Linked List, which utilizes templates (similar to Java’s generics), in order to store any type of data. In addition, the nature of a Linked List will give you some experience dealing with non-contiguous memory organization. This will also give you more experience using pointers and memory management. Pointers, memory allocation, and understand how data is stored in memory will serve you well in a variety of situations, not just for an assignment like this.
Background
Remember Memory? Variables, functions, pointers—everything takes up SOME space in memory. Sometimes that memory is occupied for only a short duration (a temporary variable in a function), sometimes that memory is allocated at the start of a program and hangs around for the lifetime of that program. Visualizing memory can be difficult sometimes, but very helpful. You may see diagrams of memory like this:
Tumblr media
Or, you may see diagrams like these:
Tumblr media
If you are trying to draw out some representation of memory to help you solve a problem, any of these (or some alternative that makes sense to you) will be fine.
Arrays
Arrays are stored in what is called contiguous memory. A contiguous memory block is one that is not interrupted by anything else (i.e. any other memory block). So if you created an array of 5 integers, each of those integers would be located one after the other in memory, with nothing else occupying memory between them. This is true for all arrays, of any data type.  
Tumblr media
All of the data in an application is not guaranteed to be contiguous, nor does it need to be. Arrays are typically the simplest and fastest way to store data, but they have a grand total of zero features. You allocate one contiguous block, but you can’t resize it, removing elements is a pain (and slow), etc. Consider the previous array. What if you wanted to add another element to that block of memory? If the surrounding memory is occupied, you can’t simply overwrite that with your new data element and expect good results.  
Tumblr media
someArray = 12; // #badIdea                This will almost certainly break. Other Memory   In this scenario, in order to store one more element you would have to: Create another array that was large enough to store all of the old elements plus the new one Copy over all of the data elements one at a time (including the new element, at the end) Free up the old array—no point in having two copies of the data  
Tumblr media
Other Memory Newly available memory Someone else’s memory 10 12 This process has to be repeated each time you want to add to the array (either at the end, or insert in the middle), or remove anything from the array. It can quite costly, in terms of performance, to delete/rebuild an entire array every time you want to make a single change. Cue the Linked List!
Linked List
The basic concept behind a Linked List is simple: It’s a container that stores its elements in a non-contiguous fashion Each element knows about the location of the element which comes after it (and possibly before, more on that later) So instead of a contiguous array, where element 4 comes after element 3, which comes after element 2, etc… you might have something like this:
Tumblr media
Each element in the Linked List (typically referred to as a “node”) stores some data, and then stores a reference (a pointer, in C++), so the node which should come next. The First node knows only about the Second node. The Second node knows only about the Third, etc. The Fourth node has a null pointer as its “next” node, indicating that we’ve reached the end of the data. A real-world example can be helpful as well. Think about a line of people, with one person at the front of the line. That person might know about the person who is next in line, but no further than that (beyond him or herself, the person at the front doesn’t need to know or care). The second person in line might know about the third person in line, but no further. Continuing on this way, the last person in line knows that there is no one else that follows, so that must be the end. Since no one is behind that person, we must be at the end of the line.  
Tumblr media
So… What are the advantages of storing data like this? When inserting elements to an array, the entire array has to be reallocated. With a Linked List, only a small number of elements are affected. Only elements surrounding the changed element need to be updated, and all other elements can remain unaffected. This makes the Linked List much more efficient when it comes to adding or removing elements. Now, imagine one person wants to step out of line. If this were an array, all of the data would have to be reconstructed elsewhere. In a Linked List, only three nodes are affected: 1) The person leaving, 2) the person in front of that person, and 3) the person behind that person. Imagine you are the person at the front of the line. You don’t really need to know or care what happens 10 people behind you, as that has no impact on you whatsoever.
Tumblr media
If the 5th person in line leaves, the only parts of the line that should be impacted are the 4th, 5th, and 6th spaces. Person 4 has a new “next” Person: whomever was behind the person behind them (Person 6). Person 5 has to be removed from the list. Person 6… actually does nothing. In this example, a Person only cares about whomever comes after them. Since Person 5 was before Person 6, Person 6 is unaffected. (A Linked List could be implemented with two-way information between nodes—more on that later). The same thought-process can be applied if someone stepped into line (maybe a friend was holding their place):
Tumblr media
In this case, Person 2 would change their “next” person from Person 3, to the new Person being added. New Guy would have his “next” pointer set to whomever Person 2 was previously keeping track of, Person 3. Because of the ordering process, Person 3 would remain unchanged, as would anyone else in the list (aside from being a bit irritated at the New Guy for cutting in line). So that’s the concept behind a Linked List. A series of “nodes” which are connected via pointer to one another, and inserting/deleting nodes is a faster process than deleting and reconstructing the entire collection of data. Now, how to go about creating that?
Terminology
Node The fundamental building block of a Linked List. A node contains the data actually being stored in the list, as well as 1 or more pointers to other nodes. This is typically implemented as a nested class (see below). Singly-linked A Linked List would be singly-linked if each node only has a single pointer to another node, typically a “next” pointer. This only allows for uni-directional traversal of the data—from beginning to end. Doubly-linked Each node contains 2 pointers: a “next” pointer and a “previous” pointer. This allows for bi-directional traversal of the data—either from front-to-back or backto-front. Head A pointer to the first node in the list, akin to index 0 of an array. Tail A pointer to the last node in the list. May or may not be used, depending on the implementation of the list.  
Nested Classes
The purpose of writing a class is to group data and functionality. The purpose of a nested class is the same—the only difference is where we declare a nested class. We declare a nested class like this: class MyClass { public: // Nested class    class NestedClass { int x, y, z;       NestedClass();       ~NestedClass();       int SomeFunction(); }; private: // Data for "MyClass" NestedClass myData;    NestedClass *somePtr;    float values; MyClass(); // Etc… }; // To create nested classes… // Use the Scope Resolution Operator MyClass::NestedClass someVariable;   // With a class template… TemplateClass foo; TemplateClass::Nested bar;   /* NOTE: You can make nested classes private if you wish, to prevent access to them outside of the encapsulating class. */ Additional reading: http://en.cppreference.com/w/cpp/language/nested_types The nature of the Linked List is that each piece of information knows about the information which follows (or precedes) it. It would make sense, then, to create some nested class to group all of that information together.  
Benefits and Drawbacks
All data structures in programming (C++ or otherwise) have advantages and disadvantages. There is no “one size fits all” data structure. Some are faster (in some cases), some have smaller memory footprints, and some are more flexible in their functionality, which can make life easier for the programmer. Linked List versus Array – Who Wins? Array Linked List Fast access of individual elements as well as iteration over the entire array Changing the Linked List is fast – nodes can be inserted/removed very quickly Random access – You can quickly “jump” to the appropriate memory location of an element Less affected by memory fragmentation, nodes can fit anywhere in memory Changing the array is slow – Have to rebuild the entire array when adding/removing elements No random access, slow iteration Memory fragmentation can be an issue for arrays—need a single, contiguous block large enough for all of the data Extra memory overhead for nodes/pointers Slow to access individual elements
Code Structure
As shown above, the Linked List class itself stores very little data: Pointers to the first and last nodes, and a count. In some implementations, you might only have a pointer to the first node, and that’s it. In addition to those data members, your Linked List class must conform to the following interface:                
Function Reference
Accessors PrintForward Iterator through all of the nodes and print out their values, one a time. PrintReverse Exactly the same as PrintForward, except completely the opposite. NodeCount Wait, we’re storing how many things in this list? FindAll Find all nodes which match the passed in parameter value, and store a pointer to that node in the passed in vector. Use of a parameter like this (passing a something in by reference, and storing data for later use) is called an output parameter. Find Find the first node with a data value matching the passed in parameter, returning a pointer to that node. Returns null if no matching node found. const and nonconst versions. GetNode Given an index, return a pointer to the node at that index. Throws an exception if the index is out of range. Const and non-const versions. Head Returns the head pointer. Const and non-const versions. Tail Returns the tail pointer. Const and non-const versions. Insertion Operations AddHead Create a new Node at the front of the list to store the passed in parameter. AddTail Create a new Node at the end of the list to store the passed in parameter. AddNodesHead Given an array of values, insert a node for each of those at the beginning of the list, maintaining the original order. AddNodesTail Ditto, except adding to the end of the list. InsertAfter Given a pointer to a node, create a new node to store the passed in value, after the indicated node. InsertBefore Ditto, except insert the new node before the indicated node. InsertAt Inserts a new Node to store the first parameter, at the index-th location. So if you specified 4 as the index, the new Node should have 3 Nodes before it. Throws an exception if given an invalid index. Removal Operations RemoveHead Deletes the first Node in the list. Returns whether or not the operation was successful. RemoveTail Deletes the last Node, returning whether or not the operation was successful. Remove Remove ALL Nodes containing values matching that of the passed-in parameter. Returns how many instances were removed. RemoveAt Deletes the index-th Node from the list, returning whether or not the operation was successful. Clear Deletes all Nodes. Don’t forget the node count! Operators operator Overloaded brackets operator. Takes an index, and returns the index-th node. Throws an exception if given an invalid index. Const and non-const versions. operator= After listA = listB, listA == listB is true. operator== Overloaded equality operator. Given listA and listB, is listA equal to listB? What would make one Linked List equal to another? If each of its nodes were equal to the corresponding node of the other. (Similar to comparing two arrays, just with non-contiguous data). Construction / Destruction LinkedList() Default constructor. A head, a tail, and a node counter walk into a bar… and get initialized? Wait, that’s not how that one goes… How many nodes in an empty list? What is head pointing to? What is tail pointing to? Copy Constructor Sets “this” to a copy of the passed in LinkedList. Other list has 10 nodes, with values of 1-10? “this” should too. ~LinkedList() The usual. Clean up your mess. (Delete all the nodes created by the list.)  
Tips
A few tips for this assignment: Remember the "Big Three" or the “Rule of Three” o If you define one of the three special functions (copy constructor, assignment operator, or destructor), you should define the other two Start small, work one bit of functionality at a time. Work on things like Add() and PrintForward() first, as well as accessors (brackets operator, Head()/Tail(), etc). You can’t really test anything else unless those are working. Refer back to the recommended chapters in your textbook as well as lecture videos for an explanation of the details of dynamic memory allocation o There are a lot of things to remember when memory allocation The debugger is your friend! (You have learned how to use it, right?) Make charts, diagrams, sketches of the problem. Memory is inherently difficult to visualize, find a way that works for you. Don’t forget your node count! Read the full article
0 notes
felord · 6 years ago
Text
cop3503 Project 1 – Templated Linked List Solved
Overview
The purpose of this assignment is for you to write a data structure called a Linked List, which utilizes templates (similar to Java’s generics), in order to store any type of data. In addition, the nature of a Linked List will give you some experience dealing with non-contiguous memory organization. This will also give you more experience using pointers and memory management. Pointers, memory allocation, and understand how data is stored in memory will serve you well in a variety of situations, not just for an assignment like this.
Background
Remember Memory? Variables, functions, pointers—everything takes up SOME space in memory. Sometimes that memory is occupied for only a short duration (a temporary variable in a function), sometimes that memory is allocated at the start of a program and hangs around for the lifetime of that program. Visualizing memory can be difficult sometimes, but very helpful. You may see diagrams of memory like this:
Tumblr media
Or, you may see diagrams like these:
Tumblr media
If you are trying to draw out some representation of memory to help you solve a problem, any of these (or some alternative that makes sense to you) will be fine.
Arrays
Arrays are stored in what is called contiguous memory. A contiguous memory block is one that is not interrupted by anything else (i.e. any other memory block). So if you created an array of 5 integers, each of those integers would be located one after the other in memory, with nothing else occupying memory between them. This is true for all arrays, of any data type.  
Tumblr media
All of the data in an application is not guaranteed to be contiguous, nor does it need to be. Arrays are typically the simplest and fastest way to store data, but they have a grand total of zero features. You allocate one contiguous block, but you can’t resize it, removing elements is a pain (and slow), etc. Consider the previous array. What if you wanted to add another element to that block of memory? If the surrounding memory is occupied, you can’t simply overwrite that with your new data element and expect good results.  
Tumblr media
someArray = 12; // #badIdea                This will almost certainly break. Other Memory   In this scenario, in order to store one more element you would have to: Create another array that was large enough to store all of the old elements plus the new one Copy over all of the data elements one at a time (including the new element, at the end) Free up the old array—no point in having two copies of the data  
Tumblr media
Other Memory Newly available memory Someone else’s memory 10 12 This process has to be repeated each time you want to add to the array (either at the end, or insert in the middle), or remove anything from the array. It can quite costly, in terms of performance, to delete/rebuild an entire array every time you want to make a single change. Cue the Linked List!
Linked List
The basic concept behind a Linked List is simple: It’s a container that stores its elements in a non-contiguous fashion Each element knows about the location of the element which comes after it (and possibly before, more on that later) So instead of a contiguous array, where element 4 comes after element 3, which comes after element 2, etc… you might have something like this:
Tumblr media
Each element in the Linked List (typically referred to as a “node”) stores some data, and then stores a reference (a pointer, in C++), so the node which should come next. The First node knows only about the Second node. The Second node knows only about the Third, etc. The Fourth node has a null pointer as its “next” node, indicating that we’ve reached the end of the data. A real-world example can be helpful as well. Think about a line of people, with one person at the front of the line. That person might know about the person who is next in line, but no further than that (beyond him or herself, the person at the front doesn’t need to know or care). The second person in line might know about the third person in line, but no further. Continuing on this way, the last person in line knows that there is no one else that follows, so that must be the end. Since no one is behind that person, we must be at the end of the line.  
Tumblr media
So… What are the advantages of storing data like this? When inserting elements to an array, the entire array has to be reallocated. With a Linked List, only a small number of elements are affected. Only elements surrounding the changed element need to be updated, and all other elements can remain unaffected. This makes the Linked List much more efficient when it comes to adding or removing elements. Now, imagine one person wants to step out of line. If this were an array, all of the data would have to be reconstructed elsewhere. In a Linked List, only three nodes are affected: 1) The person leaving, 2) the person in front of that person, and 3) the person behind that person. Imagine you are the person at the front of the line. You don’t really need to know or care what happens 10 people behind you, as that has no impact on you whatsoever.
Tumblr media
If the 5th person in line leaves, the only parts of the line that should be impacted are the 4th, 5th, and 6th spaces. Person 4 has a new “next” Person: whomever was behind the person behind them (Person 6). Person 5 has to be removed from the list. Person 6… actually does nothing. In this example, a Person only cares about whomever comes after them. Since Person 5 was before Person 6, Person 6 is unaffected. (A Linked List could be implemented with two-way information between nodes—more on that later). The same thought-process can be applied if someone stepped into line (maybe a friend was holding their place):
Tumblr media
In this case, Person 2 would change their “next” person from Person 3, to the new Person being added. New Guy would have his “next” pointer set to whomever Person 2 was previously keeping track of, Person 3. Because of the ordering process, Person 3 would remain unchanged, as would anyone else in the list (aside from being a bit irritated at the New Guy for cutting in line). So that’s the concept behind a Linked List. A series of “nodes” which are connected via pointer to one another, and inserting/deleting nodes is a faster process than deleting and reconstructing the entire collection of data. Now, how to go about creating that?
Terminology
Node The fundamental building block of a Linked List. A node contains the data actually being stored in the list, as well as 1 or more pointers to other nodes. This is typically implemented as a nested class (see below). Singly-linked A Linked List would be singly-linked if each node only has a single pointer to another node, typically a “next” pointer. This only allows for uni-directional traversal of the data—from beginning to end. Doubly-linked Each node contains 2 pointers: a “next” pointer and a “previous” pointer. This allows for bi-directional traversal of the data—either from front-to-back or backto-front. Head A pointer to the first node in the list, akin to index 0 of an array. Tail A pointer to the last node in the list. May or may not be used, depending on the implementation of the list.  
Nested Classes
The purpose of writing a class is to group data and functionality. The purpose of a nested class is the same—the only difference is where we declare a nested class. We declare a nested class like this: class MyClass { public: // Nested class    class NestedClass { int x, y, z;       NestedClass();       ~NestedClass();       int SomeFunction(); }; private: // Data for "MyClass" NestedClass myData;    NestedClass *somePtr;    float values; MyClass(); // Etc… }; // To create nested classes… // Use the Scope Resolution Operator MyClass::NestedClass someVariable;   // With a class template… TemplateClass foo; TemplateClass::Nested bar;   /* NOTE: You can make nested classes private if you wish, to prevent access to them outside of the encapsulating class. */ Additional reading: http://en.cppreference.com/w/cpp/language/nested_types The nature of the Linked List is that each piece of information knows about the information which follows (or precedes) it. It would make sense, then, to create some nested class to group all of that information together.  
Benefits and Drawbacks
All data structures in programming (C++ or otherwise) have advantages and disadvantages. There is no “one size fits all” data structure. Some are faster (in some cases), some have smaller memory footprints, and some are more flexible in their functionality, which can make life easier for the programmer. Linked List versus Array – Who Wins? Array Linked List Fast access of individual elements as well as iteration over the entire array Changing the Linked List is fast – nodes can be inserted/removed very quickly Random access – You can quickly “jump” to the appropriate memory location of an element Less affected by memory fragmentation, nodes can fit anywhere in memory Changing the array is slow – Have to rebuild the entire array when adding/removing elements No random access, slow iteration Memory fragmentation can be an issue for arrays—need a single, contiguous block large enough for all of the data Extra memory overhead for nodes/pointers Slow to access individual elements
Code Structure
As shown above, the Linked List class itself stores very little data: Pointers to the first and last nodes, and a count. In some implementations, you might only have a pointer to the first node, and that’s it. In addition to those data members, your Linked List class must conform to the following interface:                
Function Reference
Accessors PrintForward Iterator through all of the nodes and print out their values, one a time. PrintReverse Exactly the same as PrintForward, except completely the opposite. NodeCount Wait, we’re storing how many things in this list? FindAll Find all nodes which match the passed in parameter value, and store a pointer to that node in the passed in vector. Use of a parameter like this (passing a something in by reference, and storing data for later use) is called an output parameter. Find Find the first node with a data value matching the passed in parameter, returning a pointer to that node. Returns null if no matching node found. const and nonconst versions. GetNode Given an index, return a pointer to the node at that index. Throws an exception if the index is out of range. Const and non-const versions. Head Returns the head pointer. Const and non-const versions. Tail Returns the tail pointer. Const and non-const versions. Insertion Operations AddHead Create a new Node at the front of the list to store the passed in parameter. AddTail Create a new Node at the end of the list to store the passed in parameter. AddNodesHead Given an array of values, insert a node for each of those at the beginning of the list, maintaining the original order. AddNodesTail Ditto, except adding to the end of the list. InsertAfter Given a pointer to a node, create a new node to store the passed in value, after the indicated node. InsertBefore Ditto, except insert the new node before the indicated node. InsertAt Inserts a new Node to store the first parameter, at the index-th location. So if you specified 4 as the index, the new Node should have 3 Nodes before it. Throws an exception if given an invalid index. Removal Operations RemoveHead Deletes the first Node in the list. Returns whether or not the operation was successful. RemoveTail Deletes the last Node, returning whether or not the operation was successful. Remove Remove ALL Nodes containing values matching that of the passed-in parameter. Returns how many instances were removed. RemoveAt Deletes the index-th Node from the list, returning whether or not the operation was successful. Clear Deletes all Nodes. Don’t forget the node count! Operators operator Overloaded brackets operator. Takes an index, and returns the index-th node. Throws an exception if given an invalid index. Const and non-const versions. operator= After listA = listB, listA == listB is true. operator== Overloaded equality operator. Given listA and listB, is listA equal to listB? What would make one Linked List equal to another? If each of its nodes were equal to the corresponding node of the other. (Similar to comparing two arrays, just with non-contiguous data). Construction / Destruction LinkedList() Default constructor. A head, a tail, and a node counter walk into a bar… and get initialized? Wait, that’s not how that one goes… How many nodes in an empty list? What is head pointing to? What is tail pointing to? Copy Constructor Sets “this” to a copy of the passed in LinkedList. Other list has 10 nodes, with values of 1-10? “this” should too. ~LinkedList() The usual. Clean up your mess. (Delete all the nodes created by the list.)  
Tips
A few tips for this assignment: Remember the "Big Three" or the “Rule of Three” o If you define one of the three special functions (copy constructor, assignment operator, or destructor), you should define the other two Start small, work one bit of functionality at a time. Work on things like Add() and PrintForward() first, as well as accessors (brackets operator, Head()/Tail(), etc). You can’t really test anything else unless those are working. Refer back to the recommended chapters in your textbook as well as lecture videos for an explanation of the details of dynamic memory allocation o There are a lot of things to remember when memory allocation The debugger is your friend! (You have learned how to use it, right?) Make charts, diagrams, sketches of the problem. Memory is inherently difficult to visualize, find a way that works for you. Don’t forget your node count! Read the full article
0 notes