-
Notifications
You must be signed in to change notification settings - Fork 1
/
suffix_tree_dfs.c
102 lines (87 loc) · 2.59 KB
/
suffix_tree_dfs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <stdlib.h>
#include "suffix_tree_dfs.h"
#include "helpers.h"
DfsPosition *CreateDfsPosition(SuffixTree *st, int *s, int n, int ind, int treeType)
{
DfsPosition *p = calloc(1, sizeof *p);
p->tree = st;
p->treeType = treeType;
p->s = s;
p->n = n;
p->ind = ind;
p->lastDfsLeaf = 0;
p->lastChild = CreateDynamicArray(1);
PushToDynamicArray(p->lastChild, 0);
return p;
}
void FreeDfsPosition(DfsPosition *p)
{
if (!p)
return;
FreeDynamicArray(p->lastChild);
MemFree(p);
}
/* ------------ short inline helpers ------------ */
inline int EndOfDfs(DfsPosition *p)
{
return 0 == p->ind && *LastInDynamicArray(p->lastChild) == p->tree->nodes[0].childrenCount;
}
inline int GetEdgeLength(DfsPosition *p)
{
return p->tree->nodes[GetChildIndex(p)].depth - p->tree->nodes[p->ind].depth;
}
inline int GetFirstCharOfChildEdge(DfsPosition *p)
{
return *LastInDynamicArray(p->lastChild) < p->tree->nodes[p->ind].childrenCount
? p->s[p->tree->nodes[GetChildIndex(p)].from]
: p->s[p->n];
}
inline int GetChildIndex(DfsPosition *p)
{
return p->tree->nodes[p->ind].children[*LastInDynamicArray(p->lastChild)];
}
/* --------------------------------------------- */
void SwapPositions(DfsPosition **px, DfsPosition **py)
{
DfsPosition *t = *px;
*px = *py;
*py = t;
}
int CompareAndSwapDfsPositions(DfsPosition **ppx, DfsPosition **ppy)
{
DfsPosition *px = *ppx, *py = *ppy;
if (px->tree->nodes[px->ind].depth == py->tree->nodes[py->ind].depth)
{
int cx = GetFirstCharOfChildEdge(px);
int cy = GetFirstCharOfChildEdge(py);
if (cx > cy)
SwapPositions(ppx, ppy);
return cx != cy;
}
else
{
if (px->tree->nodes[px->ind].depth < py->tree->nodes[py->ind].depth)
SwapPositions(ppx, ppy);
return 1;
}
}
int NextStepOfDfs(DfsPosition *p, int minDepth)
{
if (*LastInDynamicArray(p->lastChild) < p->tree->nodes[p->ind].childrenCount)
{
// move down through next child edge
p->ind = GetChildIndex(p);
PushToDynamicArray(p->lastChild, 0);
}
// go upward until we can go downward in next step
while (*LastInDynamicArray(p->lastChild) >= p->tree->nodes[p->ind].childrenCount)
{
if (p->ind == 0 || p->tree->nodes[p->tree->nodes[p->ind].parent].depth < minDepth)
return 0;
// up to parent
p->ind = p->tree->nodes[p->ind].parent;
--(p->lastChild->count);
++(*LastInDynamicArray(p->lastChild));
}
return 1;
}