Skip to content

Commit 817e0c2

Browse files
committed
Merge branch '2024fixes' into 2024_sem2
AVL tree fixes etc. Radix sorts in menus etc also
2 parents f3ab1b9 + 55fc109 commit 817e0c2

29 files changed

+13672
-14984
lines changed

package-lock.json

Lines changed: 13135 additions & 14586 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,6 @@
4343
"last 1 safari version"
4444
]
4545
},
46-
"eslintConfig": {
47-
"extends": "react-app"
48-
},
4946
"jest": {
5047
"collectCoverageFrom": [
5148
"src/**/*.{js,jsx,ts,tsx}",
@@ -58,6 +55,8 @@
5855
]
5956
},
6057
"dependencies": {
58+
"nth-check": ">=2.0.1",
59+
"postcss": ">=8.4.31",
6160
"@emotion/react": "^11.11.1",
6261
"@emotion/styled": "^11.11.0",
6362
"@mui/icons-material": "^5.14.3",
@@ -91,10 +90,7 @@
9190
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
9291
"electron": "^31.4.0",
9392
"enzyme": "^3.11.0",
94-
"eslint": "^7.11.0",
95-
"eslint-plugin-import": "^2.28.1",
96-
"eslint-plugin-jsx-a11y": "^6.7.1",
97-
"eslint-plugin-react": "^7.33.2",
93+
"eslint-config-react-app": "^7.0.1",
9894
"husky": "^4.2.5",
9995
"jest": "^27.5.1",
10096
"lint-staged": "^10.1.3",

src/algorithms/controllers/AVLTreeInsertion.js

Lines changed: 131 additions & 87 deletions
Large diffs are not rendered by default.

src/algorithms/controllers/BFS.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ export default {
111111
);
112112

113113
const bfs = (s) => {
114-
115114
const Nodes = [s];
116115
// Seen[s] <- True B8
117116
visited[s] = true;
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# AVL Trees
2+
3+
AVL trees are binary search trees that have additional rules to keep them balanced.
4+
In an AVL tree search will always be O(log n), no matter what the input order.
5+
6+
## Binary Search Trees
7+
8+
A **binary tree** is either is either empty (Empty) or else it
9+
it has a root node and two subtrees (which are binary trees).
10+
The root node `t` has a key, `t.key`. Ordinarily it would also
11+
hold other data (`t.data`), which the user would like to find by
12+
searching for the key. Since this attribute has no impact on
13+
how insertion and search take place, we disregard it here.
14+
Note that a newly inserted node will always appear as a leaf
15+
in the tree.
16+
In a **binary search tree (BST)** the BST invariant is always maintained: for each
17+
subtree t, with root key t.key, the left subtree, t.left,
18+
contains no node with key greater than k, and the right subtree,
19+
t.right, contains no node with key smaller than k.
20+
21+
## The left-left case
22+
23+
If the new key was added to the left child of the left child (the
24+
left-left case) and the resulting tree is too unbalanced, the balance can be
25+
restored with a "Right rotation" operation, as explained in the diagram
26+
below. The 6 and 4 nodes and the edge between them rotate clockwise, and
27+
the 5 node changes parents from 4 to 6. This reduces the distance from
28+
the root to the 1 (where the new node was added), restoring the balance
29+
(the distance to the node rooted at 7 is increased but this does not
30+
cause the AVL tree balance condition to be violated). Right rotation is
31+
done by calling rightRotate(t6), where t6 is the tree rooted at 6.
32+
33+
```
34+
6 2
35+
/ \ Right Rotation / \
36+
2 7 - - - - - - - > 1 6
37+
/ \ < - - - - - - - / \
38+
1 4 Left Rotation 4 7
39+
```
40+
41+
## The right-right case
42+
43+
The right-right case is the exact opposite. If the tree on the right in
44+
the diagram above is too unbalanced due to insertion into the subtree
45+
rooted at 7, we can call rightRotate(t2) to lift that subtree and lower
46+
the 1 subtree.
47+
48+
## The left-right case (double rotation)
49+
50+
If the new key was added to the right child of the left child (the
51+
left-right case) and the resulting tree is too unbalanced, the balance can be
52+
restored with a left rotation at node 2 followed by a right rotation at
53+
node 6.
54+
```
55+
6 Rotate 6 Rotate 4
56+
/ \ left at 2 / \ right at 6 / \
57+
2 7 - - - - - > 4 7 - - - - - > 2 6
58+
/ \ / \ / \ / \
59+
1 4 2 5 1 3 5 7
60+
/ \ / \
61+
3 5 1 3
62+
```
63+
Nodes in the subtree rooted at 4 (where the extra element was added,
64+
making the tree unbalanced) are moved closer to the root.
65+
Trees rooted at 1, 3, 5 and 7 are not affected, except the distances from
66+
the root of 3, 5 and 7 are changed by one, affecting the overall balance.
67+
68+
## right-left case (double rotation):
69+
70+
If the new key was added to the left child of the right child (the
71+
right-left case) and the resulting tree is too unbalanced, it is a mirror
72+
image of the left-right case:
73+
74+
```
75+
2 Rotate 2 Rotate 4
76+
/ \ right at 6 / \ left at 2 / \
77+
1 6 - - - - - > 1 4 - - - - - > 2 6
78+
/ \ / \ / \ / \
79+
4 7 3 6 1 3 5 7
80+
/ \ / \
81+
3 5 5 7
82+
```

src/algorithms/explanations/AVLExp.md

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,74 @@
1-
# AVL Tree
1+
# AVL Trees
22

3-
A binary tree is either is either empty (Empty) or else it
3+
An AVL tree is **self-balancing** binary search tree.
4+
5+
Because the AVL tree is always balanced, search will be *O(log n)*,
6+
no matter what the order of the input data.
7+
8+
### Binary Search Trees
9+
10+
A **binary tree** is either is either empty (`Empty`) or else it
411
it has a root node and two subtrees (which are binary trees).
5-
The root node t has a key, t.key. Ordinarily it would also
6-
hold other data (t.data), which the user would like to find by
12+
The root node `t` has a key, `t.key`. Ordinarily it would also
13+
hold other data (`t.data`), which the user would like to find by
714
searching for the key. Since this attribute has no impact on
815
how insertion and search take place, we disregard it here.
916
Note that a newly inserted node will always appear as a leaf
10-
in the tree. The BST invariant is always maintained: for each
17+
in the tree.
18+
19+
In a **binary search tree (BST)** the BST invariant is always maintained:\
20+
for each
1121
subtree t, with root key t.key, the left subtree, t.left,
1222
contains no node with key greater than k, and the right subtree,
1323
t.right, contains no node with key smaller than k.
1424

25+
### AVL tree balancing
26+
27+
The AVL tree preserves the balance of the tree by (1) checking after every insertion to detect
28+
when the tree has become unbalanced
29+
and (2) performing one or more rotation operations to restore balance when necessary.
30+
Unbalanced is defined as a difference of more than `1` between the heights of the left and right subtrees.
31+
32+
(Here **MAYBE insert small pictures, thumbnails?** to show -- unbalanced at gp of new node,
33+
and also balanced at gp but unblanaced at ggp.)
34+
35+
A temporarily unbalanced AVL tree takes on one of two configurations, *zig-zag* or *zig-zig*. The
36+
sequence of rotations depends on the configuration around the node where the imbalance is detected.
37+
38+
### Zig-zig case
39+
40+
The *zig-zig* configuration has two mirror-image cases: the child and grandchild nodes or subtrees of the unbalanced node are
41+
either (1) both left subtrees or (2) both right subtrees.
42+
43+
1544
## The left-left case
1645

1746
If the new key was added to the left child of the left child (the
18-
left-left case) and the resulting tree is too unbalanced, the balance can be
19-
restored with a "Right rotation" operation, as explained in the diagram
47+
*left-left* case), the balance can be
48+
restored with a single _**Right Rotation**_ operation.
49+
50+
Note that the imbalance may be located further up the tree than the immediate grandparent of the newly inserted node:
51+
52+
**Insert very small diagrams showing (a) imbalance of the grandparent-parent and (b) imbalance of the great grandparent**
53+
*Note that all diagrams should hae nodes in BST order, and where the subtrees are not necessarily single nodes, represent them as subtree-triangles*
54+
*Have arrow showing which node is not in blanace*
55+
56+
57+
, as explained in the diagram
2058
below. The 6 and 4 nodes and the edge between them rotate clockwise, and
2159
the 5 node changes parents from 4 to 6. This reduces the distance from
2260
the root to the 1 (where the new node was added), restoring the balance
2361
(the distance to the node rooted at 7 is increased but this does not
2462
cause the AVL tree balance condition to be violated). Right rotation is
2563
done by calling rightRotate(t6), where t6 is the tree rooted at 6.
2664

65+
![Alt text if image doesn't open: AVL-left-left](images/AVL/AVL-left-left.jpg){width=120,height=50} This picture is from Greek for Geeks, and is only a placeholder to show proof of concept inserting diagrams, and to check things like size and cropping.
66+
67+
68+
69+
70+
71+
2772
```
2873
6 2
2974
/ \ Right Rotation / \
Loading

src/algorithms/parameters/ASTParam.js

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import MatrixParam from './helpers/MatrixParam';
44
import '../../styles/Param.scss';
55
import EuclideanMatrixParams from './helpers/EuclideanMatrixParams';
66
import PropTypes from 'prop-types'; // Import this for URL Param
7-
import { withAlgorithmParams } from './helpers/urlHelpers' // Import this for URL Param
7+
import { withAlgorithmParams, addURLGraph } from './helpers/urlHelpers'
88

99
// Note: 'A* Algorithm' currently used in EuclideanMatrixParams.js -
1010
// change both or neither!
@@ -34,28 +34,23 @@ const GRAPH_EGS = [ // XXX think up better examples?
3434
}];
3535
function ASTParam( { mode, xyCoords, edgeWeights, size, start, end, heuristic, min, max } ) {
3636
const [message, setMessage] = useState(null);
37-
const graph_egs = [
38-
{ name: 'URL Input Graph',
39-
size: size || GRAPH_EGS[0].size,
40-
coords: xyCoords || GRAPH_EGS[0].coords,
41-
edges: edgeWeights || GRAPH_EGS[0].edges
42-
}
43-
]
37+
let [start1, size1, graph_egs] =
38+
addURLGraph(GRAPH_EGS, xyCoords, edgeWeights, start, DEFAULT_START);
4439

4540
return (
4641
<>
4742
{/* Matrix input */}
4843
<EuclideanMatrixParams
4944
name="aStar"
5045
mode="find"
51-
defaultSize={ size || DEFAULT_SIZE }
52-
defaultStart={ start || DEFAULT_START }
46+
defaultSize={ size1 }
47+
defaultStart={ start1 }
5348
defaultEnd={ end || DEFAULT_END }
5449
heuristic = { heuristic || DEFAULT_HEUR }
5550
min={ min || 1 }
5651
max={ max || 49 }
5752
symmetric
58-
graphEgs={ graph_egs || GRAPH_EGS }
53+
graphEgs={ graph_egs }
5954
ALGORITHM_NAME={ASTAR}
6055
EXAMPLE={ASTAR_EXAMPLE}
6156
EXAMPLE2={ASTAR_EXAMPLE2}

src/algorithms/parameters/BFSParam.js

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import MatrixParam from './helpers/MatrixParam';
44
import '../../styles/Param.scss';
55
import EuclideanMatrixParams from './helpers/EuclideanMatrixParams';
66
import PropTypes from 'prop-types'; // Import this for URL Param
7-
import { withAlgorithmParams } from './helpers/urlHelpers' // Import this for URL Param
7+
import { withAlgorithmParams, addURLGraph } from './helpers/urlHelpers'
88

99
const DEFAULT_SIZE = 5;
1010
const BFS = 'BFS\'s';
@@ -33,27 +33,22 @@ const GRAPH_EGS = [ // XXX think up better examples?
3333

3434
function BFSParam({ mode, xyCoords, edgeWeights, size, start, end, heuristic, min, max }) {
3535
const [message, setMessage] = useState(null);
36-
const graph_egs = [
37-
{ name: 'URL Input Graph',
38-
size: size || GRAPH_EGS[0].size,
39-
coords: xyCoords || GRAPH_EGS[0].coords,
40-
edges: edgeWeights || GRAPH_EGS[0].edges
41-
}
42-
]
36+
let [start1, size1, graph_egs] =
37+
addURLGraph(GRAPH_EGS, xyCoords, edgeWeights, start, DEFAULT_START);
4338
return (
4439
<>
4540
{/* Matrix input */}
4641
<EuclideanMatrixParams
4742
name="BFS"
4843
mode="find"
49-
defaultSize={ size || DEFAULT_SIZE }
50-
defaultStart={ start || DEFAULT_START }
44+
defaultSize={ size1 }
45+
defaultStart={ start1 }
5146
defaultEnd={ end || DEFAULT_END }
52-
defaultHeur = { heuristic || DEFAULT_HEUR }
47+
defaultHeur = { DEFAULT_HEUR }
5348
min={ min || 1 }
5449
max={ max || 49 }
5550
symmetric
56-
graphEgs={ graph_egs || GRAPH_EGS }
51+
graphEgs={ graph_egs }
5752
ALGORITHM_NAME={BFS}
5853
EXAMPLE={BFS_EXAMPLE}
5954
EXAMPLE2={BFS_EXAMPLE2}

src/algorithms/parameters/DFSParam.js

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import MatrixParam from './helpers/MatrixParam';
44
import '../../styles/Param.scss';
55
import EuclideanMatrixParams from './helpers/EuclideanMatrixParams';
66
import PropTypes from 'prop-types'; // Import this for URL Param
7-
import { withAlgorithmParams } from './helpers/urlHelpers' // Import this for URL Param
7+
import { withAlgorithmParams, addURLGraph } from './helpers/urlHelpers'
88

99
const DEFAULT_SIZE = 5;
1010
const DFS = 'DFS\'s';
@@ -33,26 +33,21 @@ const GRAPH_EGS = [ // XXX think up better examples?
3333

3434
function DFSParam({ mode, xyCoords, edgeWeights, size, start, end, heuristic, min, max }) {
3535
const [message, setMessage] = useState(null);
36-
const graph_egs = [
37-
{ name: 'URL Input Graph',
38-
size: size || GRAPH_EGS[0].size,
39-
coords: xyCoords || GRAPH_EGS[0].coords,
40-
edges: edgeWeights || GRAPH_EGS[0].edges
41-
}
42-
]
36+
let [start1, size1, graph_egs] =
37+
addURLGraph(GRAPH_EGS, xyCoords, edgeWeights, start, DEFAULT_START);
4338
return (
4439
<>
4540
{/* Matrix input */}
4641
<EuclideanMatrixParams
4742
name="DFS"
4843
mode= "find"
49-
defaultSize={ size || DEFAULT_SIZE }
50-
defaultStart={start || DEFAULT_START }
51-
defaultHeur = {heuristic || DEFAULT_HEUR }
44+
defaultSize={ size1 }
45+
defaultStart={ start1 }
5246
defaultEnd={ end || DEFAULT_END }
47+
defaultHeur = {DEFAULT_HEUR }
5348
min={ min || 1 }
5449
max={ max || 49 }
55-
graphEgs={graph_egs || GRAPH_EGS}
50+
graphEgs={graph_egs}
5651
symmetric
5752
ALGORITHM_NAME={DFS}
5853
EXAMPLE={DFS_EXAMPLE}

src/algorithms/parameters/DFSrecParam.js

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import MatrixParam from './helpers/MatrixParam';
44
import '../../styles/Param.scss';
55
import EuclideanMatrixParams from './helpers/EuclideanMatrixParams';
66
import PropTypes from 'prop-types'; // Import this for URL Param
7-
import { withAlgorithmParams } from './helpers/urlHelpers' // Import this for URL Param
7+
import { withAlgorithmParams, addURLGraph } from './helpers/urlHelpers'
88

99
const DEFAULT_SIZE = 5;
1010
const DFSrec = 'DFSrec\'s';
@@ -33,27 +33,22 @@ const GRAPH_EGS = [ // XXX think up better examples?
3333

3434
function DFSrecParam({ mode, xyCoords, edgeWeights, size, start, end, heuristic, min, max }) {
3535
const [message, setMessage] = useState(null);
36-
const graph_egs = [
37-
{ name: 'URL Input Graph',
38-
size: size || GRAPH_EGS[0].size,
39-
coords: xyCoords || GRAPH_EGS[0].coords,
40-
edges: edgeWeights || GRAPH_EGS[0].edges
41-
}
42-
]
36+
let [start1, size1, graph_egs] =
37+
addURLGraph(GRAPH_EGS, xyCoords, edgeWeights, start, DEFAULT_START);
4338

4439
return (
4540
<>
4641
{/* Matrix input */}
4742
<EuclideanMatrixParams
4843
name="DFSrec"
4944
mode="find"
50-
defaultSize={size || DEFAULT_SIZE}
51-
defaultStart={start || DEFAULT_START}
52-
defaultHeur = {heuristic || DEFAULT_HEUR}
45+
defaultSize={ size1 }
46+
defaultStart={ start1 }
47+
defaultHeur = {DEFAULT_HEUR}
5348
defaultEnd={end || DEFAULT_END}
5449
min={min || 1}
5550
max={max || 49}
56-
graphEgs={graph_egs || GRAPH_EGS}
51+
graphEgs={graph_egs}
5752
symmetric
5853
ALGORITHM_NAME={DFSrec}
5954
EXAMPLE={DFSrec_EXAMPLE}

0 commit comments

Comments
 (0)