排序算法个人总结

来源:互联网 发布:怪物猎人角色数据 编辑:程序博客网 时间:2024/06/06 10:42

最近在看算法,自然而然地就看到了排序。下面记录一下自己的学习过程。

一、归并排序

首先我说说我理解的归并算法的核心:归即将数组中分为小部分的集合,其中也即数成为局部有序的集合。然后再将这些有序数组合并起来。

归:一般以中点划分,不断地递归,以使数组有序,其实归和并是交互的。如8个数字,归为4,4。4又归为2,2。2又归为1,1。1,1之后不能再划分,就合并。合并之后是有序的,1,1合并为2,2,2合并为4......如此归并最终整个有序了。那么问题来了:归怎么实现?并又怎么实现?归可以通过递归,不断地划分。这个实现起来不难。并是将两个有序的数组组合在一起,这个组合之后也必须是有序的。将两个有序数组结合为一个有序的数组,从两个数组的开始比较,小的取出来放在temp数组中,指针加一,一直到两个数组都遍历完毕即完成了组合。

二、快速排序

我先说一下快速排序的核心:引用白话经典算法的作者所说的就是填坑以实现分治。也就是每轮排序,先选定一个基准数,排序的结果是实现比它大的数放在前面(基准数的左边),比它小的数放在后面(基准数的右边)。一轮排序过后实现基于此基准数的排序。假设i和j分别指向数组的头和尾。那么一轮排序的过程如下:

a.设置基准数为A[i](此时A[i]相当于被挖了个坑)

b.j从后往前遍历,当A[j]<X时,A[i]=A[j];i位置被填,同时j位置被挖。此时先执行个i++;

c.i从前往后遍历,当A[i]>X时,A[j]=A[i];j位置被填,同时i位置被挖。此时先执行个j--;如果i==j时,A[i]=X,本轮循环结束。否则继续执行b,c两步,直到i==j时,A[i]=X;

当执行完一遍快排后,基于基准数左右两边是分治的。左边的小于基准数,右边的大于基准数。再对左右两边做快排,递归调用最终就实现了排序的功能。

其实快排的思想说的直白点:也即基于基准数,小的放前面(基准数的左边)、大的放右边(基准数的右边)。通过不断递归、不断选取基准数使得数组有序。

三、堆排序

用于排序的堆分为:大根堆和小根堆。它们都是二叉堆,其实也就是类似二叉树的另一个说法。我们进行堆排序的第一步:将数组堆化。数组堆化也即将数组化为大根堆或者小根堆。数组可以看成一个二叉堆,但必须经过堆化才能化为标准的大根堆或者小根堆。二叉堆的叶子节点一般认为是合乎规定的子堆。只需从(n/2-1)到0进行堆化即可。也即不断调整(n/2-1)到0的结点的值,以使堆为标准的大根堆或者小根堆。然后进行堆排序的第二步:取根节点的值,将堆进行重新调整。然后不断递归。标准大根堆的根节点即是最大的数,取出根节点的数,将数组最后一个数与之互换,即完成了将最大的数放置于最后。每次取根节点并与堆最后的数互换,这样因为每次取的结点都是剩余中最大的,这样就完成了一个可序化的排列了。

其实堆排序简单来说:就是化为标准堆结构(大根堆或者小根堆),再不断取根节点放在数组最后,然后调整堆为标准堆,进而不断循环最终得到的就是排好序的数组。

0 0
原创粉丝点击