Review the old and know the new - > data structure - > sorting - > program implementation 1_ Using C language
This blog is based on Review the old and know the new - > data structure - > sorting Part of the theoretical knowledge of sorting in the program!
Among them, three kinds of quick sorting in exchange sorting, recursive and non recursive merge sorting, non comparison sorting and so on are realized! With relevant examples and corresponding running results!
Because the sequence table and queue are used in the above program implementation, that is, the sequence table and queue need to be implemented, which will lead to a significant increase in the amount of program code. In the program, in order to clearly show the implementation code of each part, there are five files, namely queue h ,seqList.h ,queue.c ,seqList.c and main c .
Where queue H and queue C. contents and Review the old and know the new - > data structure - > queue - > program implementation 1_ Using structure Newqueue in blog H and main The above program is the same as that of C Delete or comment the test() and main() functions in C;
And seqlist H and seqlist C. contents and Review the old and know the new - > data structure - > sequence table - > program implementation 1_ Using structure Seqlist in blog H and main C corresponds to and is the same. In order to facilitate the operation of this program, it is necessary to put the main of the above blog The test() and main() functions in C are deleted or commented.
The main of this procedure will be attached in the following contents C. document contents. Other document contents can be viewed by yourself according to the above guidelines!
Note: the following code is more or less redundant, and the best performance is not considered. Readers who are interested can further simplify it!
The details are as follows:
(1)main.c
#include<stdio.h> #include<stdlib.h> #include<time.h> #include<string.h> #include"seqList.h" #include"queue.h" void swap(int *arr, int a, int b) { int t = arr[a]; arr[a] = arr[b]; arr[b] = t; } //Bubble sorting implementation method of exchange sorting void bubbleSort(int *arr, int n) { //Compare adjacent elements //First traversal range: 0 ~ the last position of unordered data int m = n; while (m>1)//Normally, the number of steps per cycle is 6 5 4 3 2 1 = 21 { //flag: marks whether a swap operation has occurred in a round of bubble sorting int flag = 0; for (int j = 1; j < m; j++) { if (arr[j-1] > arr[j]) { swap(arr, j-1, j); flag = 1; } } //If no exchange occurs, the remaining elements are all in order -- improving performance if (!flag) break; m--; } /*for (int i = 0; i < n; i++) { for (int j = i; j < n; j++) { if (arr[j - 1] > arr[j]) { swap(arr, j - 1, j); } h++; } } printf("h = %d \n", h);*/ } //hoare improvement: obtain the benchmark value: three number middle method, start, middle and end int getMid(int *arr, int begin, int end) { int mid = begin + (end - begin) / 2; if (arr[begin] >= arr[mid]) { if (arr[mid] >= arr[end]) // arr[begin]>arr[mid]>arr[end] return mid; else if (arr[begin] <= arr[end])//arr[end]>arr[begin]>=arr[mid] return begin; else // arr[begin]>arr[end]>arr[mid] return end; } else//arr[begin] < arr[mid] { if (arr[mid] <= arr[end])//arr[begin] < arr[mid] <arr[end] return mid; else if (arr[begin] >= arr[end])//arr[end]<=arr[begin]<arr[mid] return begin; else //arr[end]<arr[begin]<arr[mid] return end; } } //Pit digging method of exchange sequencing int partion2(int *arr, int begin, int end) { //Get the location of the reference value int mid = getMid(arr, begin, end); //Put the reference value at the starting position swap(arr, begin, mid); //The first value is used as the reference value, and the first position is the position of the initial pit int key = arr[begin]; //int start = begin; while (begin < end) { //int key = start; //Find the position less than the reference value from back to front while (begin < end && arr[end] >= key) --end; //Pit filling arr[begin] = arr[end]; //Find the position greater than the reference value from front to back while (begin < end && arr[begin] <= key) ++begin; //Pit filling arr[end] = arr[begin]; } //Place the encounter position into the reference value arr[begin] = key; return begin; } //Before and after pointer method of exchange sorting int partion3(int *arr, int begin, int end) { //Last position less than the reference value int prev = begin; //Next position less than the reference value int cur = begin + 1; int key = arr[begin]; while (cur <= end) { //When prev and cur are discontinuous, exchange the two numbers and judge the continuity first if (arr[cur] < key && ++prev != cur)//Discontinuity { //Discontinuous, exchange two data swap(arr, prev, cur); } ++cur; } //Exchange reference value and prev value swap(arr, begin, prev); return prev; } //Quick sorting of exchange sorting: hoare method //Returns the position of the benchmark value after division int partion(int *arr, int begin, int end) { //Get the location of the reference value int mid = getMid(arr, begin, end); //Put the reference value at the starting position swap(arr, begin, mid); //Select reference value int key = arr[begin]; int start = begin; while (begin < end) { //Find the position less than the reference value from back to front while (begin < end && arr[end] >= key) --end; //Find the position greater than the reference value from front to back while (begin < end && arr[begin] <= key) ++begin; //exchange swap(arr, begin, end); } //Exchange the data of reference value and encounter position after completion swap(arr, start, begin); return begin; } //Recursive fast scheduling void quickSort(int *arr, int begin, int end)//Implementation of hoare { if (begin >= end) return; //div: position of reference value after one division int div = partion3(arr, begin, end); //Quickly sort the left and right parts //[begin,div-1] //[div+1,end] quickSort(arr, begin, div - 1); quickSort(arr, div + 1, end); } /*Sequence table for non recursive fast scheduling */ void quickSortNor(int *arr, int n) { //Create a sequence table and save the intervals to be divided SeqList sq; initseqList(&sq); //First save the entire interval //First on the right, then on the left seqListPushBack(&sq, n - 1); seqListPushBack(&sq, 0); //Traverse the sequence table and process all intervals while (!seqListEmpty(&sq))//Only when it is not empty can the program run!!!!!!!!!!! { //Take out an interval int left = seqListBack(&sq); seqListPopBack(&sq); int right = seqListBack(&sq); seqListPopBack(&sq); //Partition interval [left,right] int div = partion(arr, left, right); //Save the generated two new areas //[left,div-1] if (left < div - 1) { seqListPushBack(&sq, div - 1); seqListPushBack(&sq, left); } //[div+1,right] if (div + 1 < right) { seqListPushBack(&sq, right); seqListPushBack(&sq, div + 1); } } } /*Non recursive fast queue */ void quickSortNor2(int *arr, int n) { //Create a queue and save the interval to be divided Queue q; initQueue(&q); //First save the entire interval queue: first in first out //First on the right, then on the left queuePush(&q, 0); queuePush(&q, n - 1); //Traverse the queue and process all intervals while (!queueEmpty(&q))//Only when it is not empty can the program run!!!!!!!!!!! { //Take out an interval int left = queueFront(&q); queuePop(&q); int right = queueFront(&q); queuePop(&q); //Partition interval [left,right] int div = partion(arr, left, right); //Save the generated two new areas //[left,div-1] if (left < div - 1) { queuePush(&q, left); queuePush(&q, div - 1); } //[div+1,right] if (div + 1 < right) { queuePush(&q, div + 1); queuePush(&q, right); } } } //Merge sort!!!!!!!!! //Merging of adjacent subsequences: begin end + 1 end2 void merge(int *arr, int begin, int mid, int end, int *tmp) { //Increasing //Subinterval: [begin,mid] [mid+1,end] int begin1 = begin; int end1 = mid; int begin2 = mid + 1; int end2 = end; //Starting position of auxiliary space int idx = begin; //Merge ordered sequence while (begin1 <= end1 && begin2 <= end2) { if (arr[begin1] <= arr[begin2]) tmp[idx++] = arr[begin1++]; else tmp[idx++] = arr[begin2++]; } //Determine whether there are unconsolidated elements if (begin1 <= end1) memcpy(tmp + idx, arr + begin1, sizeof(int)*(end1 - begin1 + 1)); if (begin2 <= end2) memcpy(tmp + idx, arr + begin2, sizeof(int)*(end2 - begin2 + 1)); //The merged sequence is copied to the corresponding interval of the original data memcpy(arr + begin, tmp + begin, sizeof(int)*(end - begin + 1)); } //Time complexity: o(nlogn) stable /* Merge recursion */ void _mergeSort(int *arr, int begin, int end, int *tmp) { if (begin >= end) return; int mid = begin + (end - begin) / 2; //First merge subsequences _mergeSort(arr, begin, mid, tmp); _mergeSort(arr, mid + 1, end, tmp); //Merge two ordered subsequences merge(arr, begin, mid, end, tmp); } void mergeSort(int *arr, int n)//recursion { //Apply for auxiliary space int *tmp = (int *)malloc(sizeof(int)*n); _mergeSort(arr, 0, n - 1, tmp); free(tmp); } /* Return is not recursive */ void mergeSortNor(int *arr, int n)//non-recursive { int *tmp = (int *)malloc(sizeof(int)*n); //Step size of subsequence int step = 1; while (step < n) { //Deal with small sequences first, and then deal with large ones for (int idx = 0; idx < n; idx += 2 * step) { //Find two subsequence intervals to be merged //[begin,mid] [mid+1,end] int begin = idx; int mid = idx + step - 1; //Determine whether there is a second subsequence if (mid >= n - 1) //There is no second subsequence, skip directly continue; int end = idx + 2 * step - 1; //Judge whether the second subsequence is out of bounds if (end >= n) end = n - 1; merge(arr, begin, mid, end, tmp); } //Update step step *= 2; } //free(tmp); } //Non comparative sort -- count sort //Time complexity: O(Max(n,range)) //Space complexity: O(range) if the scope is very large, the waste of space is huge, such as 0 1 2 10000000 void countSort(int *arr, int n) { //Find maximum and minimum values int max, min; min = max = arr[0]; for (int i = 1; i < n; i++) { if (arr[i] > max) max = arr[i]; if (arr[i] < min) min = arr[i]; } //Calculate the number range of count array int range = max - min + 1; //Create a count array and initialize it to 0 int *countArr = (int *)calloc(range,sizeof(int)); //Count calculates the number of identical numbers in the arr for (int i = 0; i < n; ++i) { countArr[arr[i] - min]++; } //Traverse count array, sort int idx = 0; for (int i = 0; i < range; i++) { while (countArr[i]--) { arr[idx++] = i + min; } } } //Print array void printArr(int *arr, int n) { for (int i = 0; i < n; i++) { printf("%d ", arr[i]); }printf("\n"); } void test() { int arr1[] = { 6, 3, 1, 8, 7, 2, 4 }; int n = sizeof(arr1) / sizeof(arr1[0]); int *arr2 = (int*)malloc(sizeof(int)*n); memcpy(arr2, arr1, sizeof(arr1)); printf("Contents before sorting:\n"); printArr(arr2, n); printf("\n"); printf("Contents after bubble sorting:\n"); bubbleSort(arr2, n); printArr(arr2, n); printf("\n"); memcpy(arr2, arr1, sizeof(arr1)); printf("Content after recursive fast scheduling:\n"); quickSort(arr2, 0, n - 1); printArr(arr2, n); printf("\n"); memcpy(arr2, arr1, sizeof(arr1)); printf("Contents after non recursive fast scheduling (using sequence table):\n"); quickSortNor(arr2, n); printArr(arr2, n); printf("\n"); memcpy(arr2, arr1, sizeof(arr1)); printf("Content after non recursive fast queuing (using queue):\n"); quickSortNor2(arr2, n ); printArr(arr2, n); printf("\n"); memcpy(arr2, arr1, sizeof(arr1)); printf("Content after recursive merging and sorting:\n"); mergeSort(arr2, n ); printArr(arr2, n);printf("\n"); memcpy(arr2, arr1, sizeof(arr1)); printf("Contents after non recursive merging and sorting:\n"); mergeSortNor(arr2, n); printArr(arr2, n); printf("\n"); memcpy(arr2, arr1, sizeof(arr1)); printf("Contents after non comparison sorting:\n"); countSort(arr2, n); printArr(arr2, n); printf("\n"); memcpy(arr2, arr1, sizeof(arr1)); } //void test2() //{ // int n; // printf("amount of data: \ n"); // scanf_s("%d", &n); // srand(time(NULL)); // int *arr = (int *)malloc(sizeof(int)*n); // int *copy1 = (int *)malloc(sizeof(int)*n); // int *copy2 = (int *)malloc(sizeof(int)*n); // for (int i = 0; i < n; i++) // { // arr[i] = rand(); // } // memcpy(copy1, arr, sizeof(int)*n); // memcpy(copy2, arr, sizeof(int)*n); // // time_t begin = clock(); // insert(copy1, n); // time_t end = clock(); // printf("direct insert sort time:% d\n", end - begin); // // begin = clock(); // shellSort(copy2, n); // end = clock(); // printf("Hill sort time:% d\n", end - begin); //} int main() { test(); system("pause"); return 0; }
(2) Operation results
Infringement deletion~