c語言實現高響應比演算法_常用排序演算法C語言實現
阿新 • • 發佈:2021-01-24
技術標籤:c語言實現高響應比演算法
#include <iostream> #include <algorithm> using namespace std; /** 排序相關演算法 * 插入排序: * 1.直接插入排序 穩定 * 2.折半插入排序 穩定 * 3.希爾排序 不穩定 * 快速排序: * 4.氣泡排序 穩定 * 5.快速排序 不穩定 * 選擇排序: * 6.簡單選擇排序 不穩定 * 7.堆排序 不穩定 * 歸併排序: * 8.二路歸併排序 穩定 */ /**1.直接插入排序 * 思想:(1)第一個記錄是有序的 * (2)從第二個記錄開始,按關鍵字的大小將每個記錄插入到已排好序的序列中 * (3)一直進行到第n個記錄 */ void InsertionSort(int list[], int length) { if (!length || !(length - 1)) //空陣列或只有一個元素直接返回 return; for (int i = 1; i < length; i++) { int j; int shell = list[i]; //設當前元素為哨兵 for (j = i - 1; j >= 0 && list[j] > shell; j--) list[j + 1] = list[j]; //比哨兵大,後移 list[j + 1] = shell; //找到恰當位置了,插入 } } //折半插入排序 void BiInsertionSort(int list[], int length) { if (!length || !(length - 1)) return; for (int i = 1; i < length; i++) { int j; int shell = list[i]; int low = 0, high = i - 1; while (low <= high) //與直接插入排序相比,多了一個二分查詢插入位置 { int m = (low + high) / 2; if (shell > list[m]) low = m + 1; else high = m - 1; } for (j = i - 1; j >= high + 1; j--) list[j + 1] = list[j]; list[j + 1] = shell; } } //希爾排序 void ShellInsert(int *list, int length, int dk) { if (!length || !(length - 1)) return; for (int i = dk; i < length; i++) { int shell = list[i]; int j; for (j = i - dk; j >= 0 && shell < list[j]; j -= dk) list[j + dk] = list[j]; list[j + dk] = shell; } } void ShellSort(int *delta, int k, int *list, int length) { for (int i = 0; i < k; i++) ShellInsert(list, length, delta[i]); //進行增量為delta[i]的直接插入排序 } //氣泡排序 void BubbleSort(int *list, int length) { int i = length, lastEx; while (i > 0) { lastEx = 0; for (int j = 0; j < i; j++) { if (list[j] > list[j + 1]) //把未排序部分的最大值上浮,使得每趟排序後完成的部分至少加一 { int temp = list[j]; list[j] = list[j + 1]; list[j + 1] = temp; lastEx = j; } } i = lastEx; //最後一次交換後面的已經完成排序 } } //快速排序 void QuickSort(int *list, int low, int high) { int Olow = low, Ohigh = high; //記錄原來的上界和下界 if (low < high) { auto midOfThree = [](int a, int b, int c) { return min(a, max(b, c)); }; int shell = midOfThree(list[low], list[high], list[(low + high) / 2]); //用low,high以及中間的數三個數的中位數做軸 while (low < high) //根據軸將左右分為小於軸的部分和大於軸的部分 { while (low < high && list[high] >= shell) //找到比軸小的數,放低半區 --high; list[low] = list[high]; //low原來的值已經拷貝,放心賦值 while (low < high && list[low] <= shell) //找到比軸大的數,放高半區 ++low; list[high] = list[low]; //high原來的值賦給了上面,不用擔心丟失 } list[low] = shell; QuickSort(list, Olow, low - 1); //對低半區遞迴 QuickSort(list, low + 1, Ohigh); //對高半區遞迴 } } //簡單選擇排序 void SelectSort(int *list, int length) { for (int i = 0; i < length - 1; i++) { int shell = list[i], minindex = i; //記錄當前的值 for (int j = i; j < length; j++) { if (list[j] < list[minindex]) //尋找未排序部分最小值 minindex = j; } if (i != minindex) //如果當前值不是未排序部分最小值,進行交換 { list[i] = list[minindex]; list[minindex] = shell; } } } //堆排序 //對於從0開始的陣列 //parent = [(i - 1)/2] [x]表示對x向下取整 //lChild = 2*i + 1 //rChild = 2*i + 2 void Heapify(int *list, int root, int high) { if (root >= high) //越界了,直接返回 return; int lChild = 2 * root + 1; int rChild = 2 * root + 2; int maxi = root; if (lChild < high && list[lChild] > list[maxi]) maxi = lChild; if (rChild < high && list[rChild] > list[maxi]) maxi = rChild; //找到了三者最大值,若不是根節點 if (maxi != root) { int temp = list[maxi]; list[maxi] = list[root]; list[root] = temp; //最大者上浮 Heapify(list, maxi, high); //可能破壞了交換的那一邊的堆結構,重新heapify一下 } } void HeapSort(int *list, const int length) { for (int i = length / 2; i >= 0; i--) //length/2之後的都是葉子節點,已經符合要求,不需要heapify { Heapify(list, i, length); //一定是自底向上開始建堆,因為只有兩個孩子都是堆的情況下才能heapify整體,而葉子節點我們認為已經heapify } for (int i = length - 1; i >= 0; i--) //上面建的大根堆,最大值在頭上 { int temp = list[i]; list[i] = list[0]; list[0] = temp; //交換0,i位置的值,讓未排序最大值加入到排好序的地方,未排序部分長度減一 Heapify(list, 0, i); //對0->i-1重新建堆 } } //歸併排序 void MSort(int *list, int *helper, int low, int high) { if (low == high)//遞迴結束 return; int mid = (low + high) / 2; MSort(list, helper, low, mid);//前一半排好序 MSort(list, helper, mid + 1, high);//後一半排好序 int i = low, j = mid + 1; int k = low; while (k <= high) { if (j > high || i <= mid && helper[i] <= helper[j])//前後兩半歸併在一起 { list[k++] = helper[i++]; } else { list[k++] = helper[j++]; } } for (int i = low; i <= high; i++) helper[i] = list[i]; } void MergeSort(int *list, int length) { int *helper = (int *)malloc(sizeof(int) * length); for (int i = 0; i < length; i++) helper[i] = list[i]; MSort(list, helper, 0, length - 1); free(helper); }
速度比較如下