算法——B/排序

一、冒泡排序

A.冒泡思想

        冒泡排序的思想是每次将最大的一下一下运到最右边,然后将最右边这个确定下来,再来确定第一大的,再确定第三大……

        对于数组a[ ],具体的来说,每次确定操作就是从左往右扫描,如果a[i]>a[i +1],我们就执行swap(a[i],a[i+1])将两项交换,然后再往右检查,这样可以找出最大的并将其丢到最右边。

        第一次确定操作是将a[1]~a[n]中最大的放到a[n];第二次确定操作是将a[1]~a[n-1]中最大的放到a[n-1]。依此类推(类似地,如果你想先把最小的放到左边也是可以的)时间复杂度为O(n^2)。由于排序过程中,数字像冒泡泡一样从左往右换过去,故名冒泡排序。

B.冒泡实现

        冒泡排序一般用双重循环来实现。在这里 i 表示每次操作的右边界,也是存放当前操作最大值的位置。虽然 j 的范围是到 i-1,实际上 j+1 会到 i,所以可以使得操作是正确的。

二、选择排序

A.选择思想

        选择排序的思想和冒泡排序类似,是每次找出最大的然后直接放到右边对应位置,然后将最右边这个确定下来(而不是一个一个地交换过去)再来确定第二大的、第三大的……对于数组a[ ],具体来说,每次确定操作(假设当前要确定的是i位置)就是从左往右扫描计算出最大元素的下标max_id,最后执行一次swap(a[max_id],a[])将两项交换即可。

第一次确定操作是将a[1]~a[n]中最大的放到a[n];

第二次确定操作是将a[1]~a[n-1]中最大的放到a[n-1]。

依此类推(类似地,如果你想先把最小的放到左边也是可以的),时间复杂度为O(n^2)。

B.选择排序实现

选择排序一般用双重循环来实现。
max_id表示最大元素的下标。
这里要注意的细节是j的范围是[1,i],
而在冒泡排序中j的范围是[1,i-1]

三、插入排序

A.插入思想

        插入排序是一种简单直观的排序算法,其基本思想是将待排序的元素逐个插入到已排序序列的合适位置中,使得已排序序列逐渐扩大,从而逐步构建有序序列,最终得到完全有序的序列。
它类似于我们打扑克牌时的排序方式,将一张张牌插入到已经有序的手牌中时间复杂度为O(n^2)。

B.插入排序的实现

        插入排序一般用双重循环来实现:初始时我们认为长度为1的数组a[1]是有序的(显然)然后将a[2]插入到合适的位置,使得a[1~2]有序,然后将a[3]插入,使得a[1~3]有序….直至a[1~ n]有序。

四、快速排序

A.快排思想

        快速排序是一种基于分治法的排序方法,原理是将一个数组分成两个子数组,其中一个子数组的所有元素都小于另一个子数组的元素然后递归地对这两个子数组进行排序。
        快速排序的思想是通过不断地将数组分成两个子数组,递归地对子数组进行排序,最终得到一个有序的数组。这个过程通过选择合适的基准和分区操作来实现。
快速排序拥有更好的时间复杂度Q(n log n),且不需要额外空间。

五、归并排序

A.归排思想

归并排序和快速排序类似,也是一种基于分治法的排序方法。
原理是将一个数组分成两个子数组,将子数组向下递归的排序后(当数组中仅有一个元素时无需再排序,直接返回)得到两个有序数组,然后进行O(n)的合并,最终合并成有序的原数组。
快速排序拥有较好的时间复杂度O(nlogn),但需要额外的空间用于合并数组O(n)。

六、桶排序

        桶排序(Bucket sort)是一种非比较的排序算法。桶排序采用了一些分类和分治的思想,把元素的值域分成若干段,每一段对应一个桶。在排序的时候,首先把每一个元素放到其对应的桶中,再对每一个桶中的元素分别排序,再按顺序把每个桶中的元素依次取出,合并成最终答案。

你可能感兴趣的:(算法,排序算法,数据结构,算法)