常见的几种排序算法

xiaoxiao2021-02-28  85

#include <iostream> using namespace std; /*排序过程都是直接在内存中完成,统称为内排序*/ //=======================交换排序================ /*冒泡排序:时间复杂度为O(n^2),空间复杂度为O(1) 依次比较相邻两个元素,首先比较第1个位置和第2个位置的数,大的放后面,小的放前面,然后比较第2个位置第3个位置的数,重复进行到第n个位置,经过这一轮,数组中最大元素交换到第n个位置; 重复上一步骤,直到第n-1个位置;依次重复执行,直到第1个位置*/ void bubbleSort(int arr[], int len) { int temp; for (int i = len - 1; i > 0; i--) { for (int j = 0; j < i; j++) { if (arr[j] > arr[j + 1]) { temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } /*鸡尾酒排序: 冒泡排序改进算法 双向冒泡排序*/ void cocktailSort(int arr[], int len) { int head = 0, tail = len - 1; int temp, k; while (head < tail) { for (k = head; k < tail; k++) { if (arr[k] < arr[k + 1]) { temp = arr[k]; arr[k] = arr[k + 1]; arr[k + 1] = temp; } tail--; for (k = tail; k>head;k--) { if (arr[k - 1]>arr[k]) { temp = arr[k-1]; arr[k - 1] = arr[k]; arr[k] = temp; } } head++; } } } /*改进冒泡排序,设置标志: 若在一轮扫描过程中没有交换元素,则表示已经排序完成,没必要继续执行*/ void bubbleFlagSort(int arr[], int len) { int temp, flag = 1; for (int i = len - 1; i > 0 && flag; i--) { flag = 0; for (int j = 0; j < i; i++) { if (arr[j] < arr[j + 1]) { temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; flag = 1; } } } } /*快速排序:O(N*log2N) 首先数组根据中枢值分成两个部分,左边元素小于等于中枢值,右边元素都大于中枢值;然后每个部分被递归的排序。 优化:消除递归; 选择基于三中值分区的中枢值; 设定一个切分数组长度的最小值,如果小于这个值就直接使用插入排序;*/ void qSort(int* a, int left, int right) { if (left >= right) return; int zsv = a[left];//选取第一个元素为中枢值 int last = left, temp; for (int p = left + 1; p <= right; p++) { if (a[p] < zsv) { ++last; temp = a[p]; a[p] = a[last]; a[last] = temp; } } a[left] = a[last]; a[last] = zsv; //递归 qSort(a, left, last - 1); qSort(a, last + 1, right); } void quickSort(int* a, int len) { qSort(a, 0, len - 1); } //============================选择排序=================== /*选择排序:每次从未排序的序列中挑选出最大(最小)的元素,重复这个过程直到所有元素都被挑完。O(n^2)*/ void selectSort(int* a, int len) { int minpos, min; for (int i = 0; i < len; i++) { min = a[i]; minpos = i; for (int j = i; j < len; j++) { if (a[j] < min) { min = a[j]; minpos = j; } } a[minpos] = a[i]; a[i] = min; } } /*堆排序:堆实际上是一棵完全二叉树 堆的基本操作分为向上调整和向下调整,利用向上调整操作构建堆,堆顶元素和堆尾交换后,堆长度减1, 利用向下调整操作从堆顶开始调整生成新堆。*/ inline void swap(int* arr, int a, int b) { int temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; } void HeapAdjust(int* L, int s, int m)//构建大顶堆 { int temp, j; temp = L[s]; for (j = 2 * s; j < m; j *= 2)//沿关键字较大的孩子结点向下筛选 { if (j < m && L[j] < L[j + 1])//lchild<rchild ++j; //j为关键字中较大的记录的小标 if (temp>=L[j])//parent>=rchild break; L[s] = L[j]; s = j; } L[s] = temp;//交换parent与lchild } //对顺序表L进行堆排序 void HeapSort(int* L,int len) { int i; for (i = len/ 2; i > 0; i--)//把L构建成一个大顶堆 HeapAdjust(L, i-1, len); /*for (i = 0; i < len; i++) cout << L[i] << " "; cout << endl;*/ for (i = len-1; i > 0; i--) { swap(L, 0, i);//将堆顶记录和当前未经排序子序列的最后一个记录交换 HeapAdjust(L, 0, i - 1);//将L[0--i-1]重新调整为大顶堆 } /*for (i = 0; i < len; i++) cout << L[i] << " "; cout << endl;*/ } //================插入排序=============== /*插入排序:O(n^2) 将一个数组分为两个部分,前一部分为已排序,后一部分为乱序, 每次将乱序部分第一个元素插入到有序部分中,从插入点开始有序部分元素依次后移, 如此重复直至乱序元素个数为0,则完成整个排序过程。*/ void insertSort(int* arr, int len) { for (int i = 1; i < len; i++) { int pos = i - 1; int temp = arr[i]; while (pos >= 0 && arr[pos]>temp) { arr[pos + 1] = arr[pos]; pos--; } arr[pos + 1] = temp; } } /*希尔(Shell)排序 :一种递减增量分组插入排序 将比较的全部元素分为几个区域来提升插入排序的性能*/ void ShellSort(int* arr, int len) { // 以 N/2^k(k从1开始)为步长,直至步长为1 for (int step = len / 2; step > 0;step/=2) { // 各组内简单插入排序 for (int i = step; i < len;i++) { int temp = arr[i]; int j = i - step; for (; j >= 0 && arr[j]>temp; j -= step) arr[j + step] = arr[j]; arr[j + step] = temp; } } } //=======================合并排序===================== /*归并排序: 假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1, 然后两两归并,得到[n/2]([x]表示不小于x的最小整数)个长度为2或1的有序子序列;再两两归并,......., 如此重复,直到得到一个长度为n的有序序列为止,即2路归并排序*/ //合并两个有序部分 void mergeArray(int a[], int first, int mid, int last, int temp[]) { if (first >= last) { return; } int i = first, j = mid + 1; int k = first; while (i <= mid && j <= last) { if (a[i] > a[j]) { temp[k++] = a[j++]; } else { temp[k++] = a[i++]; } } while (i <= mid) { temp[k++] = a[i++]; } while (j <= last) { temp[k++] = a[j++]; } // 回写到原来数组中 for (k = first; k <= last; k++) { a[k] = temp[k]; } } //递归调用归并 void mSort(int* a, int first, int last, int *temp) { if (first < last) { int mid = (first + last) >> 1; mSort(a, first, mid, temp); mSort(a, mid + 1, last, temp); mergeArray(a, first, mid, last, temp); } } //归并排序算法 void MergeSort(int* a, int len) { int* temp = new int[len]; mSort(a, 0, len - 1, temp); delete[] temp; } int main() { int a[] = {50,10,90,30,70,40,80,60,20}; MergeSort(a, 9); for (int i = 0; i < 9; i++) cout << a[i] << " "; system("pause"); return 0; }
转载请注明原文地址: https://www.6miu.com/read-39017.html

最新回复(0)