排序算法的时间复杂度及其稳定性
排序算法常用分类
1. 冒泡排序
冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
#include<iostream>
using namespace std;
// 冒泡排序 最基本的排序算法,核心是交换算法
// 相邻数据依次比较大小,根据大小将相邻元素排序, 获得有序数列
// 冒泡排序的时间复杂:平均复杂度O(n^2) 最坏:O(n^2) 最好情况O(n)
// 空间复杂度: O(1) 是稳定排序 复杂度:简单
// 冒泡排序最少是1趟,最多才是n-1趟,最少比较n-1次,最多才是n(n-1)/2
// 代码实现
void Myprintf(int *arr,int len)
{
for (int i = 0; i < len; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
//输入数列,数列的元素个数
void bubblesort(int *arr,int len)
{
// 此处-1是由于n-1次已经拍好序列
for (int i = 0; i < len-1; i++)
{
for (int j = 0; j < len-i-1; j++) //减1是由于不减1在j=n-1时j+1 =n此时数组的下标越界
{
// 从小到大排序
if (arr[j]>arr[j+1])
{
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
Myprintf(arr,len);
}
}
void main()
{
int arr[100];
int n;
cout<<"请输入数组的元素个数:"<<endl;
cin>>n;
cout<<"请输入元素"<<endl;
for (int i = 0; i < n; i++)
{
cin>>arr[i];
}
bubblesort(arr,n);
}
2. 选择排序
无论什么数据进去都是O(n²)的时间复杂度,所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。通常情况下是普通人第一时间想到的结果。
选择排序,选择最小的一个元素,将其和第一个位置的数交换
接着n-1个元素中再找最小的和第二个
不断重复直到有序
选择排序时间复杂度:最好最坏平均时间都是O(n^2) 空间复杂度O(1),复杂度简单,不稳定排序
快希选一堆// 快速,堆排序,选择排序,希尔排序 不稳定排序
选择排序一定是n-1趟排序,比较的次数永远是n(n-1)/2
前边有序后边无序
#include<iostream>
using namespace std;
void selectsort(int *arr,int len)
{
int add;// 记录最小值的下标
// 排序次数n-1轮
for(int i =0;i<len-1;i++)
{
// 标记为最小值,初始设定为第一个值从小到大
add = i;
// 每次排序都要从i+1到尾比较
for (int j = i+1; j < len; j++)
{
if (arr[add]>= arr[j])
{
add =j;//每轮找出最小的数值
}
}
if (i!=add)
{
int tv = arr[i];
arr[i] = arr[add];
arr[add] = tv;
}
for (int i = 0; i < len; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
}
void main()
{
int arr[] ={
100,20,50,80,62,38,65,75,201};
int len = sizeof(arr)/sizeof(arr[0]);
cout<<len<<endl;
selectsort(arr,len);
}
3.插入排序
1.前俩个数据进行从小到大排序
2.将第三个数与拍好顺序的前俩个比较插入合适位置
3.将四个数与前三个比较并插入
4.重复上述步骤至有序
时间: 平均复杂度O(n^2)
最坏:O(n^2)
最好情况O(n)
空间:O(1)
简单复杂度
稳定排序
#include<iostream>
using namespace std;
/*
比较和插入进行实现排序
1.前俩个数据进行从小到大排序
2.将第三个数与拍好顺序的前俩个比较插入合适位置
3.将四个数与前三个比较并插入
4.重复上述步骤至有序
时间: 平均复杂度O(n^2) 最坏:O(n^2) 最好情况O(n)
空间:O(1)
简单复杂度
稳定排序
*/
//从小到大,代码实现
void myprint(int *arr,int len)
{
for (int i = 0; i < len; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
void insertsort(int *arr,int len)
{
for (int i = 1; i < len; i++)
{
int t =arr[i];
int j = i-1;
//判断要插入的位置,找第一个比插入的数小的值,如果比插入的数大就往后移位
//从后往前找插入的位置
while (j>=0&&t<arr[j])
{
arr[j+1]=arr[j];
j--;
}
//如果比插入的数小则插在j指向的位置的下一位
arr[j+1]=t;
myprint(arr,len);
}
}
void main()
{
int arr[8] = {
8,7,5,6,2,4,1,3};
insertsort(arr,8);
}
4.希尔排序
缩小增量排序
将n个元素的数组分成n/2个数字序列,第1个数据和第n/2+1个数据为一对,…
每次循环是每一个序列对排好顺序,变成n/4在排序
不断重复,随着序列减少变为一个,完成排序
减少了数据的交换次数
时间复杂度:O(n^1.3)
空间:O(1)
不稳定排序
复杂排序
#