This repository has been archived on 2022-06-05. You can view files and clone it, but cannot push or open issues or pull requests.
Files
AiSD/Part1/Lab3/main.cpp
2022-05-14 15:22:55 +03:00

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';
}