排序算法(OC版)

针对每个算法实现的代码没有单独上传到gitHub,有需要的来群里下载<欢迎大家加入iOS开发学习交流群:QQ529560119>

数据结构与算法的作用:

数据结构与算法相当于内功心法,而各种编程语言相当于武功的各种招式例如降龙十八掌等等。内功心法更扎实,打出来的招式才会更有伤害。

排序是计算机内经常进行的一种操作,其目的是将一组"无序"的记录序列调整为"有序"的记录序列。

排序算法是所有算法中最为常见的一种算法,例如,在学校上体育课,站队按照身高从低到高,这是一种排序,高考录取按照分数从高到低降序录取,这是一种排序。

排序的稳定性:假设ki>kj(1<=i<=n,1<=j<=n,i!=j),且在排序前的序列中Ri领先于Rj(即i< j)。如果排序后的Ri仍领先于Rj,则称所用的排序方法是稳定的。反之,若可能使得排序后的序列中Rj领先于Ri,则称所用的排序方法是稳定的。

1  小毛子     700

2  小举子    680

3  小李子    700

4  小张子    650

稳定排序:

1    小毛子     700

3   小李子    700

2   小举子    680

4   小张子    650

影响排序性能的几个要素:

时间性能:比较和移动,一个好的排序要尽可能减少比较和移动。

辅助空间:需要一些辅助空间来存放一些临时数据。

算法的复杂性:算法本身的复杂度,而不是时间复杂度。

算法分类为内部排序和外部排序。若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序。反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序。

今天我们要讲的就是内部排序的几个经典的排序算法:

简单排序:  冒泡排序,选择排序,插入排序

以及这些算法改进之后的希尔排序,堆排序,快速排序。

冒泡排序基本思想:两两相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。是通过对无序序列区中的记录进行相邻记录关键字间的“比较”和记录位置的“交换”实现关键字较小的记录向一头飘移,而关键字较大的记向另一头下沉.

基本要点:

1.两两注意是相邻的两个元素的意思。

2.如果有N个元素需要比较N-1次,每一轮减少1次。

3.起泡排序的结束条件:在某一趟排序过程中没有进行.

------上代码-----

选择排序基本思想:通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(i<=i<=n)个记录交换。

---上代码---

直接插入排序基本思想:将一个记录插入到已经排好序的有序表中,从而得到一个新的,记录数增加1的有序表。

---上代码---

希尔排序基本思想:直接插入算法在记录基本有序或者记录数少的时候,直接插入的优势是很明显的。这两个条件苛刻,这两种情是在特殊情况下存在的。这个时候一个叫希尔的教授作了一些事情,对一个记录分组为若干子序列,然后对若干子序列进行基本的插入排序,这样若干个子序列排序所需要的时间加起来是小于整个记录排序所花的时间。例如,一个完整记录A直接插入排序所花时间是10小时,但是希尔教授将这个序列分为了三个子序列CDE,CDE三个子序列排序所花的时间分别是3,3,3小时,这样加起来也不过是9小时,小于10小时。

看这幅图你看懂了么?

---看代码---

堆排序基本思想:我们首先来回忆一下选择排序,选择排序每次都选择最小的记录,最后变成一个完整有序的记录。那么如果在待排序的N个记录里找到最小的记录,需要 比较多少次呢?答案很简单就是N-1次,为什么这么多次呢?因为一个元素的比较都没有很好的利用上一次比较的结果,导致整个算法下来比较了很多次,从而造成了效率的变低。在冒泡排序的改进算法中很好的利用了上一次比较的结果,增加了一个flag变量避免了很多重复的比较,那么在这里,堆排序就是利用了上一次比较的结果一个很好的实实例。

在这里先介绍一个完全二叉树的概念:如果一个二叉树深度为N层,则N-1层是完全对称的,第N层是从左到右依次连续排开,如下图。

大顶堆概念:每个节点的值都大于或者等于左右节点的值。

小顶堆概念:每个节点的值都小于或者等于左右节点的值。

要点:

1.从以上情况可以得出根节点一定是堆中所有节点最大或者最小者,如果按照层序遍历的方式给结点从1开始编号,则结点之间满足如下关系:

Ki>=K2i且Ki>=K2i+1,或者Ki<=K2i且Ki<=K2i+1.

2.下标i与2i与2i+1是双亲和子女的关系。

3.那么把大顶堆和小顶堆用程序遍历存入数组,则一定要满足下面的表达式:

堆排序就是利用堆进行排序的算法,它的基本思想是:

1.将待排序的序列构造成一个大顶堆或者小顶堆。

2.此时整个序列的最大值就是堆顶的根节点。将它移走。就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值。

3.然后将剩余的N-1个序列重新构成一个堆,这样就会得到N个元素中的最大值。

4.如此反复就能得到一个有序的序列了。

时间: 2024-12-16 11:45:04

排序算法(OC版)的相关文章

排序算法Java版,以及各自的复杂度,以及由堆排序产生的top K问题

常用的排序算法包括: 冒泡排序:每次在无序队列里将相邻两个数依次进行比较,将小数调换到前面, 逐次比较,直至将最大的数移到最后.最将剩下的N-1个数继续比较,将次大数移至倒数第二.依此规律,直至比较结束.时间复杂度:O(n^2) 选择排序:每次在无序队列中"选择"出最大值,放到有序队列的最后,并从无序队列中去除该值(具体实现略有区别).时间复杂度:O(n^2) 直接插入排序:始终定义第一个元素为有序的,将元素逐个插入到有序排列之中,其特点是要不断的 移动数据,空出一个适当的位置,把待插

常见的排序算法--java版

个人总结的常见的排序算法 public class Sort { // 1.冒泡:稳定,最优O(n) 最差O(n^2) 平均O(n^2) private static void sort1(int[] arr) { for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr.length - 1; j++) { if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = ar

经典排序算法 — C# 版(上)

提起排序,与我们的息息相关,平时开发的代码少不了排序. 经典的排序算法又非常多,我们怎么评价一个排序算法的好坏呢? 其实可以这样想,要细致的比较排序算法好坏,那我们就从多方面尽可能详细的对比 一.效率方面 1.排序算法的执行效率:最好.最坏.平均 2. 我们之前舍弃的时间复杂度的系数.常量.低阶,在这里需要拿回来 3.排序,免不了比较和移动 二.内存消耗方面 没错就是 算法的空间复杂度,不过对于排序的空间复杂度来说,又赋予了新的名词 — 原地排序. 顾名思义是 原地排序的肯定是消耗内存少,反之需

排序算法JavaScript版

冒泡排序 function bubbleSort(arr) { var len = arr.length; for (var i = 0; i < len - 1; i++) { for (var j = 0; j < len - 1 - i; j++) { if (arr[j] > arr[j+1]) { // 相邻元素两两对比 var temp = arr[j+1]; // 元素交换 arr[j+1] = arr[j]; arr[j] = temp; } } } return arr

八大排序算法_java版

import java.util.Scanner;/*直接插入排序:依次为每个元素找在以排好序列的位置 *稳定排序(相同元素在排序过程保持之间前后位置不变.) *期望复杂度:O(n2) */ public class InsertSort {        public static void main(String[] args) {        //控制台读入字符串,以逗号分隔 (1,2,3,4)        Scanner scanner = new Scanner(System.in

桶排序 - 算法 - PHP版

<?php //初始化数组,默认值为0; $arr = array(); for ($i = 0; $i <= 10; $i++) { $arr[$i] = 0; } //定义测试数据 $arr1 = array(5, 3, 5, 3, 7); //根据数据 对默认数组的对应元素进行+1 for ($j = 0; $j < count($arr1); $j++) { $arr[$arr1[$j]]++; } //循环输出 for ($k = 0; $k <= 10; $k++) {

排序算法的基本思想和OC代码实现

算法的基本思想和OC代码实现 一 .冒泡排序   (平均时间复杂度 o(N*N))  基本思想:两个数比较大小,较大的数下沉,较小的数冒起来. 过程:比较相邻的两个数据,如果第二个数小,就交换位置 从后向前两两比较,一直到比较最前两个数据.最终最小数被交换到起始的位置,这样第一个最小数的位置就排好了. 继续重复上述过程,依次将第2,3,….,n-1个最小数排好位置. int arr[5]={23,21,45,23,64}; int temp; for (int i=0; i<4; i++) {

排序算法总结(C语言版)

1.    插入排序 1.1     直接插入排序 1.2     Shell排序 2.    交换排序 2.1     冒泡排序 2.2     快速排序 3.    选择排序 3.1     直接选择排序 3.2     堆排序 4.    归并排序 4.1     二路归并排序 4.2     自然合并排序 5.    分布排序 5.1     基数排序 1.插入排序 1.1      直接插入排序 将已排好序的部分num[0]~num[i]后的一个元素num[i+1]插入到之前已排好序的

【JavaScript】【算法】JavaScript版排序算法

JavaScript版排序算法:冒泡排序.快速排序.插入排序.希尔排序(小数据时,希尔排序会比快排快哦) 1 //排序算法 2 window.onload = function(){ 3 var array = [0,1,2,44,4, 4 324,5,65,6,6, 5 34,4,5,6,2, 6 43,5,6,62,43, 7 5,1,4,51,56, 8 76,7,7,2,1, 9 45,4,6,7,8]; 10 //var array = [4,2,5,1,0,3]; 11 array