**Algorithm** is any well-defined computational procedure that takes some value, or set of values as **input** and produces some value, or set of values, as **output**.

An algorithm is said to be **correct** if, for every input instance, it halts with the correct output. An incorrect algorithm might not halt at all on some input instances, or it might halt with an incorrect answer.

A **data structure** is a way to store and organize data in order to facilitate access and modifications. No single data structure works well for all purposes, and so it is important to know the strengths and limitations of them.

No one knows whether or not an efficient algorithm exists for **NP-complete** problems. We should be aware of NP-complete problems because some of them arise surprisingly often in real applications. If you are called upon to produce an efficient algorithm for an NP-complete problem, you are likely to spend a lot of time in a fruitless search.
NP-Problem example: travelling-salesman problem

Efficiency Table (how many operations we can perform per given time):

Complexity of Popular Algorithms Table