Browse Source

Remove uncited work

main
parent
commit
7b93f9e1ed
  1. 218
      notes/data-structures.org
  2. 69
      notes/efficiency-of-algorithms.org

218
notes/data-structures.org

@ -1,218 +0,0 @@
#+TITLE: Data Structures
#+AUTHOR: Christopher James Hayward
#+ROAM_KEY: https://chrishayward.xyz/notes/data-structures/
#+HUGO_BASE_DIR: ~/.local/source/website
#+HUGO_AUTO_SET_LASTMOD: t
#+HUGO_SECTION: notes
+ Built on primitive data types
+ Organization and management format
+ Forms the basis of abstract data types
* Linked List
#+begin_export
(0 ->) (1 ->) (2 ->) (3 ->) (4 ->)
#+end_export
+ Linear data structure
+ Elements linked using pointers
+ Not stored in a contiguous location
Benefits to this approach are:
+ Dynamic size
+ Ease of manipulation
Drawbacks of this approach:
+ Random access not allowed
+ Additional memory overhead
+ Not friendly to caching
** Example
Begin with the ~stc++~ header and the ~std~ namespace.
#+begin_src cpp
#include <bits/stc++.h>
using namespace std;
#+end_src
Define the data structure that will represent a single element (node) in the linked list.
#+begin_src cpp
struct Node {
int data;
struct Node* next;
Node(int d) {
this->data = d;
this->next = NULL;
}
};
#+end_src
Initialize a new linked list, with an initial value of =0=.
#+begin_example
(0 ->)
#+end_example
To illustrate our example we will create a simple linked list with three distinct nodes. The first step is creating our root node.
#+begin_src cpp
Node* head = new Node(0);
#+end_src
We can then append new items through the ~next~ field, which is a pointer to the next item in the list. When this value is ~NULL~ we have reached the end of the list.
#+begin_src cpp
head->next = new Node(1);
head->next->next = new Node(2);
#+end_src
This gives us the expected result of:
#+begin_example
(0 ->) (1 ->) (2 ->)
#+end_example
* Binary Tree
#+begin_example
a
/ \
b c
/ \ / \
d e f
#+end_example
+ Hierarchical data structure
+ Different from Arrays, Lists, Stacks & Queues
| Node | Type | Description |
|---------+------+-----------------------------------|
| a | Root | Topmost node of the tree |
| b, c | Node | Children of a, parents of d, e, f |
| d, e, f | Node | Leaves (nothing below) |
** Example
Using =C++=, we begin by including the ~stdc++~ header and the ~std~ namespace.
#+begin_src cpp
#include <bits/stc++.h>
using namespace std;
#+end_src
We then define the data structure to represent a =Node= within the tree, including a constructor method for creating new instances easily.
#+begin_src cpp
struct Node {
int data;
struct Node* left;
struct Node* right;
Node(int d) {
this->data = d;
this->left = NULL;
this->right = NULL;
}
};
#+end_src
We begin by initializing the root of the tree, leaving us with something like this:
#+begin_example
1
/ \
? ?
#+end_example
Initialize it with the value of ~1~.
#+begin_src cpp
struct Node* node = new Node(1);
#+end_src
Creating children for nodes ~2~ and ~3~ will expand the tree outwards in both directions, leaving us with something like this:
#+begin_example
1
/ \
2 3
/ \ / \
? ? ?
#+end_example
This is done by adding the children to the root.
#+begin_src cpp
root->left = new Node(2);
root->right = new Node(3);
#+end_src
Expanding down the left side only.
#+begin_example
1
/ \
2 3
/ \ / \
4 ? ?
/ \
? ?
#+end_example
Adding a branch of ~4~ to ~2~ gives us the final result.
#+begin_src cpp
root->left->left = new Node(4);
#+end_src
** Inverting
#+begin_quote
Google: 90% of our engineers use the software you wrote (homebrew), but you can't invert a binary tree on a whiteboard? F*** off!
#+end_quote
It's actually not as daunting a task as you may think, given the hype around past statements like that. But what is the process of inverting a binary tree? Starting with the given input:
#+begin_example
1
/ \
2 5
/ \
3 4
#+end_example
We expect to produce an output matching:
#+begin_example
1
/ \
5 2
/ \
4 3
#+end_example
Using a recursive approach, we can operate on the tree as to produce the expected result.
#+begin_src cpp
Node* invert(Node* root) {
if (root == NULL) {
return NULL;
}
Node* left = invert(root->left);
Node* right = invert(root->right);
root->left = right;
root->right = left;
return root;
}
#+end_src

69
notes/efficiency-of-algorithms.org

@ -1,69 +0,0 @@
#+TITLE: Efficiency of Algorithms
#+AUTHOR: Christopher James Hayward
#+ROAM_KEY: https://chrishayward.xyz/notes/efficiency-of-algorithms/
#+HUGO_BASE_DIR: ~/.local/source/website
#+HUGO_AUTO_SET_LASTMOD: t
#+HUGO_SECTION: notes
+ Algorithms must be analyzed to determine resource usage
+ Efficiency is analogous to engineering productivity for a repeating process
+ Measured in complexity of time and space (resources)
* Background
Importance of efficiency with respect to time was first emphasized by *Ada Lovelace* in 1843 regarding the babbage machine:
#+begin_quote
In almost every computation a great variety of arrangements for the succession of the process is possible, and variouis considerations must influence the selections amongst them for the purpose of a calculating engine. One essential object is to chose that arrangement which shall tend to reduce to a minimum the time necessary for completing the calculation.
#+end_quote
* Analysis
The most commonly used notation to describe resource consumption (complexity) is using *Donald Knuth's* =Big O= notation.
| Notation | Name | Example |
|--------------+--------------+----------------------------------------------------------------|
| O(1) | Constant | Finding the median in a sorted list of measurements |
| O(log n) | Logarithmic | Finding an item in an sorted array with a binary search |
| O(n) | Linear | Finding an item in an unsorted array |
| O(n log n) | Linearithmic | Performing a fast sorting algorithm |
| O(n²) | Quadratic | Multiplying two n digit numbers by a simple algorithm |
| O(n²), c > 1 | Exponential | Finding the optimal solution to the traveling salesman problem |
* Measurement
Expression as a function of the size of the input ~n~, with the main measurements being:
+ Time :: How long does the algorithm take to complete?
+ Space :: How much working memory is required?
Other measurements for devices whose power needs to be factored in, such as for battery operated devices or super computers:
+ Direct power :: How much power is needed to compute the algorithm?
+ Indirect power :: How much power is needed for cooling, lighting, etc?
Less commonly used:
+ Transmission size :: How much data must be transferred for operation?
+ External space :: Space needed physically (such as on disk)
+ Response time :: Relevant in real time applications
+ Total cost :: Cost of hardware dedication
** Time
+ Uses time complexity analysis
+ Measured in CPU time usage
+ Detailed estimates needed to compare performance
+ Difficult to measure in parallel processing
** Space
Concerned with the usage of memory resources, typically the memory or storage needed to hold:
+ Code for the algorithm
+ Working space
+ Input data
+ Output data
+ Processing data
Loading…
Cancel
Save