Christopher James Hayward
4 years ago
1 changed files with 146 additions and 0 deletions
@ -0,0 +1,146 @@ |
|||||
|
#+TITLE: Data Structures |
||||
|
#+AUTHOR: Christopher James Hayward |
||||
|
|
||||
|
#+HUGO_BASE_DIR: ~/.local/source/website |
||||
|
#+HUGO_SECTION: notes |
||||
|
|
||||
|
+ Built on primitive data types |
||||
|
+ Organization and management format |
||||
|
+ Forms the basis of abstract data types |
||||
|
|
||||
|
* 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 |
Write
Preview
Loading…
Cancel
Save
Reference in new issue