281 lines
6.0 KiB
C++
281 lines
6.0 KiB
C++
#include <iostream>
|
|
#include <fstream>
|
|
using namespace std;
|
|
//Êëàññ «óçåë äåðåâà»
|
|
class Node {
|
|
char d; //òåã óçëà
|
|
Node* lft; // ëåâûé ñûí
|
|
Node* rgt; // ïðàâûé ñûí
|
|
int count = 0;
|
|
public:
|
|
Node() : lft(nullptr), rgt(nullptr) { } // êîíñòðóêòîð óçëà
|
|
Node(const Node&) = delete;
|
|
Node& operator = (const Node&) = delete;
|
|
~Node() {
|
|
delete lft; // äåñòðóêòîð óçëà (óíè÷òîæàåò âñå ïîääåðåâî
|
|
delete rgt;
|
|
} // â ïîðÿäêå, îáðàòíîì åãî ñîçäàíèþ)
|
|
friend class Tree; // äðóæåñòâåííûé êëàññ «äåðåâî»
|
|
};
|
|
// Êëàññ «äåðåâî â öåëîì»
|
|
class Tree
|
|
{
|
|
Node* root; // óêàçàòåëü íà êîðåíü äåðåâà
|
|
char num, maxnum; // ñ÷åò÷èê òåãîâ è ìàêñèìàëüíûé òåã
|
|
int maxrow, offset; // ìàêñèìàëüíàÿ ãëóáèíà, ñìåùåíèå êîðíÿ
|
|
char** SCREEN; // áóôåð äëÿ âûäà÷è íà ýêðàí
|
|
void clrscr() // î÷èñòêà áóôåðà
|
|
{
|
|
for (int i = 0; i < maxrow; i++)
|
|
memset(SCREEN[i], '.', 80);
|
|
}
|
|
|
|
Node* MakeNode(int depth) // ñîçäàíèå ïîääåðåâà
|
|
{
|
|
Node* v = nullptr;
|
|
int random;
|
|
random = rand() % 5 + 1;// cout << random << endl;
|
|
int Y = (depth < random) && (num <= 'ÿ');
|
|
//Âàðèàíò: cout << "Node (" << num << ',' << depth << ")1/0: "; cin >> Y;
|
|
if (Y) { // ñîçäàíèå óçëà, åñëè Y = 1
|
|
v = new Node;
|
|
v->lft = MakeNode(depth + 1);
|
|
v->d = num++; // âàðèàíò — âî âíóòðåííåì
|
|
v->rgt = MakeNode(depth + 1);
|
|
}
|
|
return v;
|
|
}
|
|
void OutNodes(Node* v, int r, int c) // âûäà÷à ïîääåðåâà // root, 1, 40
|
|
{
|
|
if (r && c && (c < 80)) SCREEN[r - 1][c - 1] = v->d; // âûâîä ìåòêè
|
|
if (r < maxrow) {
|
|
if (v->lft) OutNodes(v->lft, r + 1, c -(offset >> r)); //ëåâûé ñûí
|
|
if (v->rgt) OutNodes(v->rgt, r + 1, c + (offset >> r)); //ïðàâûé ñûí
|
|
}
|
|
}
|
|
|
|
//Tree(const Tree&) = delete; // êîíñòðóêòîð êîïèè
|
|
//Tree(Tree&&) = delete; // êîïèÿ ñ ïåðåíîñîì (Ñ++11)
|
|
//Tree& operator = (const Tree&) const = delete; // ïðèñâàèâàíèå
|
|
//Tree& operator = (Tree&&) const = delete; // òî æå, ñ ïåðåíîñîì
|
|
//
|
|
|
|
|
|
public:
|
|
Tree(char nm, char mnm, int mxr) :
|
|
num(nm), maxnum(mnm), maxrow(mxr), offset(40), root(nullptr),
|
|
SCREEN(new char* [maxrow])
|
|
{
|
|
for (int i = 0; i < maxrow; i++) SCREEN[i] = new char[80];
|
|
}
|
|
|
|
~Tree() {
|
|
for (int i = 0; i < maxrow; i++) delete[]SCREEN[i];
|
|
delete[]SCREEN; delete root;
|
|
}
|
|
void MakeTree() // ââîä — ãåíåðàöèÿ äåðåâà
|
|
{
|
|
root = MakeNode(0);
|
|
}
|
|
bool exist() { return root != nullptr; } // ïðîâåðêà «äåðåâî íå ïóñòî»
|
|
void OutTree() // âûäà÷à íà ýêðàí
|
|
{
|
|
clrscr();
|
|
OutNodes(root, 1, offset);
|
|
for (int i = 0; i < maxrow; i++)
|
|
{
|
|
SCREEN[i][79] = 0;
|
|
cout << '\n' << SCREEN[i];
|
|
}
|
|
cout << '\n';
|
|
}
|
|
|
|
int DFS() // îáõîä äåðåâà «â ãëóáèíó»
|
|
{
|
|
const int MaxS = 20; // ìàêñèìàëüíûé ðàçìåð ñòåêà
|
|
int count = 0;
|
|
STACK <Node*> S(MaxS); //ñîçäàíèå ñòåêà óêàçàòåëåé íà óçëû
|
|
S.push(root); // STACK <- root
|
|
while (!S.empty()) // Ïîêà ñòåê íå ïóñò…
|
|
{
|
|
Node* v = S.pop(); // ïîäíÿòü óçåë èç ñòåêà
|
|
cout << v->d << '_'; count++; // âûäàòü òåã, ñ÷åò óçëîâ
|
|
if (v->rgt) S.push(v->rgt); // STACK <- (ïðàâûé ñûí)
|
|
if (v->lft) S.push(v->lft); // STACK <- (ëåâûé ñûí)
|
|
}
|
|
return count;
|
|
}
|
|
|
|
template <class Item>
|
|
class STACK
|
|
{
|
|
Item* S;
|
|
int t;
|
|
public:
|
|
STACK(int maxt)
|
|
{
|
|
S = new Item[maxt];
|
|
t = 0;
|
|
}
|
|
int empty() const
|
|
{
|
|
return t == 0;
|
|
}
|
|
void push(Item item)
|
|
{
|
|
S[t++] = item;
|
|
}
|
|
Item pop()
|
|
{
|
|
return (t ? S[--t] : 0);
|
|
}
|
|
};
|
|
|
|
|
|
int result()
|
|
{
|
|
int rezult = 0;
|
|
search_1(root, 1);
|
|
search_2(root, 1);
|
|
return counter(root, 1, &rezult);
|
|
}
|
|
void search_1(Node* v, int x) // ïðîñòàâëÿåì êîëè÷åñòâî ñûíîâåé â êàæäîé âåðøèíå
|
|
{
|
|
while (x)
|
|
{
|
|
if (v->lft != nullptr)
|
|
{
|
|
v->count++;
|
|
search_1(v->lft,1);
|
|
if (v->rgt != nullptr)
|
|
{
|
|
v->count++;
|
|
search_1(v->rgt, 1);
|
|
x = 0;
|
|
}
|
|
x = 0;
|
|
}
|
|
if ((v->rgt == nullptr && v->lft == nullptr) || (v->count > 1))
|
|
{
|
|
x = 0;
|
|
break;
|
|
}
|
|
|
|
if (v->rgt != nullptr)
|
|
{
|
|
v->count++;
|
|
search_1(v->rgt, 1);
|
|
if (v->lft != nullptr)
|
|
{
|
|
v->count++;
|
|
search_1(v->lft, 1);
|
|
x = 0;
|
|
}
|
|
x = 0;
|
|
}
|
|
|
|
if (v->rgt == nullptr && v->lft == nullptr) x = 0;
|
|
}
|
|
}
|
|
void search_2(Node* v, int x) // ê êîëè÷åñòâó óæå èìåþùèõñÿ ñûíîâåé ó êàæäîé âåðøèíû ïðèáàâëÿåì êîëè÷åñâòî ñûíîâåé ó êàæäîãîãî ñûíà î÷åðåäíîé âåðøèíû
|
|
{
|
|
while (x)// //////
|
|
{
|
|
if (v->lft != nullptr)
|
|
{
|
|
v->count = v->count + v->lft->count;
|
|
search_2(v->lft, 1);
|
|
if (v->rgt != nullptr)
|
|
{
|
|
v->count = v->count + v->rgt->count;
|
|
search_2(v->rgt, 1);
|
|
x = 0;
|
|
}
|
|
x = 0;
|
|
}
|
|
|
|
|
|
if ((v->rgt == nullptr && v->lft == nullptr) || (v->count > 3))
|
|
{
|
|
x = 0;
|
|
break;
|
|
}
|
|
|
|
if (v->rgt != nullptr)
|
|
{
|
|
v->count = v->count + v->rgt->count;
|
|
search_2(v->rgt, 1);
|
|
if (v->lft != nullptr)
|
|
{
|
|
v->count = v->count + v->lft->count;
|
|
search_2(v->lft, 1);
|
|
x = 0;
|
|
}
|
|
x = 0;
|
|
}
|
|
|
|
if (v->rgt == nullptr && v->lft == nullptr) x = 0;
|
|
}
|
|
}
|
|
|
|
int counter(Node* v, int x, int* rezult)
|
|
{// â ðåçóëüòàò èäóò âåðøèíû â êîòîðûõ îäèí èëè 0 ñûíîâåé* (*íå ñûíîâåé à òî ÷òî ìû ñ÷èòàëè â ïðîøëûõ äâóõ ôóíêöèÿõ)
|
|
while (x)
|
|
{
|
|
if (v->count < 2)
|
|
{
|
|
(*rezult)++;
|
|
if (v->lft != nullptr)
|
|
{
|
|
counter(v->lft, 1, rezult);
|
|
x = 0;
|
|
}
|
|
if (v->rgt != nullptr)
|
|
{
|
|
counter(v->rgt, 1, rezult);
|
|
x = 0;
|
|
}
|
|
if (v->rgt == nullptr && v->lft == nullptr) x = 0;
|
|
}
|
|
else
|
|
{
|
|
if (v->lft != nullptr)
|
|
{
|
|
counter(v->lft, 1, rezult);
|
|
x = 0;
|
|
}
|
|
if (v->rgt != nullptr)
|
|
{
|
|
counter(v->rgt, 1, rezult);
|
|
x = 0;
|
|
}
|
|
if (v->rgt == nullptr && v->lft == nullptr) x = 0;
|
|
}
|
|
}
|
|
return *rezult;
|
|
}
|
|
};
|
|
|
|
|
|
//
|
|
int main ()
|
|
{
|
|
int n = 0, rezult;
|
|
setlocale(LC_ALL, "Russian");
|
|
srand(time(0));
|
|
|
|
Tree tr('à','ÿ',5);
|
|
tr.MakeTree();
|
|
if (tr.exist())
|
|
{
|
|
tr.OutTree();
|
|
cout << '\n' << "Îáõîä â ãëóáèíó: ";
|
|
n = tr.DFS();
|
|
cout << " Ïðîéäåíî óçëîâ = " << n << '\n';
|
|
rezult = tr.result();
|
|
cout << "Êîëè÷åñòâî âåðøèí, èìåþùèõ íå áîëåå îäíîãî ïîòîìêà: " << rezult << '\n';
|
|
}
|
|
else
|
|
cout << "Error." << '\n';
|
|
|
|
} |