diff --git a/Algorithm Visualizer.sln b/Algorithm Visualizer.sln new file mode 100644 index 0000000..28c5bc9 --- /dev/null +++ b/Algorithm Visualizer.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29911.84 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Algorithm Visualizer", "Algorithm Visualizer\Algorithm Visualizer.vcxproj", "{43866F34-C7C2-4E2A-A1C2-655981735A94}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {43866F34-C7C2-4E2A-A1C2-655981735A94}.Debug|x64.ActiveCfg = Debug|x64 + {43866F34-C7C2-4E2A-A1C2-655981735A94}.Debug|x64.Build.0 = Debug|x64 + {43866F34-C7C2-4E2A-A1C2-655981735A94}.Debug|x86.ActiveCfg = Debug|Win32 + {43866F34-C7C2-4E2A-A1C2-655981735A94}.Debug|x86.Build.0 = Debug|Win32 + {43866F34-C7C2-4E2A-A1C2-655981735A94}.Release|x64.ActiveCfg = Release|x64 + {43866F34-C7C2-4E2A-A1C2-655981735A94}.Release|x64.Build.0 = Release|x64 + {43866F34-C7C2-4E2A-A1C2-655981735A94}.Release|x86.ActiveCfg = Release|Win32 + {43866F34-C7C2-4E2A-A1C2-655981735A94}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A7CB0499-8A75-421A-97D3-494501BF95ED} + EndGlobalSection +EndGlobal diff --git a/Algorithm Visualizer/Algorithm Visualizer.cpp b/Algorithm Visualizer/Algorithm Visualizer.cpp new file mode 100644 index 0000000..58e6bf7 --- /dev/null +++ b/Algorithm Visualizer/Algorithm Visualizer.cpp @@ -0,0 +1,12 @@ +// Algorithm Visualizer.cpp : This file contains the 'main' function. Program execution begins and ends there. +// + +#include "Common.h" + +// Driver program to test above functions +int main() +{ + FreeConsole(); + Render::RenderThread(); + return 0; +} \ No newline at end of file diff --git a/Algorithm Visualizer/Algorithm Visualizer.vcxproj b/Algorithm Visualizer/Algorithm Visualizer.vcxproj new file mode 100644 index 0000000..286caa8 --- /dev/null +++ b/Algorithm Visualizer/Algorithm Visualizer.vcxproj @@ -0,0 +1,191 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {43866F34-C7C2-4E2A-A1C2-655981735A94} + Win32Proj + AlgorithmVisualizer + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ./imgui-master;./imgui-master/examples;%(AdditionalIncludeDirectories); + + + Console + true + $(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories) + Shell32.lib;oleaut32.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + + + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + + + Level3 + true + true + true + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ./imgui-master;./imgui-master/examples;%(AdditionalIncludeDirectories); + + + Console + true + true + true + $(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories) + Shell32.lib;oleaut32.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + + + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ./imgui-master;./imgui-master/examples;%(AdditionalIncludeDirectories); + + + Console + true + true + true + Shell32.lib;oleaut32.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + $(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Algorithm Visualizer/Algorithm Visualizer.vcxproj.filters b/Algorithm Visualizer/Algorithm Visualizer.vcxproj.filters new file mode 100644 index 0000000..7311df2 --- /dev/null +++ b/Algorithm Visualizer/Algorithm Visualizer.vcxproj.filters @@ -0,0 +1,114 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {951d43c5-e2e0-4af0-8cea-e352ddb4318f} + + + {d6263eef-12c2-4b7e-bddd-a2ce2cc5db81} + + + {e41daa50-de79-4f68-b72b-2dd2a6c193d5} + + + {bab07a45-18df-4dc5-a416-b2b38a8d4fee} + + + {8394abc1-96d7-4aeb-beff-e393415e7df1} + + + + + Source Files + + + Source Files\ImGui + + + Source Files\ImGui + + + Source Files\ImGui + + + Source Files\ImGui + + + Source Files\ImGui + + + Source Files\ImGui + + + Source Files\Render + + + Source Files\Algorithm + + + Source Files\Algorithm + + + Source Files\Algorithm + + + Source Files\Algorithm + + + Source Files\Algorithm + + + Source Files\Algorithm + + + Source Files\Algorithm + + + Source Files\Algorithm + + + + + Header Files\Render + + + Header Files + + + Header Files\Algorithm + + + Header Files\Algorithm + + + Header Files\Algorithm + + + Header Files\Algorithm + + + Header Files\Algorithm + + + Header Files\Algorithm + + + Header Files\Algorithm + + + Header Files\Algorithm + + + \ No newline at end of file diff --git a/Algorithm Visualizer/Algorithm Visualizer.vcxproj.user b/Algorithm Visualizer/Algorithm Visualizer.vcxproj.user new file mode 100644 index 0000000..0f14913 --- /dev/null +++ b/Algorithm Visualizer/Algorithm Visualizer.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Algorithm Visualizer/Bubble Sort.cpp b/Algorithm Visualizer/Bubble Sort.cpp new file mode 100644 index 0000000..424a00d --- /dev/null +++ b/Algorithm Visualizer/Bubble Sort.cpp @@ -0,0 +1,41 @@ +#include "Bubble Sort.h" + +namespace BubbleSort +{ + // https://www.geeksforgeeks.org/bubble-sort/ + void swap(float* xp, float* yp) + { + float temp = *xp; + *xp = *yp; + *yp = temp; + } + + void ThreadBubbleSort(LPVOID pOptions) + { + float* arr = reinterpret_cast(pOptions); + int n = 100; + + int i, j; + for (i = 0; i < n - 1; i++) + { + // Last i elements are already in place + for (j = 0; j < n - i - 1; j++) + { + if (arr[j] > arr[j + 1]) + { + Render::SelectedChange = j; + Render::SelectedChange2 = j + 1; + + swap(&arr[j], &arr[j + 1]); + + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness)); + } + } + } + + Render::SelectedChange = -1; + Render::SelectedChange2 = -1; + + Render::Status = false; + } +} \ No newline at end of file diff --git a/Algorithm Visualizer/Bubble Sort.h b/Algorithm Visualizer/Bubble Sort.h new file mode 100644 index 0000000..24fe868 --- /dev/null +++ b/Algorithm Visualizer/Bubble Sort.h @@ -0,0 +1,7 @@ +#pragma once +#include "Common.h" + +namespace BubbleSort +{ + extern void ThreadBubbleSort(LPVOID pOptions); +} \ No newline at end of file diff --git a/Algorithm Visualizer/Common.h b/Algorithm Visualizer/Common.h new file mode 100644 index 0000000..18fd66c --- /dev/null +++ b/Algorithm Visualizer/Common.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "imgui.h" +#include "imgui_impl_win32.h" +#include "imgui_impl_dx11.h" + +#include "Render.h" + +#include "Quick Sort.h" +#include "Bubble Sort.h" +#include "Selection Sort.h" +#include "Merge Sort.h" +#include "Heap Sort.h" +#include "Radix Sort.h" +#include "Counting Sort.h" +#include "Shell Sort.h" \ No newline at end of file diff --git a/Algorithm Visualizer/Counting Sort.cpp b/Algorithm Visualizer/Counting Sort.cpp new file mode 100644 index 0000000..79e09de --- /dev/null +++ b/Algorithm Visualizer/Counting Sort.cpp @@ -0,0 +1,78 @@ +#include "Counting Sort.h" + +namespace CountingSort +{ + // Counting sort in C++ programming + +#include + using namespace std; + + void countSort(float array[], int size) + { + // The size of count must be at least the (max+1) but + // we cannot assign declare it as int count(max+1) in C++ as + // it does not support dynamic memory allocation. + // So, its size is provided statically. + int output[100]; + int count[100]; + int max = array[0]; + for (int i = 1; i < size; i++) + { + if (array[i] > max) + max = array[i]; + } + + for (int i = 0; i <= max; ++i) + { + count[i] = 0; + } + + for (int i = 0; i < size; i++) + { + Render::SelectedChange = i; + Render::SelectedChange2 = i; + + count[(int)array[i]]++; + + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness / 4)); + } + for (int i = 1; i <= max; i++) + { + Render::SelectedChange = i; + Render::SelectedChange2 = i; + + count[i] += count[i - 1]; + + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness / 4)); + } + for (int i = size - 1; i >= 0; i--) + { + Render::SelectedChange = i; + Render::SelectedChange2 = i; + + output[count[(int)array[i]] - 1] = array[i]; + count[(int)array[i]]--; + + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness / 4)); + } + for (int i = 0; i < size; i++) + { + Render::SelectedChange = i; + Render::SelectedChange2 = i; + array[i] = output[i]; + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness / 4)); + } + } + + void ThreadCountingSort(LPVOID pOptions) + { + float* arr = reinterpret_cast(pOptions); + + countSort(arr, 100); + + Render::SelectedChange = -1; + Render::SelectedChange2 = -1; + + Render::Status = false; + } +} \ No newline at end of file diff --git a/Algorithm Visualizer/Counting Sort.h b/Algorithm Visualizer/Counting Sort.h new file mode 100644 index 0000000..82890d5 --- /dev/null +++ b/Algorithm Visualizer/Counting Sort.h @@ -0,0 +1,7 @@ +#pragma once +#include "Common.h" + +namespace CountingSort +{ + void ThreadCountingSort(LPVOID pOptions); +} \ No newline at end of file diff --git a/Algorithm Visualizer/Heap Sort.cpp b/Algorithm Visualizer/Heap Sort.cpp new file mode 100644 index 0000000..5226870 --- /dev/null +++ b/Algorithm Visualizer/Heap Sort.cpp @@ -0,0 +1,70 @@ +#include "Heap Sort.h" + +namespace HeapSort +{ + void heapify(float arr[], int n, int i) + { + int largest = i; // Initialize largest as root + int l = 2 * i + 1; // left = 2*i + 1 + int r = 2 * i + 2; // right = 2*i + 2 + + // If left child is larger than root + if (l < n && arr[l] > arr[largest]) + largest = l; + + // If right child is larger than largest so far + if (r < n && arr[r] > arr[largest]) + largest = r; + + // If largest is not root + if (largest != i) + { + Render::SelectedChange = i; + Render::SelectedChange2 = largest; + + float temp = arr[i]; + arr[i] = arr[largest]; + arr[largest] = temp; + + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness)); + + // Recursively heapify the affected sub-tree + heapify(arr, n, largest); + } + } + + // main function to do heap sort + void heapSort(float arr[], int n) + { + // Build heap (rearrange array) + for (int i = n / 2 - 1; i >= 0; i--) + heapify(arr, n, i); + + // One by one extract an element from heap + for (int i = n - 1; i > 0; i--) + { + Render::SelectedChange = i; + Render::SelectedChange2 = 0; + + float temp = arr[i]; + arr[i] = arr[0]; + arr[0] = temp; + + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness)); + + // call max heapify on the reduced heap + heapify(arr, i, 0); + } + } + + void ThreadHeapSort(LPVOID pOptions) + { + float* arr = reinterpret_cast(pOptions); + heapSort(arr, 100); + + Render::SelectedChange = -1; + Render::SelectedChange2 = -1; + + Render::Status = false; + } +} \ No newline at end of file diff --git a/Algorithm Visualizer/Heap Sort.h b/Algorithm Visualizer/Heap Sort.h new file mode 100644 index 0000000..c97a574 --- /dev/null +++ b/Algorithm Visualizer/Heap Sort.h @@ -0,0 +1,7 @@ +#pragma once +#include "Common.h" + +namespace HeapSort +{ + extern void ThreadHeapSort(LPVOID pOptions); +} \ No newline at end of file diff --git a/Algorithm Visualizer/Merge Sort.cpp b/Algorithm Visualizer/Merge Sort.cpp new file mode 100644 index 0000000..18be961 --- /dev/null +++ b/Algorithm Visualizer/Merge Sort.cpp @@ -0,0 +1,118 @@ +#include "Merge Sort.h" + +namespace MergeSort +{ + // https://www.geeksforgeeks.org/merge-sort/ + // Merges two subarrays of arr[]. + // First subarray is arr[l..m] + // Second subarray is arr[m+1..r] + void merge(float arr[], int l, int m, int r) + { + int i, j, k; + int n1 = m - l + 1; + int n2 = r - m; + + /* create temp arrays */ + int L[110], R[110]; + + /* Copy data to temp arrays L[] and R[] */ + for (i = 0; i < n1; i++) + { + L[i] = arr[l + i]; + Render::SelectedChange = i; + Render::SelectedChange2 = l + i; + + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness / 4)); + } + for (j = 0; j < n2; j++) + { + R[j] = arr[m + 1 + j]; + Render::SelectedChange = j; + Render::SelectedChange2 = m + 1 + j; + + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness / 4)); + } + + /* Merge the temp arrays back into arr[l..r]*/ + i = 0; // Initial index of first subarray + j = 0; // Initial index of second subarray + k = l; // Initial index of merged subarray + while (i < n1 && j < n2) + { + if (L[i] <= R[j]) + { + arr[k] = L[i]; + Render::SelectedChange = k; + Render::SelectedChange2 = i; + + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness / 4)); + i++; + } + else + { + arr[k] = R[j]; + Render::SelectedChange = k; + Render::SelectedChange2 = j; + + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness / 4)); + j++; + } + k++; + } + + /* Copy the remaining elements of L[], if there + are any */ + while (i < n1) + { + arr[k] = L[i]; + Render::SelectedChange = i; + Render::SelectedChange2 = k; + + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness / 4)); + i++; + k++; + } + + /* Copy the remaining elements of R[], if there + are any */ + while (j < n2) + { + arr[k] = R[j]; + Render::SelectedChange = k; + Render::SelectedChange2 = j; + + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness / 4)); + j++; + k++; + } + } + + void mergeSort(float arr[], int l, int r) + { + if (l < r) + { + // Same as (l+r)/2, but avoids overflow for + // large l and h + int m = l + (r - l) / 2; + + // Sort first and second halves + mergeSort(arr, l, m); + mergeSort(arr, m + 1, r); + + merge(arr, l, m, r); + } + } + + /* l is for left index and r is right index of the + sub-array of arr to be sorted */ + void ThreadMergeSort(LPVOID pOptions) + { + float* arr = reinterpret_cast(pOptions); + mergeSort(arr, 0, 99); + + Render::SelectedChange = -1; + Render::SelectedChange2 = -1; + + Render::Status = false; + } +} \ No newline at end of file diff --git a/Algorithm Visualizer/Merge Sort.h b/Algorithm Visualizer/Merge Sort.h new file mode 100644 index 0000000..301f681 --- /dev/null +++ b/Algorithm Visualizer/Merge Sort.h @@ -0,0 +1,7 @@ +#pragma once +#include "Common.h" + +namespace MergeSort +{ + extern void ThreadMergeSort(LPVOID pOptions); +} \ No newline at end of file diff --git a/Algorithm Visualizer/Quick Sort.cpp b/Algorithm Visualizer/Quick Sort.cpp new file mode 100644 index 0000000..fa4d11e --- /dev/null +++ b/Algorithm Visualizer/Quick Sort.cpp @@ -0,0 +1,74 @@ +#include "Quick Sort.h" + +namespace QuickSort +{ + //https://www.geeksforgeeks.org/cpp-program-for-quicksort/ + /* This function takes last element as pivot, places + the pivot element at its correct position in sorted + array, and places all smaller (smaller than pivot) + to left of pivot and all greater elements to right + of pivot */ + int partition(float arr[], int low, int high) + { + int pivot = arr[high]; // pivot + int i = (low - 1); // Index of smaller element + + for (int j = low; j <= high - 1; j++) + { + // If current element is smaller than or + // equal to pivot + if (arr[j] <= pivot) + { + i++; // increment index of smaller element + + Render::SelectedChange = i; + Render::SelectedChange2 = j; + + float temp = arr[j]; + arr[j] = arr[i]; + arr[i] = temp; + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness)); + } + } + + Render::SelectedChange = i + 1; + Render::SelectedChange2 = high; + + float temp = arr[high]; + arr[high] = arr[i + 1]; + arr[i + 1] = temp; + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness)); + return (i + 1); + } + + /* The main function that implements QuickSort + arr[] --> Array to be sorted, + low --> Starting index, + high --> Ending index */ + void quickSort(float arr[], int low, int high) + { + if (low < high) + { + /* pi is partitioning index, arr[p] is now + at right place */ + int pi = partition(arr, low, high); + + // Separately sort elements before + // partition and after partition + quickSort(arr, low, pi - 1); + quickSort(arr, pi + 1, high); + } + //std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + + void ThreadQuickSort(LPVOID pOptions) + { + float* buf2 = reinterpret_cast(pOptions); + quickSort(buf2, 0, 99); + + Render::SelectedChange = -1; + Render::SelectedChange2 = -1; + + Render::Status = false; + } +} \ No newline at end of file diff --git a/Algorithm Visualizer/Quick Sort.h b/Algorithm Visualizer/Quick Sort.h new file mode 100644 index 0000000..fcfbda9 --- /dev/null +++ b/Algorithm Visualizer/Quick Sort.h @@ -0,0 +1,7 @@ +#pragma once +#include "Common.h" + +namespace QuickSort +{ + extern void ThreadQuickSort(LPVOID pOptions); +} \ No newline at end of file diff --git a/Algorithm Visualizer/Radix Sort.cpp b/Algorithm Visualizer/Radix Sort.cpp new file mode 100644 index 0000000..3b46d7b --- /dev/null +++ b/Algorithm Visualizer/Radix Sort.cpp @@ -0,0 +1,73 @@ +#include "Radix Sort.h" + +namespace RadixSort +{ + int getMax(float arr[], int n) + { + int mx = arr[0]; + for (int i = 1; i < n; i++) + if (arr[i] > mx) + mx = arr[i]; + return mx; + } + + // A function to do counting sort of arr[] according to + // the digit represented by exp. + void countSort(float arr[], int n, int exp) + { + float output[110]; // output array + int i, count[10] = { 0 }; + + // Store count of occurrences in count[] + for (i = 0; i < n; i++) + count[((int)arr[i] / exp) % 10]++; + + // Change count[i] so that count[i] now contains actual + // position of this digit in output[] + for (i = 1; i < 10; i++) + count[i] += count[i - 1]; + + // Build the output array + for (i = n - 1; i >= 0; i--) + { + output[count[((int)arr[i] / exp) % 10] - 1] = arr[i]; + count[((int)arr[i] / exp) % 10]--; + Render::SelectedChange2 = i; + } + + // Copy the output array to arr[], so that arr[] now + // contains sorted numbers according to current digit + for (i = 0; i < n; i++) + { + arr[i] = output[i]; + + // Not much to show since it already stores it in a different array. + Render::SelectedChange = i; + Render::SelectedChange2 = i; + + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness)); + } + } + + // The main function to that sorts arr[] of size n using + // Radix Sort + void ThreadRadixSort(LPVOID pOptions) + { + float* arr = reinterpret_cast(pOptions); + int n = 100; + + // Find the maximum number to know number of digits + int m = getMax(arr, n); + + // Do counting sort for every digit. Note that instead + // of passing digit number, exp is passed. exp is 10^i + // where i is current digit number + for (int exp = 1; m / exp > 0; exp *= 10) + countSort(arr, n, exp); + + Render::SelectedChange = -1; + Render::SelectedChange2 = -1; + + Render::Status = false; + } +} \ No newline at end of file diff --git a/Algorithm Visualizer/Radix Sort.h b/Algorithm Visualizer/Radix Sort.h new file mode 100644 index 0000000..ad83ae4 --- /dev/null +++ b/Algorithm Visualizer/Radix Sort.h @@ -0,0 +1,7 @@ +#pragma once +#include "Common.h" + +namespace RadixSort +{ + void ThreadRadixSort(LPVOID pOptions); +} \ No newline at end of file diff --git a/Algorithm Visualizer/Render.cpp b/Algorithm Visualizer/Render.cpp new file mode 100644 index 0000000..9c3e946 --- /dev/null +++ b/Algorithm Visualizer/Render.cpp @@ -0,0 +1,320 @@ +#include "Render.h" + +namespace Render +{ + ID3D11Device* g_pd3dDevice = NULL; + ID3D11DeviceContext* g_pd3dDeviceContext = NULL; + IDXGISwapChain* g_pSwapChain = NULL; + ID3D11RenderTargetView* g_mainRenderTargetView = NULL; + + HANDLE hRenderThread = NULL; + DWORD RenderThreadID = NULL; + + int Length = 100; + float arr[100] = { 60 }; + + int SelectedChange = -1; + int SelectedChange2 = -1; + + bool Status = false; + int Slowness = 30; + + void RenderThread() + { + // Create application window + WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, Render::WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, L"Algorithm Visualizer", NULL }; + ::RegisterClassEx(&wc); + HWND hwnd = ::CreateWindow(wc.lpszClassName, L"Algorithm Visualizer", WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); + + // Initialize Direct3D + if (!Render::CreateDeviceD3D(hwnd)) + { + Render::CleanupDeviceD3D(); + ::UnregisterClass(wc.lpszClassName, wc.hInstance); + return; + } + + ImGuiWindowFlags window_flags = 0; + window_flags |= ImGuiWindowFlags_NoCollapse; + window_flags |= ImGuiWindowFlags_NoMove; + window_flags |= ImGuiWindowFlags_NoResize; + window_flags |= ImGuiCol_PopupBg; + + // Fill Array + for (int i = 0; i < 100; i++) + arr[i] = (i + 1); + + // Show the window + ::ShowWindow(hwnd, SW_SHOWDEFAULT); + ::UpdateWindow(hwnd); + + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + + ExtasyHostingTheme(); + + ImGui_ImplWin32_Init(hwnd); + ImGui_ImplDX11_Init(Render::g_pd3dDevice, Render::g_pd3dDeviceContext); + + MSG msg; + ZeroMemory(&msg, sizeof(msg)); + + DragAcceptFiles(hwnd, TRUE); + while (msg.message != WM_QUIT) + { + if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + continue; + } + + ImGui_ImplDX11_NewFrame(); + ImGui_ImplWin32_NewFrame(); + ImGui::NewFrame(); + + ImGui::SetNextWindowPos(ImVec2(-1, 0)); + ImGui::SetNextWindowSize(ImVec2(1267, 760)); + if (ImGui::Begin("Main", NULL, window_flags)) + { + if (ImGui::BeginChild("##Options", ImVec2(1250, 95), true)) + { + static int AlgorithmUsed = 0; + + ImGui::SetNextItemWidth(1187); + ImGui::Combo("Display Mode", &AlgorithmUsed, "Quick Sort\0Bubble Sort\0Selection Sort\0Merge Sort\0Heap Sort\0Radix Sort\0Counting Sort\0Shell Sort\0"); + + if (!Status) + { + if (ImGui::Button("Scramble", ImVec2(1230, 0))) + Scramble(); + + if (ImGui::Button("Start", ImVec2(1230, 0))) + { + switch (AlgorithmUsed) + { + case 0: + Status = true; + CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)QuickSort::ThreadQuickSort, (LPVOID)arr, NULL, NULL); + break; + case 1: + Status = true; + CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)BubbleSort::ThreadBubbleSort, (LPVOID)arr, NULL, NULL); + break; + case 2: + Status = true; + CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)SelectionSort::ThreadSelectionSort, (LPVOID)arr, NULL, NULL); + break; + case 3: + Status = true; + CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)MergeSort::ThreadMergeSort, (LPVOID)arr, NULL, NULL); + break; + case 4: + Status = true; + CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)HeapSort::ThreadHeapSort, (LPVOID)arr, NULL, NULL); + break; + case 5: + Status = true; + CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)RadixSort::ThreadRadixSort, (LPVOID)arr, NULL, NULL); + break; + case 6: + Status = true; + CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)CountingSort::ThreadCountingSort, (LPVOID)arr, NULL, NULL); + break; + case 7: + Status = true; + CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ShellSort::ThreadShellSort, (LPVOID)arr, NULL, NULL); + break; + default: + break; + } + } + } + ImGui::SetNextItemWidth(1180); + ImGui::SliderInt("Slowness", &Slowness, 10, 1000); + ImGui::EndChild(); + } + + ImGui::PlotHistogram("##Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0, 100, ImVec2(1250, 730 - 105), sizeof(float), SelectedChange, SelectedChange2); + ImGui::End(); + } + + + ImGui::Render(); + Render::g_pd3dDeviceContext->OMSetRenderTargets(1, &Render::g_mainRenderTargetView, NULL); + Render::g_pd3dDeviceContext->ClearRenderTargetView(Render::g_mainRenderTargetView, (float*)&ImVec4(0.45f, 0.55f, 0.60f, 1.00f)); + ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); + + Render::g_pSwapChain->Present(1, 0); + } + + ImGui_ImplDX11_Shutdown(); + ImGui_ImplWin32_Shutdown(); + ImGui::DestroyContext(); + + Render::CleanupDeviceD3D(); + ::DestroyWindow(hwnd); + ::UnregisterClass(wc.lpszClassName, wc.hInstance); + } + + void Scramble() + { + SelectedChange = -1; + SelectedChange2 = -1; + + // Re-do the array just in case + for (int i = 0; i < 100; i++) + arr[i] = (i + 1); + + srand(time(NULL)); + for (int i = 99; i > 0; i--) + { + int j = rand() % (i + 1); + + float temp = arr[j]; + arr[j] = arr[i]; + arr[i] = temp; + } + } + + bool CreateDeviceD3D(HWND hWnd) + { + // Setup swap chain + DXGI_SWAP_CHAIN_DESC sd; + ZeroMemory(&sd, sizeof(sd)); + sd.BufferCount = 2; + sd.BufferDesc.Width = 0; + sd.BufferDesc.Height = 0; + sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + sd.BufferDesc.RefreshRate.Numerator = 60; + sd.BufferDesc.RefreshRate.Denominator = 1; + sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + sd.OutputWindow = hWnd; + sd.SampleDesc.Count = 1; + sd.SampleDesc.Quality = 0; + sd.Windowed = TRUE; + sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + + UINT createDeviceFlags = 0; + //createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; + D3D_FEATURE_LEVEL featureLevel; + const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, }; + if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK) + return false; + + CreateRenderTarget(); + return true; + } + + void CleanupRenderTarget() + { + if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = NULL; } + } + + void CleanupDeviceD3D() + { + CleanupRenderTarget(); + if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = NULL; } + if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = NULL; } + if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } + } + + void CreateRenderTarget() + { + ID3D11Texture2D* pBackBuffer; + g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); + g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_mainRenderTargetView); + pBackBuffer->Release(); + } + + void ExtasyHostingTheme() + { + ImGuiStyle* style = &ImGui::GetStyle(); + + style->WindowPadding = ImVec2(6, 4); + style->WindowRounding = 0.0f; + style->FramePadding = ImVec2(5, 2); + style->FrameRounding = 8.f; + style->ItemSpacing = ImVec2(7, 3); + style->ItemInnerSpacing = ImVec2(1, 1); + style->TouchExtraPadding = ImVec2(0, 0); + style->IndentSpacing = 6.0f; + style->ScrollbarSize = 12.0f; + style->ScrollbarRounding = 16.0f; + style->GrabMinSize = 20.0f; + style->GrabRounding = 8.f; + style->ChildRounding = 8.f; + style->WindowTitleAlign.x = 0.50f; + style->FrameBorderSize = 0.0f; + style->WindowBorderSize = 1.0f; + + style->Colors[ImGuiCol_Text] = ImVec4(0.80f, 0.80f, 0.83f, 1.00f); + style->Colors[ImGuiCol_TextDisabled] = ImVec4(0.24f, 0.23f, 0.29f, 1.00f); + style->Colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.05f, 0.07f, 1.00f); + style->Colors[ImGuiCol_PopupBg] = ImVec4(0.07f, 0.07f, 0.09f, 1.00f); + style->Colors[ImGuiCol_Border] = ImVec4(0.80f, 0.80f, 0.83f, 0.88f); + style->Colors[ImGuiCol_BorderShadow] = ImVec4(0.92f, 0.91f, 0.88f, 0.00f); + style->Colors[ImGuiCol_FrameBg] = ImVec4(0.10f, 0.09f, 0.12f, 1.00f); + style->Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.24f, 0.23f, 0.29f, 1.00f); + style->Colors[ImGuiCol_FrameBgActive] = ImVec4(0.56f, 0.56f, 0.58f, 1.00f); + style->Colors[ImGuiCol_Tab] = ImVec4(0.10f, 0.09f, 0.12f, 1.00f); + style->Colors[ImGuiCol_TabActive] = ImVec4(0.20f, 0.09f, 0.22f, 1.00f); + style->Colors[ImGuiCol_TabHovered] = ImVec4(0.15f, 0.09f, 0.17f, 1.00f); + style->Colors[ImGuiCol_Tab] = ImVec4(0.10f, 0.09f, 0.12f, 1.00f); + style->Colors[ImGuiCol_TitleBg] = ImVec4(0.10f, 0.09f, 0.12f, 1.00f); + style->Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 0.98f, 0.95f, 0.75f); + style->Colors[ImGuiCol_TitleBgActive] = ImVec4(0.07f, 0.07f, 0.09f, 1.00f); + style->Colors[ImGuiCol_MenuBarBg] = ImVec4(0.10f, 0.09f, 0.12f, 1.00f); + style->Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.10f, 0.09f, 0.12f, 1.00f); + style->Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.80f, 0.80f, 0.83f, 0.31f); + style->Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.56f, 0.56f, 0.58f, 1.00f); + style->Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.06f, 0.05f, 0.07f, 1.00f); + style->Colors[ImGuiCol_CheckMark] = ImVec4(0.80f, 0.80f, 0.83f, 0.31f); + style->Colors[ImGuiCol_SliderGrab] = ImVec4(0.80f, 0.80f, 0.83f, 0.31f); + style->Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.06f, 0.05f, 0.07f, 1.00f); + style->Colors[ImGuiCol_Button] = ImVec4(0.10f, 0.09f, 0.12f, 1.00f); + style->Colors[ImGuiCol_ButtonHovered] = ImVec4(0.24f, 0.23f, 0.29f, 1.00f); + style->Colors[ImGuiCol_ButtonActive] = ImVec4(0.56f, 0.56f, 0.58f, 1.00f); + style->Colors[ImGuiCol_Header] = ImVec4(0.10f, 0.09f, 0.12f, 1.00f); + style->Colors[ImGuiCol_HeaderHovered] = ImVec4(0.56f, 0.56f, 0.58f, 1.00f); + style->Colors[ImGuiCol_HeaderActive] = ImVec4(0.06f, 0.05f, 0.07f, 1.00f); + style->Colors[ImGuiCol_ResizeGrip] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + style->Colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.56f, 0.56f, 0.58f, 1.00f); + style->Colors[ImGuiCol_ResizeGripActive] = ImVec4(0.06f, 0.05f, 0.07f, 1.00f); + style->Colors[ImGuiCol_PlotLines] = ImVec4(0.40f, 0.39f, 0.38f, 0.63f); + style->Colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.25f, 1.00f, 0.00f, 1.00f); + style->Colors[ImGuiCol_PlotHistogram] = ImVec4(0.40f, 0.39f, 0.38f, 0.63f); + style->Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(0.25f, 1.00f, 0.00f, 1.00f); + style->Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.25f, 1.00f, 0.00f, 0.43f); + style->Colors[ImGuiCol_ModalWindowDarkening] = ImVec4(1.00f, 0.98f, 0.95f, 0.73f); + } + + LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) + { + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) + return true; + + switch (msg) + { + case WM_SIZE: + if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED) + { + CleanupRenderTarget(); + g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, 0); + CreateRenderTarget(); + } + return 0; + case WM_SYSCOMMAND: + if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu + return 0; + break; + case WM_DESTROY: + exit(0); + return 0; + } + + return ::DefWindowProc(hWnd, msg, wParam, lParam); + } +} \ No newline at end of file diff --git a/Algorithm Visualizer/Render.h b/Algorithm Visualizer/Render.h new file mode 100644 index 0000000..642b52f --- /dev/null +++ b/Algorithm Visualizer/Render.h @@ -0,0 +1,32 @@ +#pragma once +#include "Common.h" + +namespace Render +{ + extern int Length; + extern float arr[100]; + + extern int SelectedChange; + extern int SelectedChange2; + + extern bool Status; + extern int Slowness; + + extern HANDLE hRenderThread; + extern DWORD RenderThreadID; + extern void RenderThread(); + extern void Scramble(); + + extern ID3D11Device* g_pd3dDevice; + extern ID3D11DeviceContext* g_pd3dDeviceContext; + extern IDXGISwapChain* g_pSwapChain; + extern ID3D11RenderTargetView* g_mainRenderTargetView; + + extern bool CreateDeviceD3D(HWND hWnd); + extern void CleanupDeviceD3D(); + extern void CreateRenderTarget(); + extern void CleanupRenderTarget(); + extern void ExtasyHostingTheme(); + extern LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +} +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); \ No newline at end of file diff --git a/Algorithm Visualizer/Selection Sort.cpp b/Algorithm Visualizer/Selection Sort.cpp new file mode 100644 index 0000000..41d84dc --- /dev/null +++ b/Algorithm Visualizer/Selection Sort.cpp @@ -0,0 +1,38 @@ +#include "Selection Sort.h" + +namespace SelectionSort +{ + // https://www.geeksforgeeks.org/selection-sort/ + void ThreadSelectionSort(LPVOID pOptions) + { + float* arr = reinterpret_cast(pOptions); + int n = 100; + + int i, j, min_idx; + + // One by one move boundary of unsorted subarray + for (i = 0; i < n - 1; i++) + { + // Find the minimum element in unsorted array + min_idx = i; + for (j = i + 1; j < n; j++) + if (arr[j] < arr[min_idx]) + min_idx = j; + + // Swap the found minimum element with the first element + Render::SelectedChange = i; + Render::SelectedChange2 = min_idx; + + float temp = arr[i]; + arr[i] = arr[min_idx]; + arr[min_idx] = temp; + + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness)); + } + + Render::SelectedChange = -1; + Render::SelectedChange2 = -1; + + Render::Status = false; + } +} \ No newline at end of file diff --git a/Algorithm Visualizer/Selection Sort.h b/Algorithm Visualizer/Selection Sort.h new file mode 100644 index 0000000..9c5cf2c --- /dev/null +++ b/Algorithm Visualizer/Selection Sort.h @@ -0,0 +1,7 @@ +#pragma once +#include "Common.h" + +namespace SelectionSort +{ + extern void ThreadSelectionSort(LPVOID pOptions); +} \ No newline at end of file diff --git a/Algorithm Visualizer/Shell Sort.cpp b/Algorithm Visualizer/Shell Sort.cpp new file mode 100644 index 0000000..2c8111c --- /dev/null +++ b/Algorithm Visualizer/Shell Sort.cpp @@ -0,0 +1,48 @@ +#include "Shell Sort.h" + +namespace ShellSort +{ + void shellSort(float arr[], int n) + { + // Start with a big gap, then reduce the gap + for (int gap = n / 2; gap > 0; gap /= 2) + { + // Do a gapped insertion sort for this gap size. + // The first gap elements a[0..gap-1] are already in gapped order + // keep adding one more element until the entire array is + // gap sorted + for (int i = gap; i < n; i += 1) + { + // add a[i] to the elements that have been gap sorted + // save a[i] in temp and make a hole at position i + int temp = arr[i]; + + // shift earlier gap-sorted elements up until the correct + // location for a[i] is found + int j; + for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) + { + arr[j] = arr[j - gap]; + Render::SelectedChange = j; + Render::SelectedChange2 = j - gap; + std::this_thread::sleep_for(std::chrono::milliseconds(Render::Slowness)); + } + + // put temp (the original a[i]) in its correct location + arr[j] = temp; + } + } + } + + void ThreadShellSort(LPVOID pOptions) + { + float* arr = reinterpret_cast(pOptions); + + shellSort(arr, 100); + + Render::SelectedChange = -1; + Render::SelectedChange2 = -1; + + Render::Status = false; + } +} \ No newline at end of file diff --git a/Algorithm Visualizer/Shell Sort.h b/Algorithm Visualizer/Shell Sort.h new file mode 100644 index 0000000..ad459cc --- /dev/null +++ b/Algorithm Visualizer/Shell Sort.h @@ -0,0 +1,7 @@ +#pragma once +#include "Common.h" + +namespace ShellSort +{ + void ThreadShellSort(LPVOID pOptions); +} \ No newline at end of file diff --git a/Algorithm Visualizer/imgui.ini b/Algorithm Visualizer/imgui.ini new file mode 100644 index 0000000..f2687df --- /dev/null +++ b/Algorithm Visualizer/imgui.ini @@ -0,0 +1,15 @@ +[Window][Debug##Default] +Pos=60,60 +Size=400,400 +Collapsed=0 + +[Window][Main] +Pos=-1,0 +Size=1267,760 +Collapsed=0 + +[Window][Dear ImGui Demo] +Pos=316,28 +Size=550,680 +Collapsed=0 + diff --git a/Algorithm Visualizer/ss/gif.gif b/Algorithm Visualizer/ss/gif.gif new file mode 100644 index 0000000..f9f2ceb Binary files /dev/null and b/Algorithm Visualizer/ss/gif.gif differ