Skip to content

Commit ea642c3

Browse files
committed
Update DSA Notes..
1 parent 0403b3e commit ea642c3

10 files changed

Lines changed: 2659 additions & 144 deletions

.github/workflows/sync-logseq-content.yml

Lines changed: 37 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ jobs:
2121
with:
2222
ref: Admin
2323
path: logseq-source
24-
fetch-depth: 0
2524

2625
- name: Checkout Web-live branch (Quartz site)
2726
uses: actions/checkout@v4
@@ -50,64 +49,43 @@ jobs:
5049
echo "files_before=$before" >> $GITHUB_OUTPUT
5150
echo "files_after=$after" >> $GITHUB_OUTPUT
5251
53-
- name: Inject Git Timestamps into Frontmatter
52+
- name: Setup Node.js
53+
uses: actions/setup-node@v4
54+
with:
55+
node-version: 22
56+
57+
- name: Cache node_modules
58+
id: cache-node-modules
59+
uses: actions/cache@v4
60+
with:
61+
path: quartz-site/node_modules
62+
key: ${{ runner.os }}-node-modules-${{ hashFiles('quartz-site/package-lock.json') }}
63+
64+
- name: Install dependencies
65+
if: steps.cache-node-modules.outputs.cache-hit != 'true'
5466
run: |
55-
cat << 'EOF' > inject_dates.py
56-
import os
57-
import subprocess
58-
import re
59-
60-
source_dir = 'logseq-source/pages'
61-
dest_dir = 'quartz-site/content'
62-
63-
if not os.path.exists(source_dir):
64-
exit(0)
65-
66-
for filename in os.listdir(source_dir):
67-
if not filename.endswith('.md'):
68-
continue
69-
70-
dest_path = os.path.join(dest_dir, filename)
71-
if not os.path.exists(dest_path):
72-
continue
73-
74-
created_cmd = ['git', 'log', '--diff-filter=A', '--format=%aI', '-1', '--', f"pages/{filename}"]
75-
updated_cmd = ['git', 'log', '-1', '--format=%aI', '--', f"pages/{filename}"]
76-
77-
try:
78-
created = subprocess.run(created_cmd, cwd='logseq-source', capture_output=True, text=True, check=True).stdout.strip()
79-
updated = subprocess.run(updated_cmd, cwd='logseq-source', capture_output=True, text=True, check=True).stdout.strip()
80-
except subprocess.CalledProcessError:
81-
continue
82-
83-
if not created or not updated:
84-
continue
85-
86-
with open(dest_path, 'r', encoding='utf-8') as f:
87-
content = f.read()
88-
89-
inject = ""
90-
if not re.search(r'^date:\s+', content, flags=re.MULTILINE):
91-
inject += f"date: {created}\n"
92-
if not re.search(r'^lastmod:\s+', content, flags=re.MULTILINE):
93-
inject += f"lastmod: {updated}\n"
94-
95-
if inject:
96-
if content.startswith('---'):
97-
content = content.replace('---', f'---\n{inject}', 1)
98-
else:
99-
content = f'---\n{inject}---\n' + content
100-
101-
with open(dest_path, 'w', encoding='utf-8') as f:
102-
f.write(content)
103-
EOF
104-
python3 inject_dates.py
105-
106-
- name: Check for changes in content/
67+
cd quartz-site
68+
npm ci
69+
70+
- name: Cache Quartz build cache
71+
uses: actions/cache@v4
72+
with:
73+
path: quartz-site/.quartz-cache
74+
key: ${{ runner.os }}-quartz-cache-${{ github.run_id }}-${{ github.run_attempt }}
75+
restore-keys: |
76+
${{ runner.os }}-quartz-cache-
77+
78+
- name: Build Quartz site
79+
run: |
80+
cd quartz-site
81+
npx quartz build
82+
83+
- name: Check for changes in content/ and public/
10784
id: changes
10885
run: |
10986
cd quartz-site
11087
git add content/
88+
git add -f public/
11189
if git diff --staged --quiet; then
11290
echo "has_changes=false" >> $GITHUB_OUTPUT
11391
echo "No changes detected — skipping deploy."
@@ -126,18 +104,19 @@ jobs:
126104
COMMIT_SHA=$(cd ../logseq-source && git rev-parse --short HEAD)
127105
128106
git add content/
107+
git add -f public/
129108
git commit -m "sync: ${{ steps.changes.outputs.changed_count }} file(s) updated from Logseq (Admin@$COMMIT_SHA)"
130109
git push origin Web-live
131110
132111
- name: Summary
133112
run: |
134113
if [ "${{ steps.changes.outputs.has_changes }}" == "true" ]; then
135-
echo "### ✅ Sync complete" >> $GITHUB_STEP_SUMMARY
114+
echo "### ✅ Sync & Build complete" >> $GITHUB_STEP_SUMMARY
136115
echo "- **Files before:** ${{ steps.sync.outputs.files_before }}" >> $GITHUB_STEP_SUMMARY
137116
echo "- **Files after:** ${{ steps.sync.outputs.files_after }}" >> $GITHUB_STEP_SUMMARY
138-
echo "- **Changed files:** ${{ steps.changes.outputs.changed_count }}" >> $GITHUB_STEP_SUMMARY
139-
echo "- Content files pushed to **Web-live**. Vercel will build and deploy." >> $GITHUB_STEP_SUMMARY
117+
echo "- **Changed files (source & build):** ${{ steps.changes.outputs.changed_count }}" >> $GITHUB_STEP_SUMMARY
118+
echo "- Pre-built \`public/\` files pushed to **Web-live**. Vercel will deploy instantly." >> $GITHUB_STEP_SUMMARY
140119
else
141120
echo "### ⏭️ No changes" >> $GITHUB_STEP_SUMMARY
142-
echo "Content was already up to date — no commit made." >> $GITHUB_STEP_SUMMARY
121+
echo "Content and build output were already up to date — no commit made." >> $GITHUB_STEP_SUMMARY
143122
fi

pages/A Search Algorithm.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ displayTitle: A* Search Algorithm
241241
# Output: [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2), (3, 2)]
242242
```
243243
244-
```cpp
244+
```c++
245245
#include <iostream>
246246
#include <vector>
247247
#include <queue>

pages/AA Tree.md

Lines changed: 215 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ keywords: "AA tree, balanced BST, self-balancing tree, skew, split, C++, Python,
7878
- # Implementation
7979
collapsed:: true
8080
- > [!note] AA Tree Implementation
81-
> Below are complete, production-ready implementations in Python and C++ for AA Trees, including search, skew, split, insert, and delete rebalancing operations.
81+
> Below are complete implementations for AA Trees, including search, skew, split, and insert operations.
82+
> Languages: [[Python]] · [[Cpp]] · [[Java Script]] · [[Java]] · [[C]]
8283
-
8384
- :::code-tabs
8485
@@ -215,7 +216,7 @@ keywords: "AA tree, balanced BST, self-balancing tree, skew, split, C++, Python,
215216
print("Search 15 after removal:", tree.search(15)) # Output: False
216217
```
217218
218-
```cpp
219+
```c++
219220
#include <iostream>
220221
#include <vector>
221222
#include <algorithm>
@@ -365,10 +366,216 @@ keywords: "AA tree, balanced BST, self-balancing tree, skew, split, C++, Python,
365366
}
366367
```
367368
369+
```javascript
370+
class AANode {
371+
constructor(key) {
372+
this.key = key;
373+
this.level = 1;
374+
this.left = null;
375+
this.right = null;
376+
}
377+
}
378+
379+
class AATree {
380+
constructor() {
381+
this.root = null;
382+
}
383+
384+
skew(node) {
385+
if (!node || !node.left) return node;
386+
if (node.left.level === node.level) {
387+
let leftChild = node.left;
388+
node.left = leftChild.right;
389+
leftChild.right = node;
390+
return leftChild;
391+
}
392+
return node;
393+
}
394+
395+
split(node) {
396+
if (!node || !node.right || !node.right.right) return node;
397+
if (node.right.right.level === node.level) {
398+
let rightChild = node.right;
399+
node.right = rightChild.left;
400+
rightChild.left = node;
401+
rightChild.level++;
402+
return rightChild;
403+
}
404+
return node;
405+
}
406+
407+
insert(key) {
408+
this.root = this._insert(this.root, key);
409+
}
410+
411+
_insert(node, key) {
412+
if (!node) return new AANode(key);
413+
if (key < node.key) {
414+
node.left = this._insert(node.left, key);
415+
} else if (key > node.key) {
416+
node.right = this._insert(node.right, key);
417+
} else {
418+
return node;
419+
}
420+
node = this.skew(node);
421+
node = this.split(node);
422+
return node;
423+
}
424+
425+
search(key) {
426+
let curr = this.root;
427+
while (curr) {
428+
if (key === curr.key) return true;
429+
else if (key < curr.key) curr = curr.left;
430+
else curr = curr.right;
431+
}
432+
return false;
433+
}
434+
}
435+
```
436+
437+
```java
438+
class AANode {
439+
int key, level;
440+
AANode left, right;
441+
public AANode(int key) {
442+
this.key = key;
443+
this.level = 1;
444+
}
445+
}
446+
447+
public class AATree {
448+
private AANode root;
449+
450+
private AANode skew(AANode node) {
451+
if (node == null || node.left == null) return node;
452+
if (node.left.level == node.level) {
453+
AANode leftChild = node.left;
454+
node.left = leftChild.right;
455+
leftChild.right = node;
456+
return leftChild;
457+
}
458+
return node;
459+
}
460+
461+
private AANode split(AANode node) {
462+
if (node == null || node.right == null || node.right.right == null) return node;
463+
if (node.right.right.level == node.level) {
464+
AANode rightChild = node.right;
465+
node.right = rightChild.left;
466+
rightChild.left = node;
467+
rightChild.level++;
468+
return rightChild;
469+
}
470+
return node;
471+
}
472+
473+
public void insert(int key) {
474+
root = insertRec(root, key);
475+
}
476+
477+
private AANode insertRec(AANode node, int key) {
478+
if (node == null) return new AANode(key);
479+
if (key < node.key) node.left = insertRec(node.left, key);
480+
else if (key > node.key) node.right = insertRec(node.right, key);
481+
else return node;
482+
483+
node = skew(node);
484+
node = split(node);
485+
return node;
486+
}
487+
488+
public boolean search(int key) {
489+
AANode curr = root;
490+
while (curr != null) {
491+
if (key == curr.key) return true;
492+
else if (key < curr.key) curr = curr.left;
493+
else curr = curr.right;
494+
}
495+
return false;
496+
}
497+
}
498+
```
499+
500+
```c
501+
#include <stdio.h>
502+
#include <stdlib.h>
503+
504+
typedef struct AANode {
505+
int key;
506+
int level;
507+
struct AANode *left, *right;
508+
} AANode;
509+
510+
AANode* createNode(int key) {
511+
AANode* node = (AANode*)malloc(sizeof(AANode));
512+
node->key = key;
513+
node->level = 1;
514+
node->left = node->right = NULL;
515+
return node;
516+
}
517+
518+
AANode* skew(AANode* node) {
519+
if (node == NULL || node->left == NULL) return node;
520+
if (node->left->level == node->level) {
521+
AANode* leftChild = node->left;
522+
node->left = leftChild->right;
523+
leftChild->right = node;
524+
return leftChild;
525+
}
526+
return node;
527+
}
528+
529+
AANode* split(AANode* node) {
530+
if (node == NULL || node->right == NULL || node->right->right == NULL) return node;
531+
if (node->right->right->level == node->level) {
532+
AANode* rightChild = node->right;
533+
node->right = rightChild->left;
534+
rightChild->left = node;
535+
rightChild->level++;
536+
return rightChild;
537+
}
538+
return node;
539+
}
540+
541+
AANode* insert(AANode* node, int key) {
542+
if (node == NULL) return createNode(key);
543+
if (key < node->key) node->left = insert(node->left, key);
544+
else if (key > node->key) node->right = insert(node->right, key);
545+
else return node;
546+
547+
node = skew(node);
548+
node = split(node);
549+
return node;
550+
}
551+
552+
int search(AANode* root, int key) {
553+
AANode* curr = root;
554+
while (curr != NULL) {
555+
if (key == curr->key) return 1;
556+
else if (key < curr->key) curr = curr->left;
557+
else curr = curr->right;
558+
}
559+
return 0;
560+
}
561+
```
562+
368563
:::
369564
-
370565
- # When to Use
371566
collapsed:: true
567+
- ```mermaid
568+
flowchart TD
569+
Q{"Need a self-balancing\nbinary search tree?"}
570+
Q -- No --> S1{"Static data?"}
571+
S1 -- Yes --> R1["✅ Use standard BST\nor sorted array"]
572+
Q -- Yes --> S2{"Are you implementing\nit from scratch?"}
573+
S2 -- No --> R2["✅ Use standard library\nRed-Black Tree (std::map, TreeMap)"]
574+
S2 -- Yes --> S3{"Need simpler code\nthan Red-Black Tree?"}
575+
S3 -- Yes --> R3["✅ Use AA Tree"]
576+
S3 -- No --> R4["✅ Use AVL or Red-Black"]
577+
```
578+
-
372579
- ## ✅ Use AA Tree When:
373580
- You want to implement a self-balancing BST from scratch and want to avoid the complex edge-cases of Red-Black Trees.
374581
- Standard libraries aren't available, and coding simplicity is paramount.
@@ -388,4 +595,9 @@ keywords: "AA tree, balanced BST, self-balancing tree, skew, split, C++, Python,
388595
- AA Trees enforce balance via integer **levels** instead of node colors.
389596
- They eliminate left-leaning horizontal links by only allowing red links to lean right.
390597
- Two operations, **skew** (right rotate) and **split** (left rotate and level up), handle all insertion balance needs.
391-
- The worst-case height is $O(\log n)$, guaranteeing lookup, insert, and delete in $O(\log n)$ time.
598+
- The worst-case height is $O(\log n)$, guaranteeing lookup, insert, and delete in $O(\log n)$ time.
599+
-
600+
- # More Learn
601+
- ## GitHub & Webs
602+
- [TheAlgorithms – Binary Tree](https://github.com/TheAlgorithms/Python/tree/master/data_structures/binary_tree)
603+
- [Wikipedia - AA tree](https://en.wikipedia.org/wiki/AA_tree)

0 commit comments

Comments
 (0)