From 019fc6ef46854192a30347af80581e9741f11426 Mon Sep 17 00:00:00 2001 From: memeToasty Date: Thu, 4 Aug 2022 20:03:52 +0200 Subject: [PATCH] added Heap-Sort --- source/main.cpp | 276 +++++++++++++++++++++++++++++++----------------- 1 file changed, 178 insertions(+), 98 deletions(-) diff --git a/source/main.cpp b/source/main.cpp index d2fe84c..442f336 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -8,25 +8,21 @@ #include #include -#define SCREEN_WIDTH 400 +#define SCREEN_WIDTH 400 #define SCREEN_HEIGHT 240 #define SAMPLERATE 22050 #define SAMPLESPERBUF (SAMPLERATE / 30) #define BYTESPERSAMPLE 4 - - // Input Stuff static SwkbdState swkbd; static char mybuf[10]; SwkbdButton button = SWKBD_BUTTON_NONE; u32 kDown; - const char *selector = "> "; - // Define Menus Menu *mainMenu; Menu *algoMenu; @@ -38,19 +34,20 @@ Menu *activeMenu; ndspWaveBuf waveBuf[2]; u32 *audioBuffer; -void fill_buffer(void *audioBuffer,size_t offset, size_t size, int frequency ) { +void fill_buffer(void *audioBuffer, size_t offset, size_t size, int frequency) +{ - u32 *dest = (u32*)audioBuffer; + u32 *dest = (u32 *)audioBuffer; - for (int i=0; i< (int) size; i++) { + for (int i = 0; i < (int)size; i++) + { - s16 sample = INT16_MAX * sin(frequency*(2*M_PI)*(offset+i)/SAMPLERATE); + s16 sample = INT16_MAX * sin(frequency * (2 * M_PI) * (offset + i) / SAMPLERATE); - dest[i] = (sample<<16) | (sample & 0xffff); + dest[i] = (sample << 16) | (sample & 0xffff); } - DSP_FlushDataCache(audioBuffer,size); - + DSP_FlushDataCache(audioBuffer, size); } // Main menu text @@ -77,15 +74,16 @@ int selected = 0; bool arrayUpdate = false; -unsigned int* array; +unsigned int *array; unsigned int arrayLen = 10; const unsigned int maxArrayVal = 100; unsigned int delayMs = 2; -C3D_RenderTarget* top; +C3D_RenderTarget *top; u32 bar_clr; u32 active_clr; u32 clrClear; +u32 doneClr; const size_t maxBars = 9500; // Threading vars @@ -96,52 +94,61 @@ s32 prio = 0; volatile bool doneSorting = false; volatile unsigned int activeIndex = 0; -int atoui(const char* str){ - unsigned int num = 0; - int i = 0; - while (str[i] && (str[i] >= '0' && str[i] <= '9')){ - num = num * 10 + (str[i] - '0'); - i++; - } - return num; +int atoui(const char *str) +{ + unsigned int num = 0; + int i = 0; + while (str[i] && (str[i] >= '0' && str[i] <= '9')) + { + num = num * 10 + (str[i] - '0'); + i++; + } + return num; } -void accessElement(unsigned int accessedIndex) { +void accessElement(unsigned int accessedIndex) +{ activeIndex = accessedIndex; - if (waveBuf[0].status == NDSP_WBUF_DONE) { - fill_buffer(audioBuffer,0, SAMPLESPERBUF * 2, 300 + (array[activeIndex] * 20)); + if (waveBuf[0].status == NDSP_WBUF_DONE) + { + fill_buffer(audioBuffer, 0, SAMPLESPERBUF * 2, 300 + (array[activeIndex] * 20)); ndspChnWaveBufAdd(0, &waveBuf[0]); } } - -void switchMenu(Menu* menu) +void switchMenu(Menu *menu) { selected = 0; activeMenu = menu; } -void ThreadSleep(unsigned int ms) { - svcSleepThread(1000000ULL * (u32) ms); +void ThreadSleep(unsigned int ms) +{ + svcSleepThread(1000000ULL * (u32)ms); } -void finishSorting() { - for (unsigned short i = 0; i < arrayLen; ++i) { +void finishSorting() +{ + for (unsigned short i = 0; i < arrayLen; ++i) + { accessElement(i); - ThreadSleep((unsigned int) (1000.0 / (double) arrayLen)); + ThreadSleep((unsigned int)(1000.0 / (double)arrayLen)); } } // Sorting algorithms -void swap(unsigned short index1, unsigned short index2) { +void swap(unsigned short index1, unsigned short index2) +{ unsigned int temp = array[index1]; array[index1] = array[index2]; array[index2] = temp; - } -void insertionSort(void* arg) { - for (unsigned int i = 1; i < arrayLen; i++) { +void insertionSort(void *arg) +{ + for (unsigned int i = 1; i < arrayLen; i++) + { unsigned short j = i; - while (j > 0 && array[j] < array[j-1]) { - swap(j,j-1); + while (j > 0 && array[j] < array[j - 1]) + { + swap(j, j - 1); j--; accessElement(j); ThreadSleep(delayMs); @@ -151,36 +158,95 @@ void insertionSort(void* arg) { finishSorting(); } -void merge(unsigned int p, unsigned int q, unsigned int r) { +void maxHeapify(unsigned int i, unsigned int heapSize) +{ + unsigned int left = (2 * i) + 1; + unsigned int right = (2 * i) + 2; + + accessElement(i); + ThreadSleep(delayMs); + + unsigned int largest = i; + if (left < heapSize && array[i] < array[left]) + { + largest = left; + } + + if (right < heapSize && array[largest] < array[right]) + { + largest = right; + } + if (largest != i) + { + swap(i, largest); + maxHeapify(largest, heapSize); + } +} + +void buildMaxHeap(unsigned int heapSize) +{ + for (int i = (int)(floor((double)heapSize / (double)2) + 1); i >= 0; i--) + { + printf("%i\n", i); + maxHeapify(i, heapSize); + } +} + +void heapSort(void *arg) +{ + unsigned int heapSize = arrayLen; + buildMaxHeap(heapSize); + for (unsigned int i = arrayLen - 1; i > 0; i--) + { + accessElement(i); + ThreadSleep(delayMs); + + swap(0, i); + heapSize--; + maxHeapify(0, heapSize); + } + + doneSorting = true; + finishSorting(); +} + +void merge(unsigned int p, unsigned int q, unsigned int r) +{ // Make 2 new Arrays with 1 extra space for the sentinel cards // Sizes of both arrays - unsigned int leftSize = (q-p+1)+1; - unsigned int rightSize = (r-q)+1; - unsigned int* left = (unsigned int*) malloc(leftSize * sizeof(unsigned int)); - unsigned int* right = (unsigned int*) malloc(rightSize * sizeof(unsigned int)); - + unsigned int leftSize = (q - p + 1) + 1; + unsigned int rightSize = (r - q) + 1; + unsigned int *left = (unsigned int *)malloc(leftSize * sizeof(unsigned int)); + unsigned int *right = (unsigned int *)malloc(rightSize * sizeof(unsigned int)); + // Fill arrays with respective values - for (unsigned short i = 0; i < leftSize; i++) { - left[i] = array[p+i]; + for (unsigned short i = 0; i < leftSize; i++) + { + left[i] = array[p + i]; } - for (unsigned short i = 0; i < rightSize; i++) { - right[i] = array[q+1+i]; + for (unsigned short i = 0; i < rightSize; i++) + { + right[i] = array[q + 1 + i]; } - //add sentinels - left[leftSize-1] = UINT8_MAX; - right[rightSize-1] = UINT8_MAX; + // add sentinels + left[leftSize - 1] = UINT8_MAX; + right[rightSize - 1] = UINT8_MAX; unsigned short leftHead = 0; unsigned short rightHead = 0; - for (unsigned short i = p; i <= r; i++) { + for (unsigned short i = p; i <= r; i++) + { accessElement(i); ThreadSleep(delayMs); - if (left[leftHead] < right[rightHead]) { + if (left[leftHead] < right[rightHead]) + { array[i] = left[leftHead]; leftHead++; - } else { + } + else + { array[i] = right[rightHead]; rightHead++; } @@ -189,67 +255,79 @@ void merge(unsigned int p, unsigned int q, unsigned int r) { free(left); free(right); } -void mergeSort(unsigned int p, unsigned int r) { - if (p < r) { - unsigned int q = (p+r) / 2; - mergeSort(p,q); - mergeSort(q+1,r); - merge(p,q,r); +void mergeSort(unsigned int p, unsigned int r) +{ + if (p < r) + { + unsigned int q = (p + r) / 2; + mergeSort(p, q); + mergeSort(q + 1, r); + merge(p, q, r); } } -void mergeSortInit(void* arg) { - mergeSort(0, arrayLen-1); +void mergeSortInit(void *arg) +{ + mergeSort(0, arrayLen - 1); doneSorting = true; finishSorting(); } -void drawArray() { +void drawArray() +{ C3D_FrameBegin(C3D_FRAME_SYNCDRAW); C2D_TargetClear(top, clrClear); C2D_SceneBegin(top); - const float width = (float) SCREEN_WIDTH / (float) arrayLen; - for (unsigned int i = 0; i < arrayLen; i++) { - const float height = (float) ((float) SCREEN_HEIGHT / (float) maxArrayVal) * array[i]; + const float width = (float)SCREEN_WIDTH / (float)arrayLen; + for (unsigned int i = 0; i < arrayLen; i++) + { + const float height = (float)((float)SCREEN_HEIGHT / (float)maxArrayVal) * array[i]; const float x = i * width; const float y = SCREEN_HEIGHT - height; - if (i == activeIndex) { - C2D_DrawRectSolid(x, y, 0, width, height, active_clr); - } else { + if (i == activeIndex) + { + C2D_DrawRectSolid(x, y, 0, width, height, active_clr); + } + else + { C2D_DrawRectSolid(x, y, 0, width, height, bar_clr); } - } } -void initArray() { +void initArray() +{ free(array); - array = (unsigned int*)malloc(sizeof(unsigned int) * arrayLen); - if (array == NULL) { + array = (unsigned int *)malloc(sizeof(unsigned int) * arrayLen); + if (array == NULL) + { exit(1); } - for (unsigned int i = 0; i < arrayLen; ++i) { - //array[i] = rand() % maxArrayVal; - array[i] = (unsigned int) (( (double) maxArrayVal / (double) arrayLen) * (i+1)); + for (unsigned int i = 0; i < arrayLen; ++i) + { + // array[i] = rand() % maxArrayVal; + array[i] = (unsigned int)(((double)maxArrayVal / (double)arrayLen) * (i + 1)); } - for (unsigned short i = 0; i < arrayLen; ++i) { + for (unsigned short i = 0; i < arrayLen; ++i) + { swap(rand() % arrayLen, i); } arrayUpdate = true; } -unsigned int inputNum() { +unsigned int inputNum() +{ swkbdInit(&swkbd, SWKBD_TYPE_NUMPAD, 1, 8); swkbdSetPasswordMode(&swkbd, SWKBD_PASSWORD_NONE); - swkbdSetValidation(&swkbd, SWKBD_NOTEMPTY_NOTBLANK , 0, 0); + swkbdSetValidation(&swkbd, SWKBD_NOTEMPTY_NOTBLANK, 0, 0); swkbdSetFeatures(&swkbd, SWKBD_FIXED_WIDTH); button = swkbdInputText(&swkbd, mybuf, sizeof(mybuf)); return atoui(mybuf); } void settingsMenuHandler() -{ +{ // Handle, if user pressed A if (kDown & KEY_A) { @@ -288,10 +366,13 @@ void algoMenuHandler() switch (selected) { case 0: - sortThread = threadCreate(insertionSort, NULL, STACKSIZE, prio-1, 1, false); + sortThread = threadCreate(insertionSort, NULL, STACKSIZE, prio - 1, 1, false); break; case 1: - sortThread = threadCreate(mergeSortInit, NULL, STACKSIZE, prio-1, 1, false); + sortThread = threadCreate(mergeSortInit, NULL, STACKSIZE, prio - 1, 1, false); + break; + case 2: + sortThread = threadCreate(heapSort, NULL, STACKSIZE, prio - 1, 1, false); case 3: switchMenu(mainMenu); break; @@ -338,9 +419,8 @@ int main(int argc, char *argv[]) C2D_Prepare(); consoleInit(GFX_BOTTOM, NULL); - // Initialize sounds - audioBuffer = (u32*)linearAlloc(SAMPLESPERBUF*BYTESPERSAMPLE*2); + audioBuffer = (u32 *)linearAlloc(SAMPLESPERBUF * BYTESPERSAMPLE * 2); ndspInit(); @@ -356,16 +436,16 @@ int main(int argc, char *argv[]) mix[1] = 1.0; ndspChnSetMix(0, mix); - memset(waveBuf,0,sizeof(waveBuf)); + memset(waveBuf, 0, sizeof(waveBuf)); waveBuf[0].data_vaddr = &audioBuffer[0]; waveBuf[0].nsamples = SAMPLESPERBUF; waveBuf[1].data_vaddr = &audioBuffer[SAMPLESPERBUF]; waveBuf[1].nsamples = SAMPLESPERBUF; - //fill_buffer(audioBuffer,0, SAMPLESPERBUF * 2, 460); + // fill_buffer(audioBuffer,0, SAMPLESPERBUF * 2, 460); ndspChnWaveBufAdd(0, &waveBuf[0]); - //ndspChnWaveBufAdd(0, &waveBuf[1]); + // ndspChnWaveBufAdd(0, &waveBuf[1]); // Initialize random seed srand(time(NULL)); @@ -373,11 +453,11 @@ int main(int argc, char *argv[]) top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT); clrClear = C2D_Color32(0xFF, 0xFF, 0xFF, 0xFF); bar_clr = C2D_Color32(0x00, 0x00, 0x00, 0xFF); - active_clr = C2D_Color32(0xFF, 0x00, 0x00, 0xFD); - + active_clr = C2D_Color32(0xFF, 0x00, 0x00, 0xFF); + doneClr = C2D_Color32(0x00, 0xFF, 0x00, 0xFF); // Initialize Menus - + mainMenu = new Menu(MENU_TEXT, &kDown, &selected, &mainMenuHandler); settingsMenu = new Menu(SETTINGS_TEXT, &kDown, &selected, &settingsMenuHandler); algoMenu = new Menu(ALGO_TEXT, &kDown, &selected, &algoMenuHandler); @@ -386,23 +466,23 @@ int main(int argc, char *argv[]) initArray(); - //Initialize Threads + // Initialize Threads svcGetThreadPriority(&prio, CUR_THREAD_HANDLE); // Main loop APT_SetAppCpuTimeLimit(30); while (aptMainLoop()) - { + { hidScanInput(); kDown = hidKeysDown(); C3D_FrameBegin(C3D_FRAME_SYNCDRAW); C2D_TargetClear(top, clrClear); C2D_SceneBegin(top); - + gspWaitForVBlank(); Menu::clearConsole(); - + printf("\x1b[%i;1H%s", selected + 1, selector); activeMenu->draw(); @@ -413,17 +493,17 @@ int main(int argc, char *argv[]) C3D_FrameEnd(0); gfxFlushBuffers(); - //gfxSwapBuffers(); - + // gfxSwapBuffers(); - if (doneSorting) { + if (doneSorting) + { threadJoin(sortThread, 10000000LL); threadFree(sortThread); activeIndex = UINT32_MAX; doneSorting = false; } } - + ndspExit(); linearFree(audioBuffer);