排序方法
0.1 分类
非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序。
线性时间非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此称为线性时间非比较类排序。


0.3 相关概念
稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。
时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。
空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。
一、冒泡排序
从左向右依次比较相邻两个数,找出大的后移。
第一轮,找出最大的放到最后一位;
第二轮,找出次大的放到倒数第二位;
多次循环后,排序完成。
二、选择排序(Selection Sort)
首先选择所有数据中最小的,放到第一位;然后再剩下的数据中选择次小的,放到第二位;…多次循环后,排序完成。
(比较冒泡和选择,冒泡两个数值比较完后,就得交换两个数值;选择排序的话,比较只需记录最小的下标,全部完后再交换)
三、插入排序(Insertion Sort)
假设第一个值最小,第二个值 与第一个值比较,如果小于第一个值,则插入到第一个值之前,这样,前两个值就排好序了。
然后,第三个值与排好序的前两个值比较,在合适的位置插入进去,这样前三个值就排好序了。
依次类推。排好所有的值。
难点:排好序的值得统一右移,通过while来实现比较好。
function insertionSort(arr) {
var len = arr.length;
var preIndex, current;
for (var i = 1; i < len; i++) {
preIndex = i - 1;
current = arr[i];
while (preIndex >= 0 && arr[preIndex] > current) {
arr[preIndex + 1] = arr[preIndex];
preIndex--;
}
arr[preIndex + 1] = current;
}
return arr;
}
黄色部分,通过arr[preIndex]>current,来控制条件,通过preIndex--来控制下标。
四、希尔排序(Shell Sort)
1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。

利用局部先排序,然后最后插入的时候,比较次数会比一开始就采用插入排序要少的方法。
#include <iostream>
using namespace std;
void ShellSort(int *a,int len) //数组的位置引用
{
int i, j, h;
int r, temp;
int x = 0;
for (r=len/2;r>=1;r/=2) //r>=1保证至少有两个可以比较的数,r/=2确定序列对
{
for (i=r;i<len;i++)
{
temp = a[i];
j = i - r; //分组方式
while (j>=0 && temp<a[j])//对配对的两个数进行比较
{
a[j + r] = a[j]; //向右移
j -= r;
}
a[j + r] = temp; //插入
}
x++; //第几步
cout<<"第"<<x<<"步的排序结果:";
for (h=0;h<len;h++)
{
cout<<a[h]<<" ";
}
cout<<"\n";
}
}
int main()
{
int i;
int arr[] = {50,83,88,87,61,84,70,60,80,99};
cout<<"排序前:"<<"\n";
for (i=0;i<10;i++)
{
cout<<arr[i]<<' ';
}
cout<<"\n";
ShellSort(arr,10); //注意引用方式
cout<<"排序后:"<<"\n";
for (i=0;i<10;i++)
{
cout<<arr[i]<<' ';
}
cout<<"\n";
return 0;
}
(1)

交换的是相同颜色的,也就是相同颜色的是一个组,此时增量为5,分为了5组。
(2)

相同颜色的为一组,排序;增量为2,分为了2组。
(3)

增量为1,分为1组,采用插入排序。
五、
浙公网安备 33010602011771号