一、排序的分类
插入排序
1.直接插入排序
#include<iostream>
using namespace std;
void insertSort(int a[],int n)
{
int i,j;
for(int i=2;i<=n;++i)//依次将a[2]~a[n]插入到前面已排序的序列
{
if(a[i]<a[i-1])//a[i]小于前驱的话,将a[i]插入有序表
{
a[0]=a[i];//将a[i]复制为哨兵
for(j=i-1;a[0]<a[j];--j)//从后往前查找插入位置
a[j+1]=a[j];//往后挪位
a[j+1]=a[0];//复制到插入位置
}
}
}
int main()
{
int a[10]={0,7,86,9,5,44,6,2,14,3};//a[0]为哨兵的位置,不参与排序
insertSort(a,10);
for(int i=1;i<10;++i)
cout<<a[i]<<" ";
}
直接插入排序的时间复杂度为o(n^2),空间复杂度为o(1)。
稳定性:稳定
2.希尔排序
#include<iostream>
using namespace std;
void shellSort(int a[],int n)
{
/**
**相对直接插入排序:
1.位置增量变为dk,不是1
2.a[0]是暂存单元
*/
int dk = 0;
int len = n;
int i = 0;
int j = 0;
for(dk=len/2;dk>=1;dk=dk/2)//步长变化
{
for(i=dk+1;i<=n;++i)
{
if(a[i]<a[i-dk])//将a[i]插入有序增量子表
{
a[0] = a[i];//暂存在a[0]
for(j=i-dk;j>0&&a[0]<a[j];j-=dk)
a[j+dk]=a[j];
a[j+dk]=a[0];//插入
}
}
}
}
int main()
{
int a[10]={0,7,86,9,5,44,6,2,14,3};
shellSort(a,10);
for(int i=1;i<10;++i)
cout<<a[i]<<" ";
}
空间复杂度位O(1),时间复杂度最坏为O(n^2)。
稳定性:不稳定
交换排序
1、冒泡排序
#include <iostream>
using namespace std;
//从小到大排列
void bubbleSort(int a[],int n)
{
int flag = false;//本趟是否发生交换的标志
for(int i=0;i<n-1;++i)
{
flag = false;
for(int j=n-1;j>i;--j)
{
if(a[j-1]>a[j])
{
int temp = 0;
temp = a[j-1];
a[j-1] = a[j];
a[j] = temp;
flag = true;
}
}
if(flag == false)//本趟未发生交换,则表明已有序
return ;
}
}
int main()
{
int a[10]={0,7,86,9,5,44,6,2,14,3};
bubbleSort(a,10);
for(int i=0;i<10;++i)
cout<<a[i]<<" ";
}
最坏时间复杂度O(n^2),有序时为O(n)。空间复杂度为O(1)。
稳定性:稳定
2、快速排序
#include <iostream>
using namespace std;
int partition(int a[],int low,int high);
void quickSort(int a[],int low,int high)
{
if(low<high)//不满足条件,跳出递归
{
int pivotpos = partition(a,low,high);//划分表
quickSort(a,low,pivotpos-1);//对两个子表进行递归排序
quickSort(a,pivotpos+1,high);
}
}
int partition(int a[],int low,int high)
{
int pivot = a[low];//将表中第一个元素设为枢轴值,对表进行划分
while(low<high)//不满足,跳出
{
while(low<high&&a[high]>=pivot)
--high;
a[low]=a[high];//比枢轴值小的元素,移到左端
while(low<high&&a[low]<=pivot)
++low;
a[high] =a[low];//比枢轴值大的元素,移到右端
}
a[low]=pivot;//枢轴元素放到最终位置
return low;//返回枢轴值位置
}
int main()
{
int a[10]={0,7,86,9,5,44,6,2,14,3};
quickSort(a,0,9);
for(int i=0;i<10;++i)
cout<<a[i]<<" ";
}
时间复杂度 空间复杂度
稳定性:不稳定
选择排序
1、简单选择排序
#include <iostream>
using namespace std;
void swap(int &x,int &y)
{
int temp =0;
temp = x;
x = y;
y =temp;
}
void selectSort(int a[],int n)
{
for(int i=0;i<n-1;++i)//需要进行n-1趟
{
int min = i;//每趟将min=i
for(int j=i+1;j<n;++j)//在a[i...n-1]中选择最小的元素
{
if(a[j]<a[min])
min =j;
}
if(min!=i)//与第i个位置交换
swap(a[i],a[min]);
}
}
int main()
{
int a[10]={0,7,86,9,5,44,6,2,14,3};
selectSort(a,10);
for(int i=0;i<10;++i)
cout<<a[i]<<" ";
}
时间复杂度:O(n^2) 空间复杂度:O(1)
稳定性:不稳定
2、堆排序
首先,将L[1...n]视为一棵完全二叉树的顺序存储结构。
a.进行初始建堆。
b.输出堆顶元素,再将最后一个元素放到堆顶
向下调整。
c.重复进行b操作
向下调整也是删除元素时进行的操作
向上调整为插入元素进行的操作
#include <iostream>
using namespace std;
void swap(int &x,int &y)
{
int temp =0;
temp = x;
x = y;
y =temp;
}
void adjustDown(int a[],int k,int len)
{
a[0] = a[k];
for(int i=2*k;i<=len;i*=2)
{
if(i<len && a[i]<a[i+1])
i++;
if(a[0]>=a[i])
break;
else
{
a[k] = a[i];
k=i;
}
}
a[k]= a[0];
}
void buildMaxHeap(int a[],int len)
{
for(int i=len/2;i>0;--i)
adjustDown(a,i,len);
}
void heapSort(int a[],int len)
{
buildMaxHeap(a,len);//初始建堆
for(int i=len;i>1;--i)//n-1趟交换和建堆的过程
{
swap(a[i],a[1]);
adjustDown(a,1,i-1);
}
}
int main()
{
int a[10]={0,7,86,9,5,44,6,2,14,3};
heapSort(a,10);
for(int i=1;i<10;++i)
cout<<a[i]<<" ";
}
时间复杂度O(nlogn) 空间复杂度 O(1)
稳定性:不稳定
未完。。。