This repository has been archived by the owner on Oct 23, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtree.h
151 lines (125 loc) · 3.12 KB
/
tree.h
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#pragma once
#include "header.h"
/* Tree (data structure) support */
class Node {
private:
int _degree;
Data* data;
Node* _father = nullptr;
std::vector<Node*> children;
public:
Node(void);
Node(const Data& data);
~Node(void);
std::vector<Node*>::const_iterator begin(void) const;
std::vector<Node*>::const_iterator end(void) const;
public:
Data* get(void) const;
int degree(void) const;
Node* father(void) const;
void add(Node*& child);
void add(const Data& data);
void remove(const int index);
Node* operator[] (int index);
const Node* operator[] (int index) const;
//friend class Iterator;
};
/* Traversing support */
template <typename Contaniner>
class Traverse {
protected:
Node* current;
bool running = true;
Contaniner unvisited;
public:
// Prevent the compiler from generating a default constructor
Traverse(void) { this->current = nullptr; }
typedef Node* data;
Traverse(Node* root) {
this->unvisited.push(root);
this->current = root;
}
bool status(void) const {
return this->running;
}
virtual void next(void) = 0;
data get(void) const {
return this->current;
}
data yield(void) {
try {
this->next();
data current = this->current;
return current;
}
catch (std::out_of_range) {
this->running = false;
return nullptr;
}
}
};
/*
Traversing the tree using the BFS algorithm
Traverse all nodes of the tree using the queue's first-in,
first-out (FIFO) feature level.
*/
class BFSTraverse : public Traverse<std::queue<Node*>> {
using Traverse::Traverse;
void next(void) {
// If queue is empty
if (!this->unvisited.size())
throw std::out_of_range("traverse ended.");
this->current = this->unvisited.front();
this->unvisited.pop();
// Traversing the child nodes to the queue
if (!this->current->degree())
return;
for (auto child : *(this->current))
this->unvisited.push(child);
}
};
/*
Traversing the tree using the DFS algorithm
The principle is the same as above, but the stack is LIFO
*/
class DFSTraverse : public Traverse<std::stack<Node*>> {
using Traverse::Traverse;
void next(void) {
// If list if empty
if (!this->unvisited.size())
throw std::out_of_range("traverse ended.");
this->current = this->unvisited.top();
this->unvisited.pop();
// Traversing the child nodes to the queue
if (!this->current->degree())
return;
for (auto child : *(this->current))
this->unvisited.push(child);
}
};
/*
Tree support
bool exist(Node* target); // Find if specified node in tree
std::vector<Node*> path(const Node*); // Find path for specified node
*/
class Tree {
private:
Node* root;
public:
Tree(Node*);
~Tree(void);
bool exist(const Node*);
std::stack<Node*> search(const Node*);
static std::stack<Node*> path(const Node*);
// Give an iterator that generates a root node to a leaf node
class Parser {
private:
bool running = true;
DFSTraverse traverser;
public:
Parser(Node*);
bool status(void) const;
std::stack<Node*> yield(void);
};
Tree::Parser leaves(void);
};