- 前言
- 简单排序算法
- 1.冒泡排序
- 2.选择排序
- 3.插入排序
- 三种简单排序算法总结
常用的排序算法有7种,按照算法的复杂度分为两大类:
1、简单算法:冒泡排序、选择排序、插入排序
2、优化算法:希尔排序、堆排序、归并排序、快速排序
本文主要讲解和分析这3种简单排序算法。在这之前,还要先介绍一些排序算法的稳定性:假设一个序列中有nums[a]=nums[b],并且a
简单排序算法
1.冒泡排序
冒泡排序是一种交换排序,它的基本思想是:两两比较相邻的值,如果反序则进行交换,直到没有反序的记录为止,可以归结为比较、交换。以升序为例,从第一个元素开始,依次比较相邻两个元素的值,如果nums[j]>nums[j+1],则进行交换,这样下来就会选出最大的元素放到最后一个位置上。有n个元素,则需要进行n-1次迭代。
C++代码:
vector<int> BubbleSort(vector<int>& nums)
{
int len = nums.size();
for (int i = 1; i < len ; i++)//i表示迭代次数,n个元素需要进行n-1次迭代
{
for (int j = 0; j < len -i; j++)//j表示元素位置,第i次迭代的时候只需要进行n-i次比较
{
if (nums[j] > nums[j + 1])
{
int tmp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = tmp;
}
}
}
return nums;
}
复杂度分析:
冒泡排序,不论是一个怎么样的序列,都需要进行n*(n-1)/2次比较,交换次数视原始序列而定,若是一个排好序的数组,则无需交换,若是一个逆序的数组,则需要交换n*(n-1)/2次,复杂度为O(n²)。
稳定性分析
冒泡排序是稳定的排序算法。
选择排序的思想是:通过n-i次的比较,在n-i+1个元素中找到最小的一个,记为nums[min],将nums[min]与nums[i-1]进行交换,同冒泡排序一样,可以总结为比较、交换。如第一次遍历所有的n个元素,找到最小的元素nums[min],将nums[min]和nums[0]进行交换。
C++代码:
vector<int> SelectSort(vector<int>& nums)
{
int len = nums.size();
for (int i = 0; i < len - 1; i++)
{
int min = i;
for (int j = i + 1; j < len; j++)
{
if (nums[j] < nums[min])
{
int tmp = nums[j];
nums[j] = nums[min]
nums[min] = tmp;
}
}
}
return nums;
}
复杂度分析:
对于一个有n个元素的序列,需要进行n*(n-1)/2次比较,交换次数为0~n-1,最好的情况就是一个排好序的数组,无需进行交换,对坏的情况就是一个逆序的数组,需要进行n-1次交换,复杂度为O(n²)。
稳定性分析
选择排序不是稳定的排序算法。例如6,5,6,4,2,8这个序列,第一次选择交换的时候,会把第一个6和后面的2进行交换,这样第一个6就换到第二个6后面去了,跟原来的先后顺序发生了改变,因此选择排序是不稳定的排序算法。
插入排序的基本思想是将无序序列插入到有序序列中。基本 *** 作如下:假定nums[0]是已经排序好的序列,则从nums[1]开始,逐个与已排序好的序列进行对比。
C++代码:
vector<int> InsertSort(vector<int>& nums)
{
int len = nums.size();
for (int i = 1; i < len; i++)//认为nums[0]是已经排好序的序列
{
if (nums[i] < nums[i - 1])//将当前元素与前一个元素比较,若是比前一个小,则依次往前查找至当前元素应在的位置
{
int tmp = nums[i];
int j;
for (j = i - 1; j >= 0 && tmp < nums[j]; j--)
{
nums[j + 1] = nums[j];
}
nums[j + 1] = tmp;
}
}
return nums;
}
复杂度分析:
最好的情况是拿到的序列本身就是有序的,需要比较和移动次数均为n;最坏的情况是拿到的序列是倒序的,需要移动和比较的次数是n(n-1)/2。平均时间复杂度为O(n²)。
稳定性分析
插入排序算法是稳定的排序算法,插入过程中序列元素的先后顺序不会被改变。
三种简单排序算法总结1.冒泡排序、插入排序都是稳定的排序算法,选择排序是不稳定的排序算法。
2.冒泡排序、选择排序、插入排序这三种算法的时间复杂度都是O(n²),但是选择排序法要优于冒泡排序法,因为交换的次数少;插入排序要优于冒泡排序,因为在进行交换的时候,冒泡排序需要进行三次赋值 *** 作,而插入排序只需要进行一次赋值 *** 作:
//冒泡排序
if (nums[j] > nums[j + 1])
{
int tmp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = tmp;
}
//插入排序
for (j = i - 1; j >= 0 && tmp < nums[j]; j--)
{
nums[j + 1] = nums[j];
}
综上所述,在这三种简单排序算法中,性能最好的是插入排序算法。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)