diff --git a/lab1/include/Funcs.cpp b/lab1/include/Funcs.cpp new file mode 100644 index 000000000..2e58b6785 --- /dev/null +++ b/lab1/include/Funcs.cpp @@ -0,0 +1,171 @@ +#include"Stack.h" +#include +#include"Funcs.h" + +using namespace std; + +int funcs::checkpriority(char x) +{ + int res = 0; + if (x == '!') return 0; + if (((x >= 'A') && (x <= 'Z')) || ((x >= 'a') && (x <= 'z')))return 5; + if ((x == '/') || (x == '*')) return 3; + if ((x == '+') || (x == '-')) return 2; + if (x == '(')return 0; + if (x == ')')return 4; + throw"error"; +} + +void funcs::calculate(string string) +{ + float op, op1, op2; + Stack Tstack; + map valuemap = readvalue(string); + for (const char& k : string) + { + if (((k >= 'A') && (k <= 'Z')) || ((k >= 'a') && (k <= 'z'))) + { + op = valuemap[k]; + Tstack.Push(op); + } + + switch (k) + { + case'-': + { + op1 = Tstack.Pop(); + op2 = Tstack.Pop(); + Tstack.Push(op2 - op1); + break; + } + case'+': + { + op1 = Tstack.Pop(); + op2 = Tstack.Pop(); + Tstack.Push(op2 + op1); + break; + } + case'*': + { + op1 = Tstack.Pop(); + op2 = Tstack.Pop(); + Tstack.Push(op2*op1); + break; + } + case'/': + { + op1 = Tstack.Pop(); + op2 = Tstack.Pop(); + Tstack.Push(op2 / op1); + break; + } + } + } + cout << "Результат: " << Tstack.Pop() << endl; + + +} + + +string funcs::postfixform(string string) +{ + Stack first; + Stack second; + int priority, oppriority; + for (char el : string) + { + priority = checkpriority(el); + if (priority == 0)//пришла левая скобка + { + second.Push(el); + } + + if (priority == 5)//пришел операнд-кладем в 1й стек + { + first.Push(el); + } + if (priority == 2)//пришла операция "+" или "-" + { + oppriority = checkpriority(second.checktop()); + if (oppriority <= 2)//если приоритет операции на вершине стека меньше либо равен приоритету операции-кладем операцию во 2й стек + { + second.Push(el); + + } + else//вытаскиваем все операции из ст.2 у которых приоритет выше либо равен приоритеу операции и перекладываем в ст.1 + { + while (checkpriority(second.checktop()) >= 2) + { + first.Push(second.Pop()); + } + second.Push(el); + } + } + if (priority == 3)//т.к. максимальный приоритет-3,то просто кладем в стек 3; + { + second.Push(el); + } + if (priority == 4) + { + while (checkpriority(second.checktop()) != 0)//перекладываем операции из ст.2 в ст.1 до "(" + { + first.Push(second.Pop()); + } + second.Pop();//изымаем "(" из ст.2 + } + } + while (!second.IsEmpty()) + { + first.Push(second.Pop()); + } + + std::string tmpstring; + int j = first.Size(); + for (int i = 0; i funcs::readvalue(string str) +{ + map res; + float value; + for (const char& c : str) + { + if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))) { + if (res.count(c) == 0) + { + cout << "Введите: " << c << endl; + cin >> value; + res.insert(pair(c, value)); + } + } + } + return res; +} \ No newline at end of file diff --git a/lab1/include/List.h b/lab1/include/List.h new file mode 100644 index 000000000..254a3ecf2 --- /dev/null +++ b/lab1/include/List.h @@ -0,0 +1,137 @@ +#pragma once +#include +#include "Node.h" +using namespace std; + + +template +class List { +private: + Node*root;//указатель на первый элемент списка +public: + List();//конструктор по умолчанию + List(const List&);//конструктор копирования + ~List();//деструктор + void insertend(Tkey key);//вставка в конец списка + void insertbegin(Tkey key);//вставка в начало списка + void remove(Tkey key);//удаление элемента + Node* search(Tkey key);//поиск элемента + int Size()const;//кол-во элементов списка + Node* GetRoot();//получить ссылку на первый элемент списка +}; +template +List::List() +{ + root = nullptr; +}; + +template +List::~List() +{ + delete root; +}; + +template +void List::insertbegin(Tkey key) +{ + Node*nNode = new Node; + nNode->Key = key; + nNode->pNext = root; + root = nNode; +}; +template +void List::insertend(Tkey key) +{ + if (root == nullptr) + { + insertbegin(key); + return; + } + Node*tmp = root; + while (tmp->pNext != nullptr) + { + tmp = tmp->pNext; + } + tmp->pNext = new Node; + tmp->pNext->key = key; + tmp->pNext->pNext = nullptr; +}; + +template +void List::remove(Tkey key) +{ + if (root == nullptr) return; + Node*node = root; + if (root->Key == key) + { + root = root->pNext; + delete node; + return; + } + while ((node->pNext != nullptr) && (node->pNext->Key != key)) + { + node = node->pNext; + } + + if (node->pNext == nullptr) + { + throw "Element not found"; + } + Node*node1 = node->pNext; + node->pNext = node1->pNext; + delete node1; + +}; +template +Node* List::search(Tkey key) +{ + if (root == nullptr) return; + Node*node = root; + while ((node->pNext != nullptr) && (node->pNext->key != key)) + { + node = node->pNext; + } + if (node->pNext == nullptr) + { + throw "Element not found"; + } + + return node->pNext; +}; + +template +Node* List::GetRoot() +{ + return root; +}; + +template +int List::Size()const +{ + Node*node = root; + int count = 0; + while (node != nullptr) + { + node = node->pNext; + count++; + } + return count; +}; + +template +List::List(const List& a) +{ + root = new Node; + Node*copy = root;//указатель для элементов нового списка + Node*node = a->GetRoot();//указатель для элементов старого списка + while (node->pNext != nullptr) + { + copy->Key = node->Key; + copy->pNext = new Node; + copy = copy->pNext; + node = node->pNext; + } + copy->Key = node->Key; + copy->pNext = new Node; + copy->pNext = nullptr; +}; diff --git a/lab1/include/Node.h b/lab1/include/Node.h new file mode 100644 index 000000000..13f12cc30 --- /dev/null +++ b/lab1/include/Node.h @@ -0,0 +1,8 @@ +#pragma once +template +class Node +{ +public: + Tkey Key; + Node*pNext; +}; \ No newline at end of file diff --git a/lab1/include/Stack.h b/lab1/include/Stack.h new file mode 100644 index 000000000..a768376f1 --- /dev/null +++ b/lab1/include/Stack.h @@ -0,0 +1,109 @@ +#pragma once +#include +#include "List.h" + + +using namespace std; + +template +class Stack +{ +private: + List*elems; +public: + Stack();//конструктор по умолчанию + Stack(const Stack&);//конструктор копирования + ~Stack();//деструктор + void Push(Tkey a);//добавление элемента в стек + Tkey Pop();//изъятие элемента из стека + bool IsFull()const;//проверка стека на полноту + bool IsEmpty()const;//проверка стека на пустоту + int Size()const;//количество элементов в стеке + Tkey checktop();//возвращает значение верхнего элемента + List* GetList();//доступ к elems +}; + + + +template +List* Stack::GetList() +{ + return elems; +} + +template +int Stack::Size()const +{ + return elems->Size(); +}; + +template +Tkey Stack::checktop() +{ + + if (IsEmpty()) + return '!'; + Tkey res = elems->GetRoot()->Key; + return res; +}; + +template +Stack::Stack() +{ + elems = new List; +}; + +template +Stack::~Stack() +{ + elems->~List(); +}; +template +bool Stack::IsEmpty()const +{ + return (elems->Size() == 0); +} + + +template +bool Stack::IsFull()const +{ + Tkey Key = 1; + try + { + elems->insertbegin(Key); + elems->remove(Key); + } + catch (...) + { + return true; + } + return false; + +}; + +template +void Stack::Push(Tkey a) +{ + if (IsFull()) { + throw "Stack is full"; + } + elems->insertbegin(a); +} + +template +Tkey Stack::Pop() +{ + if (IsEmpty()) + throw "Stack is empty"; + Tkey Key = elems->GetRoot()->Key; + elems->remove(Key); + return Key; +}; + +template +Stack::Stack(const Stack& a) +{ + elems = new List; + elems(a->GetList()); +}; \ No newline at end of file diff --git a/lab1/include/funcs.h b/lab1/include/funcs.h new file mode 100644 index 000000000..8cd7de434 --- /dev/null +++ b/lab1/include/funcs.h @@ -0,0 +1,14 @@ +#pragma once +#include +#include"Stack.h" +#include +using namespace std; +class funcs { +private: + static int checkpriority(char);//проверка приоритета у символа + static map readvalue(string);//формирование контейнера типа map,где ключ-символ операнда,a значение-значение операнда +public: + static void calculate(string);//подсчет арифметического выражения + static string postfixform(string);//перевод в постфиксную форму + static bool checkcorrectness(string);//проверка строки на корректность +}; \ No newline at end of file diff --git a/lab1/sample/main.cpp b/lab1/sample/main.cpp new file mode 100644 index 000000000..5693a7f2a --- /dev/null +++ b/lab1/sample/main.cpp @@ -0,0 +1,28 @@ +#include +#include +#include +#include +#include + +using namespace std; +int main() +{ + setlocale(LC_ALL, "Russian"); + string string; + try { + getline(cin, string); + while (!funcs::checkcorrectness(string)) + { + cout << "Повторите ввод"; + getline(cin, string); + } + string=funcs::postfixform(string); + cout << "Постфиксная форма:" << string << endl; + funcs::calculate(string); + } + catch (const char* ex) + { + cout << ex << endl; + } + +} \ No newline at end of file diff --git "a/lab1/\320\276\321\202\321\207\320\265\321\202.doc" "b/lab1/\320\276\321\202\321\207\320\265\321\202.doc" new file mode 100644 index 000000000..ff45ee5fb Binary files /dev/null and "b/lab1/\320\276\321\202\321\207\320\265\321\202.doc" differ diff --git a/lab2/include/Algorithms.h b/lab2/include/Algorithms.h new file mode 100644 index 000000000..966950282 --- /dev/null +++ b/lab2/include/Algorithms.h @@ -0,0 +1,149 @@ +#pragma once +#include"Graph.h" +#include"PQueue.h" +#include"Dheap.h" +#include"DisjointSet.h" +#include"DQueue.h" + +struct Vertex +{ + int index = 0; + double dist = 0; + int up = -1; + double weight; + Vertex(){} + Vertex(int index, double dist, int up) + { + this->dist = dist; + this->up = up; + this->index = index; + weight = dist; + } + + bool operator<(const Vertex& p) const + { + return dist < p.dist; + } +}; + + +template +class Algorithms { +public: + static Graph* Kruskal(Graph&gr, PQueue& queue); + static void Sort(T*arr, int n, int d); + static vector deikstra(Graph *graph, int s, PQueue* queue); +}; + +template +Graph* Algorithms::Kruskal(Graph& gr, PQueue& queue) +{ + int n = gr.getsize(); + int m = gr.getrealsize(); + Graph* tree=new Graph(n, m); + DisjointSet *set = new DisjointSet(n); + for (int i = 0; imakesets(i); + + for (int i = 0; igetrealsize() < n - 1) && (!queue.IsEmpty())) + { + tmp = queue.checktop(); + queue.pop(); + + int u = tmp.begin; + int v = tmp.end; + int weight = tmp.weight; + + int An = set->findsets(u); + int Ak = set->findsets(v); + if (An != Ak) + { + set->unionsets(An, Ak); + tree->insert(u, v, weight); + + } + + } + + return tree; +} + + +template +void Algorithms::Sort(T*arr, int n, int d) +{ + PArr* data=new PArr[n]; + for (int i = 0; i < n; i++) + { + data[i].weight = arr[i]; + } + Dheap> heap(data,n,d); + heap.hilling(); + for (int i = 0; i < n; i++) + { + arr[i] = heap.checktop().weight; + heap.remove(0); + } +} + + + +vector Algorithms::deikstra(Graph *graph, int s, PQueue* queue) +{ + int m = graph->getrealsize(); + int n = graph->getVerticesNum(); + if ((s < 0) || (s >= n)) + throw "Invalid start vertex!"; + vector vertex = graph->getVertices(); + vector dist = vector(n, numeric_limits::infinity()); + vector up = vector(n, -1); + + vector> matrix = vector>(n); + for (int i = 0; i < n; i++) { + matrix[i] = vector(n, -1.0); + } + Edge*Edges = graph->getEdges(); + for (int i = 0; i < m; i++) + { + matrix[Edges[i].begin][Edges[i].end] = Edges[i].weight; + matrix[Edges[i].end][Edges[i].begin] = Edges[i].weight; + } + dist[s] = 0; + queue->push(Vertex(s, dist[s], up[s])); + + while (!queue->IsEmpty()) + { + const Vertex p = queue->checktop(); + queue->pop(); + vector weight = matrix[p.index]; + for (int i = 0; i < weight.size(); i++) + { + if (weight[i] == -1) + continue; + + const double newDist = dist[p.index] + weight[i]; + if (newDist < dist[i]) + { + dist[i] = newDist; + up[i] = p.index; + queue->push(Vertex(i, dist[i], up[i])); + } + } + } + + vector result = vector(); + result.reserve(n); + for (int i = 0; i < n; i++) + { + result.push_back(Vertex(i, dist[i], up[i])); + } + return result; + +} \ No newline at end of file diff --git a/lab2/include/BQueue.h b/lab2/include/BQueue.h new file mode 100644 index 000000000..9a7cdfc5a --- /dev/null +++ b/lab2/include/BQueue.h @@ -0,0 +1,61 @@ +#pragma once +#include"PQueue.h" +#include"btree.h" + +template +class BQueue : public PQueue +{ +private: + btree *tree; +public: + BQueue(); + virtual ~BQueue() { delete tree; }; + + virtual void push(const T& a); + virtual void pop(); + virtual bool isEmpty(); + virtual T top(); + virtual int GetSize(); + int operator==(const BQueue&)const; +}; + +template +BQueue::BQueue() +{ + tree = new btree; +} + +template +void BQueue::push(const T& a) +{ + Node *tmp = new Node(a); + tree->insert(tree->root, tmp); +} +template +void BQueue::pop() +{ + tree->remove(tree->root, tree->root->key); +} +template +bool BQueue::isEmpty() +{ + return tree->getsize() == 0; +} + +template +inline T BQueue::top() +{ + return tree->root->key; +} + +template +inline int BQueue::GetSize() +{ + return tree->getsize(); +} + +template +int BQueue::operator==(const BQueue& a)const +{ + return *tree == *a.tree; +} \ No newline at end of file diff --git a/lab2/include/DHqueue.h b/lab2/include/DHqueue.h new file mode 100644 index 000000000..dc0cf36b6 --- /dev/null +++ b/lab2/include/DHqueue.h @@ -0,0 +1,32 @@ +#pragma once +#include"PriorityQueue.h" +#include"Dheap.h" +template +class DHeapBasePriorityQueue { +private: + Dheap*Dheap; +public: + DheapBasePriorityQueue(); + virtual T get(); + virtual void put(T); +}; + +template +DHeapBasePriorityQueue::DheapBasePriorityQueue() +{ + Dheap = new Dheap; +} + +template +T DHeapBasePriorityQueue::get() +{ + T res = Dheap->getlast(); + Dheap->remove(Dheap->find(res)); + return res; +} + +template +void DHeapBasePriorityQueue::put(T a) +{ + Dheap->insert(a); +} diff --git a/lab2/include/DQueue.h b/lab2/include/DQueue.h new file mode 100644 index 000000000..56d2bac9a --- /dev/null +++ b/lab2/include/DQueue.h @@ -0,0 +1,82 @@ +#pragma once +#include"PQueue.h" +#include"Dheap.h" + +using namespace std; + +template +class DQueue:public PQueue { +private: + Dheap*heap; +public: + DQueue(int); + DQueue(Dheap&); + virtual ~DQueue() {}; + void print(); + + void push(T); + void pop(); + T checktop(); + bool IsFull(); + bool IsEmpty(); + void refresh(); +}; + +template + DQueue::DQueue(int d) +{ + heap = new Dheap(d); + +} + + template +DQueue::DQueue(Dheap& a) + { + heap = new Dheap(a); + } + +template + void DQueue::print() +{ + heap->psevdoprint(); +} + +template +void DQueue::push(T elem) +{ + heap->insert(elem); +} + +template +void DQueue::pop() + +{ + if (heap->IsEmpty()) + throw"Pqueue is empty"; + heap->remove(0); +} + + template + T DQueue::checktop() + { + return heap->checktop(); + } + + template + bool DQueue::IsFull() { + if (heap->IsFull()) + throw "Pqueue is full"; + return heap->IsFull(); + + } + template + bool DQueue::IsEmpty() { + + return heap->IsEmpty(); + } + + template +void DQueue::refresh() + { + heap->hilling(); + } diff --git a/lab2/include/Dheap.h b/lab2/include/Dheap.h new file mode 100644 index 000000000..3abeb078d --- /dev/null +++ b/lab2/include/Dheap.h @@ -0,0 +1,276 @@ +#pragma once +#include"Graph.h" +#include +#define MSIZE 1000; + +template +class PArr +{public: + K weight; +}; + +template +class Dheap { +private: + int d;//арность кучи + int m;//максимальное число элементов + T* keys; + int freepos;//индекс след элемента +public: + Dheap(int); + Dheap(int,int); + Dheap(T*,int, int); + Dheap(const Dheap&); + Dheap( Graph&,int); + ~Dheap(); + + void transpose(int, int); + void dipping(int); + void surfacing(int); + void hilling(); + int find(T); + void insert(T); + void remove(int); + int min_child(int); + bool IsFull(); + bool IsEmpty(); + int getparid(int); + T checktop(); + void print(); + void psevdoprint(); +}; +template +void Dheap::print() +{ + int level = 0, tmp = 0; + while (tmp < freepos) + { + tmp += pow(d, level); + level++; + } + int k = 1, z = 0; + cout << "\t" << keys[0].weight << endl; + for (int i = 1; i < level; i++) + { + for (int j = k; (j freepos) + k = freepos; + else k += pow(d, i); + } +} +template + void Dheap::psevdoprint() +{ + for (int i=0;i + Dheap::Dheap(int d) + { + if (d < 1) + throw"wrong d"; + m = MSIZE; + this->d = d; + keys = new T[m]; + freepos = 0; + } + template + Dheap::Dheap(int _m,int _d) + { + d = _d; + m = _m; + freepos = 0; + keys = new T[_m]; +} + + template + Dheap::Dheap(T *a, int m, int d) + { + this->d = d; + this->m = m; + freepos = m; + keys = new T[m]; + for (int i = 0; i < m; i++) + { + keys[i] = a[i]; + } + } + + template + Dheap::Dheap(const Dheap&a) + { + d = a.d; + m = a.m; + keys = new T[m]; + freepos = a.freepos; + for(int i=0;i + Dheap::Dheap(Graph& Graph,int _d) + { + d = _d; + m = Graph.getsize(); + keys = new T[m]; + Edge* a = Graph.getEdges(); + for (int i = 0; i < Graph.getsize(); i++) + { + keys[i] = a[i]; + } + freepos = m; + } + + template + Dheap::~Dheap() + { + delete[] keys; + } + + template +void Dheap::transpose(int i, int p) +{ + T tmp=keys[i]; + keys[i] = keys[p]; + keys[p] = tmp; +} + +template +void Dheap::dipping(int i) +{ + int s = min_child(i); + while ((s != 0) && (keys[i].weight > keys[s].weight)) + { + transpose(i, s); + i = s; + s = min_child(i); + } +} +template +void Dheap::surfacing(int i) +{ + int p = getparid(i); + while ((i != 0) && (keys[p].weight > keys[i].weight)) + { + transpose(i, p); + i = p; + p = getparid(i); + } +} + + /*template +int Dheap::min_child(int i) +{ + int s, min_key,last; + s = i*d + 1; + if (s>= count) return 0; + else { + + min_key = keys[s].weight; + last = (i + 1)*d; + if (last >= count) last = count- 1; + for (int j = s + 1; j <= last; j++) + { + if (min_key > keys[j].weight) min_key = keys[j].weight; + s = j; + } + return s; + } +}*/ +template +int Dheap::min_child(int a) +{ + int minCh = a*d + 1; + int maxCh; + if (minCh >= freepos) return 0; + if (a*d + d < freepos - 1) + maxCh = a*d + d; + else maxCh =freepos -1; + + for (int i = minCh; i <= maxCh; i++) + { + if (keys[i].weight < keys[minCh].weight) + { + minCh = i; + } + } + return minCh; +} + + +template +void Dheap::hilling() +{ + for (int i = freepos - 1; i >= 0; i--) + { + dipping(i); + } +} + +template + int Dheap::find(T a) +{ + for (int i = 0; i < m; i++) + { + if (keys[i] == a)return i; + } + throw"Element not found"; +} + + template +void Dheap::insert(T a) +{ + if (IsFull()) + throw "Dheap is full"; + keys[freepos] = a; + freepos++; +} + +template +void Dheap::remove(int i) +{ + if (IsEmpty()) + throw"Dheap is empty"; + T tmp = keys[freepos - 1]; + keys[freepos - 1] = keys[i]; + keys[i] = tmp; + freepos--; + if ((i != 0) && (keys[i].weight< keys[getparid(i)].weight)) + surfacing(i); + else dipping(i); +} + + + +template +bool Dheap::IsFull() +{ + return (freepos == m ); +} + +template +inline bool Dheap::IsEmpty() +{ + return (freepos == 0); +} + +template +int Dheap::getparid(int i) +{ + int res = i - 1 / d; + return res; +} + +template +T Dheap::checktop() +{ + return keys[0]; +} diff --git a/lab2/include/DisjointSet.h b/lab2/include/DisjointSet.h new file mode 100644 index 000000000..278111524 --- /dev/null +++ b/lab2/include/DisjointSet.h @@ -0,0 +1,84 @@ +#pragma once + + + +class DisjointSet +{ +private: + int *marks; + int *sizes; + int n; +public: + DisjointSet(int); + ~DisjointSet(); + + void makesets(int); + int findsets(int); + void unionsets(int, int); + +}; + + +DisjointSet::DisjointSet(int i) +{ + if (i < 0) throw "the number must be positive"; + marks = new int[i]; + for (int j = 0; j < i; j++) + { + marks[j] = -1; + } + sizes = new int[i]; + n = i; +} + + +DisjointSet::~DisjointSet() +{ + delete marks; + delete sizes; +} + +void DisjointSet::makesets(int x) +{ + if ((x > n) || (x < 0)) + throw ("out of range"); + + if (marks[x] != -1) + return; + + marks[x] = x; + sizes[x] = 1; +} + +int DisjointSet::findsets(int x) +{ + if ((x > n) || (x < 0)) + throw ("out of range"); + if (sizes[x] == -1) + return -1; + + while (marks[x] != x) + x = marks[x]; + return x; +} + +void DisjointSet::unionsets(int x, int y) +{ + if ((x > n) || (x < 0) || (y > n) || (y < 0)) + throw ("out of range"); + if ((marks[x] == -1) || (marks[y] == -1)) + throw ("Set is empty"); + + x = findsets(x); + y = findsets(y); + if (sizes[x] > sizes[y]) + marks[y] = x; + else if (sizes[x] < sizes[y]) + marks[x] = y; + else + { + marks[y] = x; + sizes[x]++; + } +} + diff --git a/lab2/include/Edge.h b/lab2/include/Edge.h new file mode 100644 index 000000000..5b6f35d64 --- /dev/null +++ b/lab2/include/Edge.h @@ -0,0 +1,42 @@ +#pragma once + + +struct Edge { + int begin; + int end; + double weight; + Edge(int, int, double); + Edge(); + + Edge& operator=(Edge&a) + { + begin = a.begin; + end = a.end; + weight = a.weight; + return *this; + } +}; + +Edge::Edge() +{ + +} + + + +Edge::Edge(int a, int b, double c) +{ + begin = a; + end = b; + weight = c; +} + + + +bool operator ==(Edge a, Edge b) +{ + if ((a.begin == b.begin) && (a.end == b.end) && (a.weight == b.weight)) + return true; + else + return false; +} diff --git a/lab2/include/Graph.h b/lab2/include/Graph.h new file mode 100644 index 000000000..d0daae109 --- /dev/null +++ b/lab2/include/Graph.h @@ -0,0 +1,199 @@ +п»ї#pragma once +#include "Edge.h" +#include +#include +#include +#include +#include + + +using namespace std; + + +class Graph { +private: + int m;//число ребер + int n;// число вершин + Edge* Edges; + int current; +public: + Graph(int, int); + Graph(Graph&); + ~Graph(); + + void insert(int, int, int); + void remove(int, int); + int findEdge(int, int); + void generate (int, int); + int getsize(); + int getrealsize(); + Edge getEdge(int); + Edge* getEdges(); + double getWeight(int, int); + void print(); + int getVerticesNum(); + vector getVertices(); +}; + + + +Graph::Graph(int _m, int _n) +{ + if (_n < 0) + throw "wrong ver num"; + else + n = _n; + if ((_m < 0)|| (_m > _n*(_n - 1) / 2)) + throw "wrong edge num"; + m = _m; + Edges = new Edge[m]; + current = 0; +} + + +Graph::Graph(Graph& a) +{ + n = a.n; + m = a.m; + Edges = new Edge[m]; + Edge* z = a.getEdges(); + for (int i = 0; i < m; i++) + { + Edges[i].begin =z[i].begin; + Edges[i].end = z[i].end; + Edges[i].weight = z[i].weight; + } +} + + +Graph::~Graph() +{ + + delete []Edges; +} + + +int Graph::getsize() +{ + return m; +} + +int Graph::getrealsize() +{ + return current; +} + + +Edge Graph::getEdge(int i) +{ + return Edges[i]; +} + + +int Graph::findEdge(int a, int b) +{ + for (int i = 0; i < current; i++) + { + if ((Edges[i].begin == a) && (Edges[i].end == b) || (Edges[i].end == a) && (Edges[i].begin == b)) + return i; + } + return -1; +} + + +void Graph::insert(int a, int b, int c) +{ + Edge newEdge(a, b, c); + if (current == m+1) + throw "graph is full"; + if (a == b) + throw "the graph must be simple"; + if ((a > n) || (b > n)) + throw ("there are no such vertices"); + + Edges[current] = newEdge; + current++; +} + + +void Graph::remove(int a, int b) +{ + int tmp = findEdge(a, b); + if (tmp == -1) + throw ("there is no such edge"); + Edges[tmp].~Edge(); + Edges[tmp] = Edges[current - 1]; + current--; +} + + +Edge* Graph:: getEdges() +{ + return Edges; +} + +double Graph::getWeight(int a, int b) +{ + return Edges[findEdge(a, b)].weight; +} + + + +void Graph::generate(int a, int b) +{ + + int u, v; + double weight; + srand(time(NULL)); + for (int i = 0; i < m; i++) + { + do + { + u = rand() % n; + v = rand() % n; + } while ((u == v) || (findEdge(u, v) != -1)); + + weight = a + (rand()) / ( (RAND_MAX / (b - a))); + Edge newEdge(u, v, weight); + Edges[i] = newEdge; + current++; + } +} + + +void Graph::print() +{ + cout << "Edges:" << endl; + for (int i = 0; i < n; i++) + { + for (int j = 0; j < current; j++) + { + if (Edges[j].begin == i) + cout << "(" << Edges[j].begin << ")---(" << Edges[j].end <<") "<< " (" << Edges[j].weight << ")" << endl; + } + } +} + +int Graph::getVerticesNum() +{ + return n; +} + +vector Graph::getVertices() +{ + vector res; + for (int i = 0; i < m; i++) + { + if (find(res.begin(), res.end(), Edges[i].begin) == res.end()) + { + res.push_back(Edges[i].begin); + } + if (find(res.begin(), res.end(), Edges[i].end) == res.end()) + { + res.push_back(Edges[i].end); + } + } + + + return res; +} diff --git a/lab2/include/Node.h b/lab2/include/Node.h new file mode 100644 index 000000000..708fc2ffe --- /dev/null +++ b/lab2/include/Node.h @@ -0,0 +1,12 @@ +#pragma once +template +class Node +{ +public: + T key; + Node *pleft; + Node *pright; + Node *pparent; + Node() { left = nullptr; right = nullptr; parent = nullptr; }; + Node(const T& k) { key = k; left = nullptr; right = nullptr; parent = nullptr; }; +}; \ No newline at end of file diff --git a/lab2/include/PQueue.h b/lab2/include/PQueue.h new file mode 100644 index 000000000..2e6f92ed8 --- /dev/null +++ b/lab2/include/PQueue.h @@ -0,0 +1,18 @@ +#pragma once +#include"Edge.h" +template +class PQueue +{ +public: + PQueue() {}; + + virtual void pop()=0; + virtual void push(T)=0; + virtual T checktop() = 0; + virtual void refresh() = 0; + + virtual bool IsFull()=0; + virtual bool IsEmpty()=0; + + +}; \ No newline at end of file diff --git a/lab2/include/btree.h b/lab2/include/btree.h new file mode 100644 index 000000000..9b0f39252 --- /dev/null +++ b/lab2/include/btree.h @@ -0,0 +1,181 @@ +#pragma once +#include "Node.h" +using namespace std; + + + +template +class btree +{ +public: + int size; + Node *root; + btree(); + ~btree(); + btree(const btree &); + + Node* CopyTree(Node *); + void insert(Node*, const Node *); + void remove(Node*, const T &); + + Node* Findkey(Node*, const T &); + Node* FindMax(Node*); + Node* FindMin(Node*); + int getsize(); + +}; + +template +btree::btree() +{ + root = nullptr; +}; + +template +btree::btree(const btree &a) +{ + root = CopyTree(a.root); +}; + +template +btree::~btree() +{ + delete root; +}; + +template +Node* btree::CopyTree(Node*croot) +{ + if (croot == nullptr) + return nullptr; + + Node* l = CopyTree(croot->left); + Node* r = CopyTree(croot->right); + Node* tree = new Node; + tree->key = croot->key; + tree->left = l; + tree->right = r; + root = tree; + return tree; +}; + +template +int btree::getSize() +{ + return size; +} + +template +void btree::insert(Node* tree, const Node *node) +{ + T a = node->key; + if (tree == nullptr) + { + tree = new Node; + tree->key = a; + size++; + return; + } + Node* tmp = tree; + Node* prev = new Node; + while (tmp != nullptr) + { + prev = tmp; + if (tmp->key <= a) + tmp = tmp->right; + else + tmp = tmp->left; + } + if (prev->key <= a) + prev->right = new Node(a); + else prev->left = new Node(a); + size++; +}; + +template +void btree::remove(Node* tree, const T &k) +{ + Node* x = Findkey(tree, k); + if (x == nullptr) + return; + + if ((x->left == nullptr) && (x->right == nullptr)) + { + delete x; + return; + }; + if ((x->left == nullptr) && (x->right != nullptr)) + { + Node* y = x->right; + y->parent = x->parent; + if (x->parent == nullptr) + { + tree = y; + return; + } + if (x->parent->right == x) + x->parent->right = y; + else + x->parent->left = y; + tree = y; + return; + } + if ((x->left != nullptr) && (x->right == nullptr)) + { + Node* y = x->left; + y->parent = x->parent; + if (x->parent->right == x) + x->parent->right = y; + else + x->parent->left = y; + delete x; + return; + } + Node* y = FindMin(x->right); + x->key = y->key; + y->parent->left = y->right; + if (y->right != nullptr) + y->right->parent = y->parent; + delete y; +}; + +template +Node* btree::Findkey(Node *tree, const T &k) +{ + while ((tree != nullptr) && (tree->key != k)) + { + if (k < tree->key) + tree = tree->left; + if (k > tree->key) + tree = tree->right; + } + if (tree == nullptr) + return nullptr; + return tree; +}; + +template +Node*btree::FindMin(Node *tree) +{ + if (tree == nullptr) + throw "Tree is empty" + while (tree->left != nullptr) + tree = tree->left; + return tree; +} +template +int btree::getsize() +{ + return size; +} +; + +template +Node* btree::FindMax(Node *tree) +{ + if (tree == nullptr) + throw "Tree is empty"; + while (tree->right != nullptr) + tree = tree->right; + return tree; +}; diff --git a/lab2/samples/Deikstra.cpp b/lab2/samples/Deikstra.cpp new file mode 100644 index 000000000..2d9ca23a6 --- /dev/null +++ b/lab2/samples/Deikstra.cpp @@ -0,0 +1,26 @@ +#include"Algorithms.h" +#include + +using namespace std; + +int main() +{ + int n, m,s,d; + vector result; + cout << "Vvedite kol-vo vershin grafa i kol-vo reber" << endl; + cin >> n >> m; + cout << "Vvedite arnost D-heap" << endl; + cin >> d; + DQueue* queue = new DQueue(d); + Graph* graph=new Graph(m, n); + graph->generate(1, 30); + graph->print(); + cout << "Vvedite nomer startovoi vershini" << endl; + cin >> s; + result = Algorithms::deikstra(graph, s, queue); + for (int i = 0; i < result.size(); i++) + { + cout << "Vertex:" << result[i].index << " Dist:" << result[i].dist << " Up:" << result[i].up << endl; + } + +} \ No newline at end of file diff --git a/lab2/samples/Kruskal.cpp b/lab2/samples/Kruskal.cpp new file mode 100644 index 000000000..0e9e76b73 --- /dev/null +++ b/lab2/samples/Kruskal.cpp @@ -0,0 +1,24 @@ +#include"Algorithms.h" +#include +using namespace std; +int main() +{ + try { + int n, m, d; + cout << "Vvedite kol-vo vershin grafa i kol-vo reber" << endl; + cin >> n >> m; + Graph graph(m, n); + graph.generate(1, 30); + graph.print(); + cout << "Vvedite arnost D-heap" << endl; + cin >> d; + DQueue queue(d); + Graph* ResGraph = Algorithms::Kruskal(graph, queue); + cout << "polucheniy graph" << endl; + ResGraph->print(); + } + catch (const char*ex) + { + cout << endl< +using namespace std; + +int main() { + double* Array=new double[10]; + cout << "Fill array" << endl; + for (int i = 0; i < 10; i++) + { + cin >> Array[i]; + } + Algorithms::Sort(Array, 10, 2); + cout<< "Sorted array:" << endl; + for (int i = 0; i < 10; i++) + { + cout<<"Array["<