void deleteNode(int p) {
			int q;

			if (parent[p] == NIL) {
				return; /* not in tree */
			}
			if (rchild[p] == NIL) {
				q = lchild[p];
			}
			else if (lchild[p] == NIL) {
				q = rchild[p];
			}
			else {
				q = lchild[p];
				if (rchild[q] != NIL) {
					do {
						q = rchild[q];
					}
					while (rchild[q] != NIL);
					rchild[parent[q]] = lchild[q];
					parent[lchild[q]] = parent[q];
					lchild[q] = lchild[p];
					parent[lchild[p]] = q;
				}
				rchild[q] = rchild[p];
				parent[rchild[p]] = q;
			}
			parent[q] = parent[p];
			if (rchild[parent[p]] == p) {
				rchild[parent[p]] = q;
			}
			else {
				lchild[parent[p]] = q;
			}
			parent[p] = NIL;
		}
initialize state, mostly the trees

For i = 0 to N - 1, rchild[i] and lchild[i] will be the right and
left children of node i. These nodes need not be initialized. Also
parent[i] is the parent of node i. These are initialzied to NIL (=N),
which stands for 'not used.' For i = 0 to 256, rchild[N + i + 1] is
the root of the tree for strings that begin with character i. These
are initialized to NIL. Note there are 256 trees.
Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/lzss/LzssCodec.java