排序算法
排序的作用
首先它是一种排序算法,排序算法是为了让无序的数据组合变成有序的数据组合。 有序的数据组合最大的优势是在于当你进行数据定位和采用时, 会非常方便,因为这个数据是有序的, 从而在代码设计的时候会让你避免很多不必要的麻烦。
几种常见的排序算法
1.冒泡排序
3.插入排序
2.快速排序
4.归并排序
……还有什么拓扑排序等等太大佬的我也没看懂……
基本概念(时间复杂度&空间复杂度)
在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。 这是一个代表算法输入值的字符串的长度的函数。 时间复杂度常用大O符号表述,不包括这个函数的低阶项和首项系数。 使用这种方式时,时间复杂度可被称为是渐近的,亦即考察输入值大小趋近无穷时的情况。
类似于 时间复杂度的讨论,一个算法的空间复杂度*S(n)定义为该算法所耗费的存储空间,它也是问题规模n的函数。 渐近空间复杂度也常常简称为空间复杂度。 空间复杂度(SpaceComplexity)是对一个算法在运行过程中临时占用存储空间*大小的量度。
下面排序全部针对一个整型数组A[n]里的元素进行
冒泡排序
原理:内循环第k次后,排在第k名的元素已被排好
代码:
if n < 2 { return; } for (int i=0;i<n;i++){ for(int j=n-1;j>0;j--){ if (A[j]>A[j-1]){ int temp=A[j]; A[j]=A[j-1]; A[j-1]=temp; } } }
插入排序
原理:对于一个排序好k个元素的数列,对下一个元素进行操作,使其插入在前面已经排序好的数列中,生成一个新的排序好k+1个元素的数列。
代码:
if n < 2 { return; } for (int i=0;i<n;i++){ for (int j=i-1;j>=0;j--){ if (A[j+1]<A[j]){ int temp=A[j]; A[j]=A[j+1]; A[j+1]=temp; }else{ break; } } }
减少交换次数的算法
if n < 2 { return } for (int i = 1; i < 10; i++) { int temp = A[i]; for (int j = i; j >= 0; j--) { if (A[j - 1] > temp) { A[j] = A[j - 1]; } else { A[j] = temp; break; } } }
(插入排序可搭配二分查找来减少交换次数,二分查找算法还不熟就先不说了。。。)
快速排序
原理:对于一个数列,取其中一个元素为基准,对剩余元素进行判断,比基准大的和比基准小的元素各方在基准两侧,操作完成后,将基准两侧的数列看成两个新数列,重复操作。
代码:
//入口为qsort(A,0,n) void qsort(int A[],int m,int n){ if (n-m<1){ return; } int pivot=A[m]; int k=m; for (int i=m+1;i<n;i++){ if (A[i]>pivot){ int q1=A[i]; for (int j=i-1;j>=m;j--){ A[j+1]=A[j]; } A[m]=q1; k++; } } qsort(A,m,k);qsort(A,k+1,n); } //这个写的。。好像交换次数有点多。。。
void quickSort(int s[], int l, int r) { if (l < r) { int i = l, j = r, x = s[l]; while (i < j) { while (i < j && s[j] >= x) // 从右向左找第一个小于x的数 j--; if (i < j) s[i++] = s[j]; while (i < j && s[i] < x) // 从左向右找第一个大于等于x的数 i++; if (i < j) s[j--] = s[i]; } s[i] = x; quickSort(s, l, i - 1); // 递归调用 quickSort(s, i + 1, r); } } //网上找的。。
归并排序
原理:找内存再要一个大小相等的空间,先将原数列拆为只含一个元素的单体进行排列,再进行合并。
void merge_sort_recursive(int arr[], int reg[], int start, int end) { if (start >= end) return; int len = end - start, mid = (len >> 1) + start; int start1 = start, end1 = mid; int start2 = mid + 1, end2 = end; merge_sort_recursive(arr, reg, start1, end1); merge_sort_recursive(arr, reg, start2, end2); int k = start; while (start1 <= end1 && start2 <= end2) reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++]; while (start1 <= end1) reg[k++] = arr[start1++]; while (start2 <= end2) reg[k++] = arr[start2++]; for (k = start; k <= end; k++) arr[k] = reg[k]; } void merge_sort(int arr[], const int len) { int reg[len]; merge_sort_recursive(arr, reg, 0, len - 1); } //递归法(迭代法google去吧)
复杂度表
PS:稳定指对于两个键值相同的元素不交换
Question:稳定性的意义
。。。。。。。。。。。。。。。。。。。。。无聊的分割线。。。。。。。。。。。。。。。。。。。。。。。
好的现在来看一道题
下列算法中,初始数据集的排列对算法性能无影响的是
A.插入排序 B.冒泡排序 C.归并排序 D.快速排序
。
。。
。。。
。。。。
。。。。。
。。。。。。
。。。。。。。
。。。。。。。。
。。。。。。。。。
。。。。。。。。。。
答案:C
口诀:一堆(堆排序)海归(归并排序)选(选择排序)基友