From 7f32fee19a0995ea75aa387e41f244a7c924aa54 Mon Sep 17 00:00:00 2001 From: Revone Date: Wed, 31 Jul 2024 14:10:32 +1200 Subject: [PATCH] docs: Added a document detailing the differences between various data structures, including schematic diagrams of the data structures. --- README.md | 87 +++++++++++++++++++++ test/unit/data-structures/heap/heap.test.ts | 20 +++++ 2 files changed, 107 insertions(+) diff --git a/README.md b/README.md index efad5de..a87679d 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,93 @@ Performance surpasses that of native JS/TS +### What are the differences + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data StructurePlain Language DefinitionDiagram
Linked List (Singly Linked List)A line of bunnies, where each bunny holds the tail of the bunny in front of it (each bunny only knows the name of the bunny behind it). You want to find a bunny named Pablo, and you have to start searching from the first bunny. If it's not Pablo, you continue following that bunny's tail to the next one. So, you might need to search n times to find Pablo (O(n) time complexity). If you want to insert a bunny named Remi between Pablo and Vicky, it's very simple. You just need to let Vicky release Pablo's tail, let Remi hold Pablo's tail, and then let Vicky hold Remi's tail (O(1) time complexity).singly linked list
ArrayA line of numbered bunnies. If you want to find the bunny named Pablo, you can directly shout out Pablo's number 0680 (finding the element directly through array indexing, O(1) time complexity). However, if you don't know Pablo's number, you still need to search one by one (O(n) time complexity). Moreover, if you want to add a bunny named Vicky behind Pablo, you will need to renumber all the bunnies after Vicky (O(n) time complexity).array
QueueA line of numbered bunnies with a sticky note on the first bunny. For this line with a sticky note on the first bunny, whenever we want to remove a bunny from the front of the line, we only need to move the sticky note to the face of the next bunny without actually removing the bunny to avoid renumbering all the bunnies behind (removing from the front is also O(1) time complexity). For the tail of the line, we don't need to worry because each new bunny added to the tail is directly given a new number (O(1) time complexity) without needing to renumber all the previous bunnies.queue
DequeA line of grouped, numbered bunnies with a sticky note on the first bunny. For this line, we manage it by groups. Each time we remove a bunny from the front of the line, we only move the sticky note to the next bunny. This way, we don't need to renumber all the bunnies behind the first bunny each time a bunny is removed. Only when all members of a group are removed do we reassign numbers and regroup. The tail is handled similarly. This is a strategy of delaying and batching operations to offset the drawbacks of the Array data structure that requires moving all elements behind when inserting or deleting elements in the middle.deque
Doubly Linked ListA line of bunnies where each bunny holds the tail of the bunny in front (each bunny knows the names of the two adjacent bunnies). This provides the Singly Linked List the ability to search forward, and that's all. For example, if you directly come to the bunny Remi in the line and ask her where Vicky is, she will say the one holding my tail behind me, and if you ask her where Pablo is, she will say right in front.doubly linked list
StackA line of bunnies in a dead-end tunnel, where bunnies can only be removed from the tunnel entrance (end), and new bunnies can only be added at the entrance (end) as well.stack
Binary TreeAs the name suggests, it's a tree where each node has at most two children. When you add consecutive data such as [4, 2, 6, 1, 3, 5, 7], it will be a complete binary tree. When you add data like [4, 2, 6, null, 1, 3, null, 5, null, 7], you can specify whether any left or right child node is null, and the shape of the tree is fully controllable.binary tree
Binary Search Tree (BST)A bunny group in the form of a tree, where each bunny can grow at most 2 tails (Doubly Linked List). The most important data structure in a binary tree (the core is that the time complexity for insertion, deletion, modification, and search is O(log n)). The data stored in a BST is structured and ordered, not in strict order like 1, 2, 3, 4, 5, but maintaining that all nodes in the left subtree are less than the node, and all nodes in the right subtree are greater than the node. This order provides O(log n) time complexity for insertion, deletion, modification, and search. Reducing O(n) to O(log n) is the most common algorithm complexity optimization in the computer field, an exponential improvement in efficiency. It's also the most efficient way to organize unordered data into ordered data (most sorting algorithms only maintain O(n log n)). Of course, the binary search trees we provide support organizing data in both ascending and descending order. Remember that basic BSTs do not have self-balancing capabilities, and if you sequentially add sorted data to this data structure, it will degrade into a list, thus losing the O(log n) capability. Of course, our addMany method is specially handled to prevent degradation. However, for practical applications, please use Red-black Tree or AVL Tree as much as possible, as they inherently have self-balancing functions.binary search tree
Red-black TreeA self-balancing binary search tree. Each node is marked with a red-black label. Ensuring that no path is more than twice as long as any other (maintaining a certain balance to improve the speed of search, addition, and deletion).red-black tree
AVL TreeA self-balancing binary search tree. Each node is marked with a balance factor, representing the height difference between its left and right subtrees. The absolute value of the balance factor does not exceed 1 (maintaining stricter balance, which makes search efficiency higher than Red-black Tree, but insertion and deletion operations will be more complex and relatively less efficient).avl tree
HeapA special type of complete binary tree, often stored in an array, where the children nodes of the node at index i are at indices 2i+1 and 2i+2. Naturally, the parent node of any node is at āŒŠ(iāˆ’1)/2āŒ‹.heap
Priority QueueIt's actually a Heap.priority queue
GraphThe base class for Directed Graph and Undirected Graph, providing some common methods.graph
Directed GraphA network-like bunny group where each bunny can have up to n tails (Singly Linked List).directed graph
Undirected GraphA network-like bunny group where each bunny can have up to n tails (Doubly Linked List).undirected graph
+ + + ### Conciseness and uniformity In [java.utils](), you need to memorize a table for all sequential data structures(Queue, Deque, LinkedList), diff --git a/test/unit/data-structures/heap/heap.test.ts b/test/unit/data-structures/heap/heap.test.ts index 009cc2b..489724a 100644 --- a/test/unit/data-structures/heap/heap.test.ts +++ b/test/unit/data-structures/heap/heap.test.ts @@ -2,6 +2,26 @@ import { FibonacciHeap, Heap, MaxHeap, MinHeap } from '../../../../src'; import { logBigOMetricsWrap } from '../../../utils'; describe('Heap Operation Test', () => { + + it('should heap add and delete work well', function () { + const hp = new MinHeap(); + + hp.add(2); + hp.add(3); + hp.add(1); + hp.add(4); + hp.add(6); + hp.add(5); + hp.add(7); + + hp.delete(4); + hp.delete(7); + hp.delete(1); + + expect(hp.size).toBe(4); + expect(hp.peek()).toBe(2); + }); + it('should numeric heap work well', function () { const minNumHeap = new MinHeap(); minNumHeap.add(1);