www.tutorialspoint.com/data_struct…

Data Structures & Algorithm Basic Concepts

Data Definition

Data Definition defines a particular data with the following characteristics.

  • Atomic − Definition should define a single concept.

  • Traceable − Definition should be able to be mapped to some data elements.

  • Accurate − Definition should be unambiguous.

  • Clear and Concise − Definition should be understandable.

Data definition Defines specific data that has the following characteristics. • Atomic definitions should define individual concepts. • Traceability – Definitions should be able to map to certain data elements. • Precise definitions should be clear. • Clear and concise definitions should be easy to understand

Data Object

Data Object represents an object having a data. A data object represents an object that has data

Data Type

Data type is a way to classify various types of data such as integer, string, etc. which determines the values that can be used with the corresponding type of data, the type of operations that can be performed on the corresponding type of data. There are two data types −

  • Built-in Data Type
  • Derived Data Type

A data type is a way to classify various types of data, such as integers and strings. It identifies the values that can be used with the corresponding types of data and the types of operations that can be performed on the corresponding types of data. − There are two types of data: built-in data type derived data type

Built-in Data Type Indicates the built-in Data Type

Those data types for which a language has built-in support are known as Built-in Data types. For example, most of the languages provide the following built-in data types.

  • Integers
  • Boolean (true, false)
  • Floating (Decimal numbers)
  • Character and Strings

Those data types supported by the language are called built-in data types. For example, most languages provide the following built-in data types. • Integer •Boolean (true, false) • Floating point (decimal number) • Characters and strings

Derived Data Type Derived Data Type

Those data types which are implementation independent as they can be implemented in one or the other way are known as derived data types. These data types are normally built by the combination of primary or built-in data types and associated operations on them. For example −

  • List
  • Array
  • Stack
  • Queue

Data types that are not implementation-dependent (because they can be implemented one way or another) are called derived data types. These data types are typically a combination of primary or built-in data types and the operations associated with them. For example: − list • array • stack • queue

Basic Operations

The data in the data structures are processed by certain operations. The particular data structure chosen largely depends on the frequency of the operation that needs to be performed on the data structure.

  • Traversing
  • Searching
  • Insertion
  • Deletion
  • Sorting
  • Merging

Data in a data structure is processed by specific operations. The particular data structure you choose depends largely on the frequency of operations that need to be performed on the data structure. • Traverse • search • Insert • Delete • Sort • merge

A discontinuous Asymptotic Analysis

Big Oh Notation, Ο

The notation (N) is The formal way to express The upper bound of an algorithm’s running time. It measures The worst case time complexity or the longest amount of time an algorithm can possibly take to complete. An official method is to use two (n) to indicate the upper bound of the algorithm running time. It measures the worst-case time complexity or the longest time an algorithm might take. For example, for a function f(n)Ο (f(n)) = { g(n) : there exists c > 0 and n such that f(n) c or less.g(n) for all n > n. }

Omega Notation, Ω

The notation ω (N) is The formal way to express The lower bound of an algorithm’s running time. It measures The best case time complexity or the best amount of time an algorithm can possibly take to complete. The symbol OMEGA (n) is a formal way of representing the lower bound of the algorithm’s running time. It measures the best-case time complexity or the best amount of time that the algorithm is likely to accomplish. For example, for a function f(n)Ω (fA (n)) {org(n) : there exists c > 0 and n such that g(n) c or less.f(n) for all n > n. }

Theta Notation, Theta

The notation θ(n) is The formal way to express both The lower bound and The upper bound of an algorithm’s running time. − The symbol θ(n) is a formal way of representing the upper and lower bounds of the algorithm’s running time. The value is in −Theta (f(n)) = { g(n) if and only if g(n) = Ο (f(n)) and g(n) = Ω (f(n)) for all n > n. }

Common parabolic Notations are commonly used

Following is a list of some common annotations

Below is a list of some common asymptotic symbols

constant Ο (1)
logarithmic Ο (log n)
linear Ο (n)
n log n Ο (n log n)
quadratic Ο (n)
cubic Ο (n)
polynomial n
exponential 2

Greedy algorithms

Greedy algorithms try to find a localized optimum solution, which may eventually lead to globally optimized solutions. However, generally greedy algorithms do not provide globally optimized solutions. Counting Coins This problem is to count to a desired value by choosing the least possible coins and the greedy approach forces the algorithm to pick the largest possible coin. If we are provided coins of ₹ 1, 2, 5 and 10 and we are asked to count ₹ 18 then the greedy procedure will be −

  • 1 − Select one ₹ 10 coins, and the remaining count is 8

  • 2 − Then select one ₹ 5 coins, and the remaining count is 3

  • 3 − Then select one ₹ 2 coins, and the remaining count is 1

  • 4 − And finally, the selection of one ₹ 1 coins solves the problem

Though, it seems to be working fine, for this count we need to pick only 4 coins. But if we slightly change the problem then the same approach may not be able to produce the same optimum result. For the currency system, where we have coins of 1, 7, 10 value, counting coins for value 18 will be absolutely optimum but for count like 15, it may use more coins than necessary. For example, the greedy approach will use 10 + 1 + 1 + 1 + 1 + 1, total 6 coins. Whereas the same problem could be solved by using only 3 coins (7 + 7 + 1) Hence, we may conclude that the greedy approach picks an immediate optimized solution and may fail where global optimization is a major concern. The problem is that by selecting as few coins as possible to count to a desired value, the greedy method forces the algorithm to select the largest possible coin. If we were offered coins of 1,2,5 and 10, and we were asked to count 18, then the greedy procedure would be − •1− select a 10 coin, 8 remaining •2− select a 5 pound coin, 3 remaining •3− Select a 2 coin, and the rest 1 •4− Finally, select 1 coin to solve the problem nonetheless, It seems to be working pretty well, and for this count, we only need to pick four coins. But if we change the problem slightly, then the same approach may not produce the same optimal results. In the monetary system, we have coins of 1, 7, 10 values, and 18 is the absolute best number, but 15 is probably the number to use more coins. For example, the greedy method will use 10 + 1 + 1 + 1 + 1 + 1 + 1 for a total of six coins. The same problem can be solved by using three coins (7 + 7 + 1). Therefore, we can conclude that the greedy approach chooses a solution that optimizes immediately and may fail where global optimization is the main concern. Examples Most networking algorithms use the greedy approach. Here is a list of few of them −

  • Travelling Salesman Problem
  • Prim’s Minimal Spanning Tree Algorithm
  • Kruskal’s Minimal Spanning Tree Algorithm
  • Dijkstra’s Minimal Spanning Tree Algorithm
  • Graph – Map Coloring
  • Graph – Vertex Cover
  • Knapsack Problem
  • Job Scheduling Problem

There are lots of similar problems that uses the greedy approach to find an optimum solution. Most web algorithms use greedy methods. Here are some examples • Traveling salesman problem •Prim minimum spanning tree algorithm •Kruskal minimum spanning tree algorithm •Dijkstra minimum spanning tree algorithm • Graph – map coloring • Graph vertex overlay • Knapsack problem • Job scheduling problem Many similar problems are solved by greedy method.

Divide and Conquer

In divide and conquer approach, the problem in hand, is divided into smaller sub-problems and then each problem is solved independently. When we keep on dividing the subproblems into even smaller sub-problems, we may eventually reach a stage where no more division is possible. Those “atomic” smallest possible sub-problem (fractions) are solved. The solution of all sub-problems is finally merged in order to obtain the solution of an original problem. The divide-and-conquer method is to break the problem at hand into smaller sub-problems and tackle each problem individually. As we continue to divide sub-problems into smaller sub-problems, we may eventually reach a stage where further segmentation is impossible. The subproblems (fractions) of the smallest possible “atoms” are solved. Finally, the solution of the original problem is obtained by combining the solutions of all sub-problems. Broadly, we can understand divide-and-conquer approach in a three-step process. Divide/BreakThis step involves breaking the problem into smaller sub-problems. Sub-problems should represent a part of the original problem. This step generally takes a recursive approach to divide the problem until no sub-problem is further divisible. At this stage, sub-problems become atomic in nature but still represent some part of the actual problem. In a broad sense, we can understand divide-and-conquer in three steps. The break/break step involves breaking the problem down into smaller sub-problems. The subproblem should represent part of the original problem. This step usually uses a recursive approach to divide the problem until there are no further subproblems to divide. At this stage, the subproblem becomes atomic in nature, but still represents part of the actual problem.Conquer/SolveThis step receives a lot of smaller sub-problems to be solved. Generally, at this level, the problems are considered ‘solved’ on their own. The conquer/solve step receives many smaller sub-problems to be solved. Generally, at this level, problems are considered to “solve” themselves.Merge/Combine When the smaller sub-problems are solved, this stage recursively combines them until they formulate a solution of the original problem. This algorithmic approach works recursively and conquer & merge steps works so close that they appear as one.

Merge/Combine As smaller subproblems are solved, this stage combines them recursively until they form a solution to the original problem. This algorithmic approach works recursively, conquering and merging steps work so closely that they appear as one. Examples The following computer algorithms are based on divide-and-conquer programming approach −

  • Merge Sort
  • Quick Sort
  • Binary Search
  • Strassen’s Matrix Multiplication
  • Closest pair (points)

There are various ways available to solve any computer problem, but the mentioned are a good example of divide and conquer approach. The following computer algorithms are based on divide-and-conquer programming methods • merge sort • quicksort • binary search • Strassen matrix multiplication • Nearest pair (points) There are various ways to solve any computer problem, but the one mentioned above is a good example of a divide-and-conquer approach.

Dynamic Programming Dynamic Programming

Dynamic programming approach is similar to divide and conquer in breaking down the problem into smaller and yet smaller possible sub-problems. But unlike, divide and conquer, these sub-problems are not solved independently. Rather, results of these smaller sub-problems are remembered and used for similar or overlapping sub-problems. Dynamic programming is used where we have problems, which can be divided into similar sub-problems, so that their results can be re-used. Mostly, these algorithms are used for optimization. Before solving the in-hand sub-problem, dynamic algorithm will try to examine the results of the previously solved sub-problems. The solutions of sub-problems are combined in order to achieve the best solution. So we can say that −

  • The problem should be able to be divided into smaller overlapping sub-problem.

  • An optimum solution can be achieved by using an optimum solution of smaller sub-problems.

  • Dynamic algorithms use Memoization.

The dynamic programming approach is similar to divide-and-conquer, breaking the problem down into smaller and smaller possible subproblems. But unlike divide-and-conquer, these subproblems are not solved independently. Instead, the results of these smaller subproblems are remembered and used for similar or overlapping subproblems. By using dynamic programming where problems exist, problems can be divided into similar sub-problems, making the results reusable. Most of these algorithms are used for optimization. Dynamic algorithms try to check the results of previously solved subproblems before solving the subproblems at hand. The optimal solution is obtained by combining the solutions of subproblems. So we can say

  • The problem should be able to be divided into smaller overlapping sub-problems.
  • The optimal solution can be obtained by using the optimal solution of the smaller problem.
  • Dynamic algorithms use memory.

Comparison In contrast to greedy algorithms, where local optimization is addressed, dynamic algorithms are motivated for an overall optimization of the problem. In contrast to divide and conquer algorithms, where solutions are combined to achieve an overall solution, dynamic algorithms use the output of a smaller sub-problem and then try to optimize a bigger sub-problem. Dynamic algorithms use Memoization to remember the output of already solved sub-problems. Unlike greedy algorithms, which focus only on local optimization, dynamic algorithms are global optimization for the problem. In contrast to “divide and conquer” algorithms, dynamic algorithms use the output of smaller problems and then try to optimize larger subproblems. Example The following computer problems can be solved using dynamic programming approach −

  • Fibonacci number series
  • Knapsack problem
  • Tower of Hanoi
  • All pair shortest path by Floyd-Warshall
  • Shortest path by Dijkstra
  • Project scheduling

Dynamic programming can be used in both top-down and bottom-up manner. And of course, most of the times, referring to the previous solution output is cheaper than recomputing in terms of CPU cycles.

The following computer problems can be solved using the dynamic programming approach −

  • Fibonacci number series
  • Knapsack problem
  • Tower of Hanoi
  • Floyd-warshall’s all-pair shortest path
  • Dijkstra’s shortest path
  • Project scheduling

Dynamic programming can be done either top-down or bottom-up. Of course, in most cases, it is cheaper to refer to the previous solution output than to recalculate CPU cycles.