From 2321676525704c5528838cc6d9e711d565941f5f Mon Sep 17 00:00:00 2001 From: Eugene Moskalev Date: Sat, 22 Apr 2017 19:24:17 +0300 Subject: [PATCH 1/5] Dynamic structures: List --- CMakeLists.txt | 1 + DynStructures/CMakeLists.txt | 7 ++ DynStructures/Data.cpp | 31 ++++++++ DynStructures/Data.h | 12 +++ DynStructures/List.cpp | 143 +++++++++++++++++++++++++++++++++++ DynStructures/List.h | 21 +++++ DynStructures/main.cpp | 41 ++++++++++ 7 files changed, 256 insertions(+) create mode 100644 DynStructures/CMakeLists.txt create mode 100644 DynStructures/Data.cpp create mode 100644 DynStructures/Data.h create mode 100644 DynStructures/List.cpp create mode 100644 DynStructures/List.h create mode 100644 DynStructures/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e973144..826ddd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required (VERSION 2.8) project (Examples) +add_subdirectory (DynStructures) add_subdirectory (Hello) diff --git a/DynStructures/CMakeLists.txt b/DynStructures/CMakeLists.txt new file mode 100644 index 0000000..a98b1a8 --- /dev/null +++ b/DynStructures/CMakeLists.txt @@ -0,0 +1,7 @@ +add_executable (DynStructures + Data.cpp + Data.h + List.cpp + List.h + main.cpp +) diff --git a/DynStructures/Data.cpp b/DynStructures/Data.cpp new file mode 100644 index 0000000..ec84181 --- /dev/null +++ b/DynStructures/Data.cpp @@ -0,0 +1,31 @@ +#include "Data.h" + +#include +#include +#include + +struct Data* CreateData(char const* name, int salary) +{ + struct Data* result = (struct Data*)malloc(sizeof(struct Data)); + strncpy(result->Name, name, 20); + result->Salary = salary; + return result; +} + +struct Data* ReadData() +{ + struct Data* result = (struct Data*)malloc(sizeof(struct Data)); + std::cout << "Enter name and salary" << std::endl; + std::cin >> result->Name >> result->Salary; + return result; +} + +void PrintData(struct Data* data) +{ + std::cout << "Name: " << data->Name << ", Salary: " << data->Salary << std::endl; +} + +int CompareByName(const struct Data* d1, const struct Data* d2) +{ + return strcmp(d1->Name, d2->Name); +} \ No newline at end of file diff --git a/DynStructures/Data.h b/DynStructures/Data.h new file mode 100644 index 0000000..2ba4dba --- /dev/null +++ b/DynStructures/Data.h @@ -0,0 +1,12 @@ +#pragma once + +struct Data +{ + char Name[20]; + int Salary; +}; + +struct Data* CreateData(char const* name, int salary); +struct Data* ReadData(); +void PrintData(struct Data* data); +int CompareByName(const struct Data* d1, const struct Data* d2); \ No newline at end of file diff --git a/DynStructures/List.cpp b/DynStructures/List.cpp new file mode 100644 index 0000000..5e4cf0d --- /dev/null +++ b/DynStructures/List.cpp @@ -0,0 +1,143 @@ +#include "List.h" + +#include + +struct ListNode* Create(struct Data* listData) +{ + struct ListNode* result = (struct ListNode*)malloc(sizeof(struct ListNode)); + result->ListData = listData; + result->Next = NULL; + return result; +} + +void Destroy(struct ListNode* node) +{ + while (node) + { + struct ListNode* p = node; + node = node->Next; + free(p->ListData); + free(p); + } +} + +struct ListNode* GetLastNode(struct ListNode* first) +{ + if (!first) + { + return NULL; + } + struct ListNode* p = first; + while (p->Next) + { + p = p->Next; + } + return p; +} + +struct ListNode* PushBack(struct ListNode* first, struct ListNode* newNode) +{ + newNode->Next = NULL; + struct ListNode* lastNode = GetLastNode(first); + if (lastNode) + { + lastNode->Next = newNode; + return first; + } + return newNode; +} + +struct ListNode* Insert(struct ListNode* first, struct ListNode* newNode) +{ + newNode->Next = NULL; + if (!first) + { + return newNode; + } + + struct ListNode* prev = NULL; + struct ListNode* p = first; + while (p) + { + if (CompareByName(newNode->ListData, p->ListData) < 0) + { + if (prev) + { + prev->Next = newNode; + newNode->Next = p; + return first; + } + else + { + newNode->Next = p; + return newNode; + } + } + prev = p; + p = p->Next; + } + prev->Next = newNode; + return first; +} + +struct ListNode* Remove(struct ListNode* first, struct ListNode* toDelete) +{ + struct ListNode* prev = NULL; + struct ListNode* p = first; + struct ListNode* newFirst = first; + while (p) + { + if (p == toDelete) + { + if (prev) + { + prev->Next = p->Next; + } + else + { + newFirst = p->Next; + } + p->Next = NULL; + break; + } + prev = p; + p = p->Next; + } + return newFirst; +} + +struct ListNode* Find(struct ListNode* first, DataCompareFunc compare) +{ + struct ListNode* p = first; + while (p) + { + if ((*compare)(p->ListData)) + { + return p; + } + p = p->Next; + } + return NULL; +} + +int GetCount(struct ListNode* first) +{ + int result = 0; + struct ListNode* p = first; + while (p) + { + ++result; + p = p->Next; + } + return result; +} + +void PrintList(struct ListNode* first) +{ + struct ListNode* p = first; + while (p) + { + PrintData(p->ListData); + p = p->Next; + } +} \ No newline at end of file diff --git a/DynStructures/List.h b/DynStructures/List.h new file mode 100644 index 0000000..3ea125b --- /dev/null +++ b/DynStructures/List.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Data.h" + +struct ListNode +{ + struct Data* ListData; + struct ListNode* Next; +}; + +typedef bool (*DataCompareFunc)(struct Data*); + +struct ListNode* Create(struct Data* listData); +void Destroy(struct ListNode* node); +struct ListNode* GetLastNode(struct ListNode* first); +struct ListNode* PushBack(struct ListNode* first, struct ListNode* newNode); +struct ListNode* Insert(struct ListNode* first, struct ListNode* newNode); +struct ListNode* Remove(struct ListNode* first, struct ListNode* toDelete); +struct ListNode* Find(struct ListNode* first, DataCompareFunc predicate); +int GetCount(struct ListNode* first); +void PrintList(struct ListNode* first); \ No newline at end of file diff --git a/DynStructures/main.cpp b/DynStructures/main.cpp new file mode 100644 index 0000000..da2bf37 --- /dev/null +++ b/DynStructures/main.cpp @@ -0,0 +1,41 @@ +#include "Data.h" +#include "List.h" + +#include + +bool SalaryGreaterThan500(struct Data* data) +{ + return data->Salary > 500; +} + +void TestListFunctional() +{ + struct ListNode* first = NULL; + int const count = 5; + for (int i = 0;i < count; ++i) + { + struct Data* data = ReadData(); + struct ListNode* node = Create(data); + first = Insert(first, node); + } + PrintList(first); + struct ListNode* first2 = NULL; + while (struct ListNode* found = Find(first, SalaryGreaterThan500)) + { + first = Remove(first, found); + first2 = PushBack(first2, found); + } + std::cout << "\nFirst list: " << GetCount(first) << " elements" << std::endl; + PrintList(first); + std::cout << "\nSecond list: " << GetCount(first2) << " elements" << std::endl; + PrintList(first2); + Destroy(first); + Destroy(first2); +} + +int main() +{ + TestListFunctional(); + + return 0; +} \ No newline at end of file From 38d581ca6c28d5f051a26b442de2b6f8d31ca16c Mon Sep 17 00:00:00 2001 From: Eugene Moskalev Date: Sat, 22 Apr 2017 20:21:20 +0300 Subject: [PATCH 2/5] Dynamic structures: Stack --- DynStructures/CMakeLists.txt | 2 ++ DynStructures/Stack.cpp | 60 ++++++++++++++++++++++++++++++++++++ DynStructures/Stack.h | 18 +++++++++++ DynStructures/main.cpp | 46 +++++++++++++++++++++++++-- 4 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 DynStructures/Stack.cpp create mode 100644 DynStructures/Stack.h diff --git a/DynStructures/CMakeLists.txt b/DynStructures/CMakeLists.txt index a98b1a8..157f8ce 100644 --- a/DynStructures/CMakeLists.txt +++ b/DynStructures/CMakeLists.txt @@ -4,4 +4,6 @@ add_executable (DynStructures List.cpp List.h main.cpp + Stack.cpp + Stack.h ) diff --git a/DynStructures/Stack.cpp b/DynStructures/Stack.cpp new file mode 100644 index 0000000..cb50ea5 --- /dev/null +++ b/DynStructures/Stack.cpp @@ -0,0 +1,60 @@ +#include "Stack.h" + +#include +#include + +struct Stack* CreateStack(unsigned int size) +{ + struct Stack* result = (struct Stack*)malloc(sizeof(Stack)); + result->bottom = (struct Data**)malloc(sizeof(struct Data*) * size); + result->size = size; + result->pos = 0; + return result; +} + +void DestroyStack(struct Stack* stack) +{ + free(stack->bottom); + free(stack); +} + +void Push(struct Stack* stack, Data* data) +{ + if (stack->pos < stack->size) + { + stack->bottom[stack->pos] = data; + ++stack->pos; + } + else + { + std::cout << "Stack is full" << std::endl; + } +} + +Data* Top(const struct Stack* stack) +{ + if (stack->pos > 0) + { + return stack->bottom[stack->pos - 1]; + } + return NULL; +} + +Data* Pop(struct Stack* stack) +{ + if (stack->pos > 0) + { + return stack->bottom[--stack->pos]; + } + return NULL; +} + +int GetCount(const struct Stack* stack) +{ + return stack->pos; +} + +bool IsEmpty(const struct Stack* stack) +{ + return stack->pos <= 0; +} \ No newline at end of file diff --git a/DynStructures/Stack.h b/DynStructures/Stack.h new file mode 100644 index 0000000..6b23f94 --- /dev/null +++ b/DynStructures/Stack.h @@ -0,0 +1,18 @@ +#pragma once + +#include "Data.h" + +struct Stack +{ + Data** bottom; + int pos; + unsigned int size; +}; + +struct Stack* CreateStack(unsigned int size); +void DestroyStack(struct Stack* stack); +void Push(struct Stack* stack, Data* data); +Data* Top(const struct Stack* stack); +Data* Pop(struct Stack* stack); +int GetCount(const struct Stack* stack); +bool IsEmpty(const struct Stack* stack); diff --git a/DynStructures/main.cpp b/DynStructures/main.cpp index da2bf37..1d30563 100644 --- a/DynStructures/main.cpp +++ b/DynStructures/main.cpp @@ -1,9 +1,10 @@ #include "Data.h" -#include "List.h" +//#include "List.h" +#include "Stack.h" #include -bool SalaryGreaterThan500(struct Data* data) +/* bool SalaryGreaterThan500(struct Data* data) { return data->Salary > 500; } @@ -31,11 +32,50 @@ void TestListFunctional() PrintList(first2); Destroy(first); Destroy(first2); +} */ + +void TestStackFunctional() +{ + struct Stack* stack = CreateStack(100); + int const count = 5; + for (int i = 0;i < count; ++i) + { + struct Data* data = ReadData(); + Push(stack, data); + } + std::cout << "Stack count: " << GetCount(stack) << std::endl; + std::cout << "Stack top:" << std::endl; + PrintData(Top(stack)); + std::cout << std::endl; + + struct Stack* stack2 = CreateStack(100); + while (struct Data* data = Pop(stack)) + { + if (data->Name[0] >= 'K') + { + PrintData(data); + free(data); + } + else + { + Push(stack2, data); + } + } + + std::cout << std::endl; + + while (struct Data* data = Pop(stack2)) + { + PrintData(data); + free(data); + } } int main() { - TestListFunctional(); + // TestListFunctional(); + + TestStackFunctional(); return 0; } \ No newline at end of file From 336ec8937eff562278f1270fce8bff685475d21c Mon Sep 17 00:00:00 2001 From: Eugene Moskalev Date: Sat, 22 Apr 2017 22:46:41 +0300 Subject: [PATCH 3/5] Dynamic structures: Queue --- DynStructures/CMakeLists.txt | 2 + DynStructures/Data.h | 2 + DynStructures/List.h | 2 - DynStructures/Queue.cpp | 72 ++++++++++++++++++++++++++++++++++++ DynStructures/Queue.h | 19 ++++++++++ DynStructures/main.cpp | 59 ++++++++++++++++++++++++++--- 6 files changed, 148 insertions(+), 8 deletions(-) create mode 100644 DynStructures/Queue.cpp create mode 100644 DynStructures/Queue.h diff --git a/DynStructures/CMakeLists.txt b/DynStructures/CMakeLists.txt index 157f8ce..f63ce6f 100644 --- a/DynStructures/CMakeLists.txt +++ b/DynStructures/CMakeLists.txt @@ -4,6 +4,8 @@ add_executable (DynStructures List.cpp List.h main.cpp + Queue.cpp + Queue.h Stack.cpp Stack.h ) diff --git a/DynStructures/Data.h b/DynStructures/Data.h index 2ba4dba..58222e3 100644 --- a/DynStructures/Data.h +++ b/DynStructures/Data.h @@ -6,6 +6,8 @@ struct Data int Salary; }; +typedef bool (*DataCompareFunc)(const struct Data*); + struct Data* CreateData(char const* name, int salary); struct Data* ReadData(); void PrintData(struct Data* data); diff --git a/DynStructures/List.h b/DynStructures/List.h index 3ea125b..adaa93b 100644 --- a/DynStructures/List.h +++ b/DynStructures/List.h @@ -8,8 +8,6 @@ struct ListNode struct ListNode* Next; }; -typedef bool (*DataCompareFunc)(struct Data*); - struct ListNode* Create(struct Data* listData); void Destroy(struct ListNode* node); struct ListNode* GetLastNode(struct ListNode* first); diff --git a/DynStructures/Queue.cpp b/DynStructures/Queue.cpp new file mode 100644 index 0000000..1433734 --- /dev/null +++ b/DynStructures/Queue.cpp @@ -0,0 +1,72 @@ +#include "Queue.h" + +#include +#include + +struct Queue* CreateQueue(unsigned int size) +{ + struct Queue* result = (struct Queue*)malloc(sizeof(struct Queue*)); + result->FirstChunk = (struct Data**)malloc(sizeof(struct Data*) * size); + result->SecondChunk = (struct Data**)malloc(sizeof(struct Data*) * size); + result->size = size; + result->bottom = 0; + result->top = 0; + return result; +} + +void DestroyQueue(struct Queue* queue) +{ + free(queue->FirstChunk); + free(queue->SecondChunk); + free(queue); +} + +void Push(struct Queue* queue, struct Data* data) +{ + unsigned int count = queue->top - queue->bottom; + if (count < queue->size) + { + if (queue->top >= queue->size) + { + queue->SecondChunk[queue->top % queue->size] = data; + } + else + { + queue->FirstChunk[queue->top] = data; + } + ++queue->top; + } + else + { + std::cout << "Queue is full" << std::endl; + } +} + +struct Data* Pop(struct Queue* queue) +{ + if (queue->bottom < queue->top) + { + struct Data* result = queue->FirstChunk[queue->bottom]; + ++queue->bottom; + if (queue->bottom >= queue->size) + { + struct Data** tmp = queue->FirstChunk; + queue->FirstChunk = queue->SecondChunk; + queue->SecondChunk = tmp; + queue->bottom -= queue->size; + queue->top -= queue->size; + } + return result; + } + return NULL; +} + +unsigned int GetCount(const struct Queue* queue) +{ + return queue->top - queue->bottom; +} + +bool IsEmpty(const struct Queue* queue) +{ + return queue->top <= queue->bottom; +} \ No newline at end of file diff --git a/DynStructures/Queue.h b/DynStructures/Queue.h new file mode 100644 index 0000000..cf53501 --- /dev/null +++ b/DynStructures/Queue.h @@ -0,0 +1,19 @@ +#pragma once + +#include "Data.h" + +struct Queue +{ + struct Data** FirstChunk; + struct Data** SecondChunk; + unsigned int size; + unsigned int bottom; + unsigned int top; +}; + +struct Queue* CreateQueue(unsigned int size); +void DestroyQueue(struct Queue* queue); +void Push(struct Queue* queue, struct Data* data); +struct Data* Pop(struct Queue* queue); +unsigned int GetCount(const struct Queue* queue); +bool IsEmpty(const struct Queue* queue); \ No newline at end of file diff --git a/DynStructures/main.cpp b/DynStructures/main.cpp index 1d30563..9205feb 100644 --- a/DynStructures/main.cpp +++ b/DynStructures/main.cpp @@ -1,15 +1,21 @@ #include "Data.h" //#include "List.h" -#include "Stack.h" +//#include "Stack.h" +#include "Queue.h" #include -/* bool SalaryGreaterThan500(struct Data* data) +bool SalaryGreaterThan500(const struct Data* data) { - return data->Salary > 500; + return data->Salary >= 500; } -void TestListFunctional() +bool SalaryLessThan500(const struct Data* data) +{ + return data->Salary < 500; +} + +/* void TestListFunctional() { struct ListNode* first = NULL; int const count = 5; @@ -34,7 +40,7 @@ void TestListFunctional() Destroy(first2); } */ -void TestStackFunctional() +/* void TestStackFunctional() { struct Stack* stack = CreateStack(100); int const count = 5; @@ -69,13 +75,54 @@ void TestStackFunctional() PrintData(data); free(data); } +} */ + +void HandleQueue(struct Queue* queue, DataCompareFunc predicate, int numHandler) +{ + std::cout << "Handler " << numHandler << std::endl; + int counter = GetCount(queue); + while (struct Data* data = Pop(queue)) + { + if ((*predicate)(data)) + { + PrintData(data); + free(data); + return; + } + Push(queue, data); + if (!--counter) + { + break; + } + } + std::cout << "Don't exist elements" << std::endl; +} + +void TestQueueFunctional() +{ + int const count = 5; + struct Queue* queue = CreateQueue(5); + + for (int i = 0;i < count; ++i) + { + struct Data* data = ReadData(); + Push(queue, data); + } + + while (!IsEmpty(queue)) + { + HandleQueue(queue, SalaryGreaterThan500, 1); + HandleQueue(queue, SalaryLessThan500, 2); + } } int main() { // TestListFunctional(); - TestStackFunctional(); + // TestStackFunctional(); + + TestQueueFunctional(); return 0; } \ No newline at end of file From 1f67382cce252f2938bda5aca204f34c49cdb2c1 Mon Sep 17 00:00:00 2001 From: Eugene Moskalev Date: Sun, 23 Apr 2017 00:32:41 +0300 Subject: [PATCH 4/5] Dynamic structures: Binary tree --- DynStructures/BinaryTree.cpp | 184 +++++++++++++++++++++++++++++++++++ DynStructures/BinaryTree.h | 19 ++++ DynStructures/CMakeLists.txt | 2 + 3 files changed, 205 insertions(+) create mode 100644 DynStructures/BinaryTree.cpp create mode 100644 DynStructures/BinaryTree.h diff --git a/DynStructures/BinaryTree.cpp b/DynStructures/BinaryTree.cpp new file mode 100644 index 0000000..6935b5d --- /dev/null +++ b/DynStructures/BinaryTree.cpp @@ -0,0 +1,184 @@ +#include "BinaryTree.h" + +#include +#include + +/*struct TreeNode* RecursiveTree(struct TreeNode* root, struct TreeNode* r, char data) +{ + if(!r) + { + r = (struct TreeNode*) malloc(sizeof(struct TreeNode)); + r->Left = NULL; + r->Right = NULL; + r->NodeData = data; + if(!root) + { + return r; + } + if(data < root->NodeData) + { + root->Left = r; + } + else + { + root->Right = r; + } + return r; + } + if(data < r->NodeData) + { + RecursiveTree(r, r->Left, data); + } + else + { + RecursiveTree(r, r->Right, data); + } + return root; +} + +struct TreeNode* InsertData(struct TreeNode* root, char data) +{ + return RecursiveTree(root, root, data); +} + +struct TreeNode* CreateTree(char data) +{ + return RecursiveTree(NULL, NULL, data); +} + +struct TreeNode* InsertData(struct TreeNode* root, char data) +{ + return RecursiveTree(root, root, data); +} */ + +struct TreeNode* CreateTree(char data) +{ + return InsertData(NULL, data); +} + +void DestroyTree(struct TreeNode* node) +{ + if (node) + { + DestroyTree(node->Left); + DestroyTree(node->Right); + free(node); + } +} + +struct TreeNode* InsertData(struct TreeNode* node, char data) +{ + if (!node) + { + node = (struct TreeNode*) malloc(sizeof(struct TreeNode)); + node->Left = NULL; + node->Right = NULL; + node->NodeData = data; + return node; + } + if (data < node->NodeData) + { + node->Left = InsertData(node->Left, data); + } + else + { + node->Right = InsertData(node->Right, data); + } + return node; +} + +struct TreeNode* RemoveData(struct TreeNode* node, char data) +{ + if (!node) + { + return NULL; + } + if (data < node->NodeData) + { + node->Left = RemoveData(node->Left, data); + } + else if (data > node->NodeData) + { + node->Right = RemoveData(node->Right, data); + } + else + { + struct TreeNode* left = node->Left; + struct TreeNode* right = node->Right; + free(node); + if (left) + { + node = left; + } + else + { + node = right; + } + } + return node; +} + +struct TreeNode* Find(struct TreeNode* root, char data) +{ + if (!root || data == root->NodeData) + { + return root; + } + + if (data < root->NodeData) + { + return Find(root->Left, data); + } + else + { + return Find(root->Right, data); + } +} + +struct TreeNode* Minimum(struct TreeNode* root) +{ + if (!root->Left) + { + return root; + } + return Minimum(root->Left); +} + +struct TreeNode* Maximum(struct TreeNode* root) +{ + if (!root->Right) + { + return root; + } + return Maximum(root->Right); +} + +void PrintInorder(struct TreeNode* root) +{ + if (root) + { + PrintInorder(root->Left); + std::cout << root->NodeData << ' '; + PrintInorder(root->Right); + } +} + +void PrintPreorder(struct TreeNode* root) +{ + if (root) + { + std::cout << root->NodeData << ' '; + PrintInorder(root->Left); + PrintInorder(root->Right); + } +} + +void PrintPostorder(struct TreeNode* root) +{ + if (root) + { + PrintInorder(root->Left); + PrintInorder(root->Right); + std::cout << root->NodeData << ' '; + } +} \ No newline at end of file diff --git a/DynStructures/BinaryTree.h b/DynStructures/BinaryTree.h new file mode 100644 index 0000000..5926365 --- /dev/null +++ b/DynStructures/BinaryTree.h @@ -0,0 +1,19 @@ +#pragma once + +struct TreeNode +{ + char NodeData; + struct TreeNode* Left; + struct TreeNode* Right; +}; + +struct TreeNode* CreateTree(char data); +void DestroyTree(struct TreeNode* root); +struct TreeNode* InsertData(struct TreeNode* node, char data); +struct TreeNode* RemoveData(struct TreeNode* node, char data); +struct TreeNode* Find(struct TreeNode* root, char data); +struct TreeNode* Minimum(struct TreeNode* root); +struct TreeNode* Maximum(struct TreeNode* root); +void PrintInorder(struct TreeNode* root); +void PrintPreorder(struct TreeNode* root); +void PrintPostorder(struct TreeNode* root); \ No newline at end of file diff --git a/DynStructures/CMakeLists.txt b/DynStructures/CMakeLists.txt index f63ce6f..c80dbee 100644 --- a/DynStructures/CMakeLists.txt +++ b/DynStructures/CMakeLists.txt @@ -1,4 +1,6 @@ add_executable (DynStructures + BinaryTree.cpp + BinaryTree.h Data.cpp Data.h List.cpp From 6bc897e7b40f4aee0f9ae0729ab1f32dcf535a85 Mon Sep 17 00:00:00 2001 From: Eugene Moskalev Date: Mon, 24 Apr 2017 18:47:48 +0300 Subject: [PATCH 5/5] Dynamic structures: Double linked list --- DynStructures/CMakeLists.txt | 2 + DynStructures/DoubleLinkedList.cpp | 227 +++++++++++++++++++++++++++++ DynStructures/DoubleLinkedList.h | 23 +++ DynStructures/main.cpp | 36 ++++- 4 files changed, 285 insertions(+), 3 deletions(-) create mode 100644 DynStructures/DoubleLinkedList.cpp create mode 100644 DynStructures/DoubleLinkedList.h diff --git a/DynStructures/CMakeLists.txt b/DynStructures/CMakeLists.txt index c80dbee..3ffb09f 100644 --- a/DynStructures/CMakeLists.txt +++ b/DynStructures/CMakeLists.txt @@ -3,6 +3,8 @@ add_executable (DynStructures BinaryTree.h Data.cpp Data.h + DoubleLinkedList.cpp + DoubleLinkedList.h List.cpp List.h main.cpp diff --git a/DynStructures/DoubleLinkedList.cpp b/DynStructures/DoubleLinkedList.cpp new file mode 100644 index 0000000..381d9c6 --- /dev/null +++ b/DynStructures/DoubleLinkedList.cpp @@ -0,0 +1,227 @@ +#include "DoubleLinkedList.h" + +#include + +struct List2Node* CreateDoubleLinkedList(struct Data* listData) +{ + struct List2Node* result = (struct List2Node*)malloc(sizeof(struct List2Node)); + result->ListData = listData; + result->Prev = NULL; + result->Next = NULL; + return result; +} + +void Destroy(struct List2Node* node) +{ + while (node) + { + struct List2Node* p = node; + node = node->Next; + free(p->ListData); + free(p); + } +} + +struct List2Node* GetFirstNode(struct List2Node* node) +{ + if (!node) + { + return NULL; + } + while (node->Prev) + { + node = node->Prev; + } + return node; +} + +struct List2Node* GetLastNode(struct List2Node* node) +{ + if (!node) + { + return NULL; + } + while (node->Next) + { + node = node->Next; + } + return node; +} + +struct List2Node* PushBack(struct List2Node* first, struct List2Node* newNode) +{ + newNode->Next = NULL; + if (first) + { + struct List2Node* lastNode = GetLastNode(first); + lastNode->Next = newNode; + newNode->Prev = lastNode; + } + else + { + newNode->Prev = NULL; + first = newNode; + } + return first; +} + +struct List2Node* Insert(struct List2Node* first, struct List2Node* newNode) +{ + newNode->Next = newNode->Prev = NULL; + if (!first) + { + // insert at empty list, new node become first + return newNode; + } + + struct List2Node* prev = NULL; + struct List2Node* p = first; + while (p) + { + if (CompareByName(newNode->ListData, p->ListData) < 0) + { + if (prev) + { + // update links with previous + prev->Next = newNode; + newNode->Prev = prev; + return first; + } + else + { + // new element become first + first = newNode; + } + // update links with next + newNode->Next = p; + p->Prev = newNode; + return first; + } + prev = p; + p = p->Next; + } + // insert at end, update link with previous + prev->Next = newNode; + newNode->Prev = prev; + return first; +} + +struct List2Node* Remove(struct List2Node* first, struct List2Node* toDelete) +{ + struct List2Node* prev = NULL; + struct List2Node* p = first; + struct List2Node* newFirst = first; + while (p) + { + if (p == toDelete) + { + if (p->Next) + { + // update next after removed node link + p->Next->Prev = prev; + } + if (prev) + { + // update before removed node link + prev->Next = p->Next; + } + else + { + // remove first node + newFirst = p->Next; + } + p->Prev = p->Next = NULL; + break; + } + prev = p; + p = p->Next; + } + return newFirst; +} + +struct List2Node* Find(struct List2Node* first, DataCompareFunc compare) +{ + struct List2Node* p = first; + while (p) + { + if ((*compare)(p->ListData)) + { + return p; + } + p = p->Next; + } + return NULL; +} + +void SwapData(struct List2Node* node1, struct List2Node* node2) +{ + Data* tmp = node1->ListData; + node1->ListData = node2->ListData; + node2->ListData = tmp; +} + +void ShakeForwardIteration(struct List2Node* firstNode, struct List2Node* lastNode) +{ + for (struct List2Node* curNode = firstNode; curNode != lastNode;) + { + struct List2Node* nextNode = curNode->Next; + if (CompareByName(curNode->ListData, nextNode->ListData) > 0) + { + SwapData(curNode, nextNode); + } + curNode = nextNode; + } +} + +void ShakeBackwardIteration(struct List2Node* firstNode, struct List2Node* lastNode) +{ + for (struct List2Node* curNode = lastNode; curNode != firstNode;) + { + struct List2Node* prevNode = curNode->Prev; + if (CompareByName(prevNode->ListData, curNode->ListData) > 0) + { + SwapData(prevNode, curNode); + } + curNode = prevNode; + } +} + +void ShakeSort(struct List2Node* firstNode) +{ + bool moveForward = true; + for (struct List2Node* lastNode = GetLastNode(firstNode); firstNode != lastNode; moveForward = !moveForward) + { + if (moveForward) + { + ShakeForwardIteration(firstNode, lastNode); + lastNode = lastNode->Prev; + } + else + { + ShakeBackwardIteration(firstNode, lastNode); + firstNode = firstNode->Next; + } + } +} + +int GetCount(struct List2Node* first) +{ + int result = 0; + struct List2Node* p = first; + while (p) + { + ++result; + p = p->Next; + } + return result; +} + +void PrintList(struct List2Node* first) +{ + struct List2Node* p = first; + while (p) + { + PrintData(p->ListData); + p = p->Next; + } +} \ No newline at end of file diff --git a/DynStructures/DoubleLinkedList.h b/DynStructures/DoubleLinkedList.h new file mode 100644 index 0000000..763631b --- /dev/null +++ b/DynStructures/DoubleLinkedList.h @@ -0,0 +1,23 @@ +#pragma once + +#include "Data.h" + +struct List2Node +{ + struct Data* ListData; + struct List2Node* Prev; + struct List2Node* Next; +}; + +struct List2Node* CreateDoubleLinkedList(struct Data* listData); +void Destroy(struct List2Node* node); +struct List2Node* GetFirstNode(struct List2Node* node); +struct List2Node* GetLastNode(struct List2Node* node); +struct List2Node* PushBack(struct List2Node* first, struct List2Node* newNode); +struct List2Node* Insert(struct List2Node* first, struct List2Node* newNode); +struct List2Node* Remove(struct List2Node* first, struct List2Node* toDelete); +struct List2Node* Find(struct List2Node* first, DataCompareFunc compare); +void SwapData(struct List2Node* node1, struct List2Node* node2); +void ShakeSort(struct List2Node* firstNode); +int GetCount(struct List2Node* first); +void PrintList(struct List2Node* first); \ No newline at end of file diff --git a/DynStructures/main.cpp b/DynStructures/main.cpp index 9205feb..a5ba56a 100644 --- a/DynStructures/main.cpp +++ b/DynStructures/main.cpp @@ -1,7 +1,8 @@ #include "Data.h" //#include "List.h" //#include "Stack.h" -#include "Queue.h" +//#include "Queue.h" +#include "DoubleLinkedList.h" #include @@ -77,7 +78,7 @@ bool SalaryLessThan500(const struct Data* data) } } */ -void HandleQueue(struct Queue* queue, DataCompareFunc predicate, int numHandler) +/*void HandleQueue(struct Queue* queue, DataCompareFunc predicate, int numHandler) { std::cout << "Handler " << numHandler << std::endl; int counter = GetCount(queue); @@ -114,6 +115,33 @@ void TestQueueFunctional() HandleQueue(queue, SalaryGreaterThan500, 1); HandleQueue(queue, SalaryLessThan500, 2); } +} */ + +void TestDoubleLinkedList() +{ + struct List2Node* first = NULL; + int const count = 5; + for (int i = 0;i < count; ++i) + { + struct Data* data = ReadData(); + struct List2Node* node = CreateDoubleLinkedList(data); + first = PushBack(first, node); + } + ShakeSort(first); + first = GetFirstNode(first); + PrintList(first); + struct List2Node* first2 = NULL; + while (struct List2Node* found = Find(first, SalaryLessThan500)) + { + first = Remove(first, found); + first2 = Insert(first2, found); + } + std::cout << "\nFirst list: " << GetCount(first) << " elements" << std::endl; + PrintList(first); + std::cout << "\nSecond list: " << GetCount(first2) << " elements" << std::endl; + PrintList(first2); + Destroy(first); + Destroy(first2); } int main() @@ -122,7 +150,9 @@ int main() // TestStackFunctional(); - TestQueueFunctional(); + // TestQueueFunctional(); + + TestDoubleLinkedList(); return 0; } \ No newline at end of file