#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define clr(str,x) memset(str,x,sizeof(str))
#define FRER() freopen("in.txt","r",stdin);
#define FREW() freopen("out.txt","w",stdout);
#define MAX_INF 0x7fffffff
#define INF 0x3f3f3f3f
#define maxn 100010
typedef long long int ll;
using namespace std;
int a[maxn] = {4, 981, 10, -17, 0, -20, 29, 50, 8, 43};
int n = 10;
void Print()
{
for(int i=0; i<n; i++)
{
if(!i)
printf("%d",a[i]);
else
printf(" %d",a[i]);
}
printf("\n");
}
/*1.选择排序:(O(n^2))
* 每次找出子数组中最小的元素,和子数组最前面的元素换位置
*/
void SelectionSort()
{
int Min,temp;
for(int i=0; i<n-1; i++)
{
Min = i;
for(int j=i+1; j<n; j++)
{
if(a[j]<a[Min])
Min=j;
}
if(i!=Min)
{
temp = a[i];
a[i] = a[Min];
a[Min] = temp;
}
//测试用
//Print();
}
}
/*2.冒泡排序:(O(n^2))
* 比较两个相邻的元素,将值大的元素交换至右端。
*/
void BubbleSort()
{
for(int i=0; i<n-1; i++) //外层循环控制排序趟数
{
for(int j=0; j<n-1-i; j++) //内层循环控制每一趟排序多少次
{
if(a[j]>a[j+1])
{
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
//测试用
//Print();
}
}
/*3.直接插入排序:(O(n^2))
* 把n个待排序的元素看成一个有序表和一个无序表,
* 开始时有序表中只有一个元素,无序表中有n-1个元素;
* 排序过程即每次从无序表中取出第一个元素,将它插入到有序表中,使之成为新的有序表,
* 重复n-1次完成整个排序过程。
*/
void InsertSort()
{
//从下标为1开始比较,直到数组的末尾
for(int i=1; i<n; i++)
{
int j;
//将要比较的元素,拿出待比较过后再插入数组
int temp = a[i];
//一次与前一元素比较,如果前一元素比要插入的元素大,则互换位置
for(j=i-1; j>=0&&a[j]>temp; j--)
{
a[j+1] = a[j];
}
//将比较的元素插入
a[j+1] = temp;
//测试用
//Print();
}
}
/*4.折半插入排序:(O(n^2))
* 折半插入排序与直接插入排序类似。
* 不同点在于折半插入利用了二分查找,直接插入是一个个地比较查找。
*/
void BinaryInsertSort()
{
for(int i=1; i<n; i++)
{
int temp = a[i];
int low = 0,high = i - 1, j;
while(low<=high)
{
int mid = (high+low)/2;
if(a[mid]>temp)
high = mid -1;
else
low = mid + 1;
}
for(j=i-1; j>=low; j--)
{
a[j+1] = a[j];
}
a[low] = temp;
//测试用
//Print();
}
}
/*5.堆排序(nlog(n))
* 完全二叉树结构
*/
void HeadAdjust(int array[],int parent,int length)
{
int temp = array[parent];
int child = 2*parent+1;
while(child<=length)
{
if(child+1<=length&&array[child]<array[child+1])
{
child++;
}
if(temp>=array[child])
break;
swap(array[parent],array[child]);
parent=child;
child=2*parent+1;
}
array[parent]=temp;
}
void headSort()
{
for(int i=n/2-1; i>=0; i--)
{
HeadAdjust(a,i,n-1);
}
for(int i=n-1; i>0; i--)
{
int temp=a[i];
a[i]=a[0];
a[0]=temp;
HeadAdjust(a,0,i-1);
}
}
/*6.归并排序
* 算法思想就是“分+治”,先将数组逐步细分,比较大小,然后合并子数组
*/
void mergeArray(int first,int mid,int last,int temp[])
{
int i=first,j=mid+1;//两部分数组开始下标
int m=mid,n=last; //两部分数组结束坐标
int k=0;
while(i<=m&&j<=n)
{
if(a[i]<=a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while(i <= m)
temp[k++] = a[i++];
while(j<=n)
temp[k++] = a[j++];
for(int i=0; i<k; i++)
a[first+i]=temp[i];
}
void mergeSort(int first,int last,int temp[])
{
if(first<last)
{
int mid = (first+last)/2;
mergeSort(first,mid,temp);
mergeSort(mid+1,last,temp);
mergeArray(first,mid,last,temp);
}
}
/*7.快速排序
*
*/
void quickSort(int p,int q)
{
int i = p, j = q;
int temp = a[p];
while(i < j)
{
while(a[j] >= temp && j >i)
j--;
if(j > i)
{
a[i] = a[j];
i++;
while(a[i] <= temp && i < j)
i++;
if(i < j)
{
a[j] = a[i];
j--;
}
}
}
a[i] = temp;
for(int k = p;k <= q; k++)
{
if( k==i )
{
printf("(%d) ",a[k]);
continue;
}
printf("%d ",a[k]);
}
printf("\n");
if(p < (i-1)) quickSort(p,i-1);
if((j+1) < q) quickSort(j+1,q);
}
/*8.希尔排序
*
*/
void shellSort()
{
int increment = n;
int key,j;
while(increment > 1)
{
increment = increment/3 + 1;
for(int i = increment; i < n; i++)
{
key = a[i];
j = i - increment;
while(j >= 0)
{
if(key <a[j])
{
int temp = a[j];
a[j] = key;
a[j+increment] = temp;
}
j = j - increment;
}
}
}
}
int main()
{
//FRER()
//FREW()
printf("初始序列:\n");
Print();
//SelectionSort(); //1.选择排序
//BubbleSort(); //2.冒泡排序
//InsertSort(); //3.直接插入排序
//BinaryInsertSort(); //4.折半插入排序
//headSort(); //5.堆排序
//int temp[maxn]; mergeSort(0,n-1,temp); //6.归并排序
//quickSort(0,n-1); //7.快速排序
//shellSort(); //8.希尔排序
printf("\n递增序列:\n");
Print();
return 0;
}