#include <iostream>
#include <list>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <map>
#include <functional>
#include <algorithm>
#include <stack>
#include <ctime>
using namespace std;
//冒泡排序(n2)
//相邻元素交换,未交换结束,每次减1
void buble_sort(int a[], int n)
{
bool flag;
do
{
flag = false;
for (int j = 1; j < n; j++)
{
if (a[j - 1]>a[j])
{
swap(a[j], a[j - 1]);
flag = true;
}
}
n--;
} while (flag);
}
//插入排序,有序序列和无序序列,o(n*2),稳定
//从1开始依次和前面的有序序列相比,找到合适的插入位置插入
void insert_sort(int a[], int n)
{
int t,i,j;
for (i = 1; i < n;i++)
{
t = a[i];//要插入的位置
for (j = i; j>0&&a[j-1]>t;j--)
{
a[j] = a[j - 1];
}
a[j] = t;
}
}
//选择排序,选择最小(不稳定) ,o(n*2)
//3 7 4 2
void select_sort(int a[], int n)
{
for (int i = 0; i < n;i++)
{
int min = i;
for (int j = i + 1; j < n; j++)
{
if (a[j] < a[min]) min = j;
}
if (min != i) swap(a[i],a[min]);
}
}
//快速排序思路,找分界值,一般用中间得数据作为分界值,和第一个元素交换作为界,O (nlogn)
//分组,比分界值小的在一边,比分界值大的在一边
//1.从左向右找,比分界值大的停下(避免走出右边界)
//2.从右向左找,比分界值小的停下(避免走出左边界)
//3, 交换
//如果分界值比,左右相遇的的值大,交换
//递归左边分组
//递归右边分组
//递归结束条件,元素个数不超过一个
void quick_sort(int a[], int n)
{
if (n <= 1) return;
if (n == 2) {
swap(a[0], a[1]); return;
}
swap(a[n / 2], a[0]);
int jie = a[0];
int* L = a + 1;
int* R = a + n - 1;
while (L<R)
{
while (L < R&&*L < jie) L++;
while (a<R&&*R>=jie) R--;
if (L < R) swap(*L,*R);
}
if (*R<jie)
{
swap(a[0], *R);
}
quick_sort(a,R-a);
quick_sort(R + 1, (n - 1) - (R - a));
}
/**************************** 排序规则 ****************************
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;
随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰
被分成一组,算法便终止。
稳定性: 希尔排序是非稳定排序算法。
*****************************************************************/
//希尔排序O(n^(1.3—2))
void shellSort(int *array, int len)
{
// 步长
int gap = len;
while (gap > 1)
{
// 步长递减公式
gap = gap / 3 + 1;
// 分组, 对每一组, 进行插入排序
for (int i = 0; i < gap; ++i)
{
int tmp; // 基准数
int index; // 坑的位置
// 插入排序
// 无序序列
for (int j = i + gap; j < len; j += gap)
{
tmp = array[j];
index = j;
// 有序序列(从后往前遍历)
for (int k = j - gap; k >= 0; k -= gap)
{
if (tmp < array[k])
{
// 后移
array[k + gap] = array[k];
// 位置
index = k;
}
else
{
break;
}
}
// 填坑
array[index] = tmp;
}
}
}
}
//分组加插入排序
void shell_sort2(int a[],int n)
{
int gap = n,k=0,i=0,j=0;
while (gap>1)
{
gap= gap / 3 + 1;
for ( i = 0; i < gap;i++)
{
for (j = i+gap; j < n;j+=gap)
{
int t = a[j];
for ( k = j ; k > 0&&a[k-gap]>t;k-=gap)
{
a[k] = a[k - gap];
}
a[k] = t;
}
}
}
}
//归并排序o(nlogn),稳定
//将两个有序数列a[first...mid]和a[mid+1...last]合并。
void mergeArray(int a[], int first, int mid, int last, int temp[])
{
int i = first; // 第一个有序序列的开始下标
int j = mid + 1; // 第2个有序序列的开始下标
int length = 0;
// 合并两个有序序列
while (i <= mid && j <= last)
{
// 找二者中比较小的数
if (a[i] < a[j])
{
temp[length] = a[i];
i++;
}
else
{
temp[length] = a[j];
j++;
}
length++;
}
// 还剩下一个有序序列中有数据
while (i <= mid)
{
temp[length] = a[i];
i++;
length++;
}
while (j <= last)
{
temp[length++] = a[j++];
}
// 覆盖原来位置的无序序列
for (int i = 0; i < length; ++i)
{
// 找到原来 的第一个有序序列的开始位置 - 开始覆盖
a[first + i] = temp[i];
}
}
//归并排序
void mergeSort(int a[], int first, int last, int temp[])
{
// 递归结束的条件
if (first == last)
{
return;
}
// 从中间位置拆分
int mid = (first + last) / 2;
// 拆分
// 左半边
mergeSort(a, first, mid, temp);
// 右半边
mergeSort(a, mid + 1, last, temp);
// 合并两个有序序列
mergeArray(a, first, mid, last, temp);
}
#define N 65530
int main()
{
int a[N];
for (int i = N; i > 0;i--)
{
a[N - i] = i;
}
int*p = (int*)malloc(sizeof(int)*N);
clock_t t1 = clock();
mergy_sort2(a, 0,N-1,p);
clock_t t2 = clock();
cout << "time:"<<double(t1 - t2) / CLOCKS_PER_SEC << endl;
for (int i = 0; i < 10;i++)
{
cout << a[i] << " ";
}
cout << endl;
free(p);
system("pause");
}