zoukankan      html  css  js  c++  java
  • 数据结构学习笔记1--简单排序

    一.冒泡排序

    冒泡排序是运行最慢点排序算法,但是确实最简单的。

    下图可以理解为队员排队。

    image

    image

    遵循的规则:

    1. 比较两个队员。

    2. 如果左边的队员高,则两队员位置交换。

    3. 向右移动一个位置,比较下面的两个队员。

    参照这样比较下去,虽然没有把所有队员位置排好,但是最高的队员已经在最右边的位置(如图d),此时,已经完成了第一趟排序,进行了N-1次比较。

    现在重新回到队伍的最左端,开始第二趟排序,需要比较N-2次,完成后,第二高的队员已经在倒数第二的位置上。

    不断执行这个过程,直到所有的队员都排定。

    需要记住的2点:

    1.相邻的两个数据比较。

    2.一趟比较下来后,数组最右边的数据是有序的。

    代码:主要代码逻辑

        /**
        *冒泡排序实现 
        *@param arr 传入数组   
    */
        public static void bubbleSort(int[] arr)
        {
            for (int i = arr.length-1; i > 0; i--) // 比较次数,第一趟排序比较N-1次,第二趟比较N-2次
            {
                for (int j = 0; j < i; j++) // 执行比较
                {
                    if (arr[j] > arr[j + 1])
                    {
                        // 交换
                           int temp = 0;
                        temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
            }
        }

    效率:

    冒泡排序大约执行N2/2次比较,执行N2/4次交换,用大O表示法,时间复杂度为O(N2)。

    二.选择排序

    选择排序比冒泡排序快,主要因为排序中交换只进行了一次。

    思路:

    1.排序从最左边的队员开始,在本子上记录最左端队员的身高,并且把标记该球员位置。

    2.然后取下一个队员的身高与本子上的值比较。

    (1)如果这个队员的身高更矮,则本子上划掉记录队员的身高数据,记录该队员的身高,并把标记移到该队员位置。

    (2)如果这个队员更高,取下一个队员身高。

    3.重复第2步,知道所有队员的身高都比较完成。此时,本子上记录的身高是矮的队员,标记记录这个队员所在的位置。

    将这个队员与最左边的队员交换,这样,左边的队员身高是有序的(至少第一个队员是有序的)。

    此时,总共进行了N-1次比较,1次交换。

    需要记住的:

    1.记录从最左端开始,记录未排序的第一个队员身高作为初始数据。

    2.比较过程中,出现更矮的队员,刷新记录,并标记其位置。

    3.交换只进行一次。

    image

    image

    第二趟排序所做的事情是一模一样的,只不过忽略了第一个队员,从第二个队员开始(即初始本子上记录的是第二个队员的身高),

    此时,总共进行N-2次比较,1次交换。

    重复上述步骤,直到所有队员排序完成。

    代码:

        /**
         * 选择排序实现
         * 
         * @param arr 传入数组
         */
        public static void selectSort(int[] arr)
        {
            for (int i = 0; i < arr.length - 1; i++) // 比较次数,第一趟排序比较N-1次,第二趟比较N-2次
            {
                // 标记队员身高的min位置,不记录值
                 int min = i;
                for (int j = i + 1; j < arr.length; j++)
                {
                    // 如果发现有队员身高比记录的要矮,则队员位置赋值给min
                    if (arr[j] < arr[min])
                    {
                        min = j;
                    }
                }
    
                // 左边数据与最小值数据交换
                 int temp = 0;
                temp = arr[min];
                arr[min] = arr[i];
                arr[i] = temp;
            }
        }

    效率:

    选择排序比较次数与冒泡排序一样,平均比较N2/2次,但是交换平均N/2次,但是如果N(数据量)很大,时间复杂度仍然为O(N2)。

    三.插入排序

    插入排序是这三个排序算法中最好的一种,一般情况下,比冒泡排序快一倍,比选择排序还要快点。

    插入排序的特点是:

    1.局部有序

    2.需要额外腾出个空位存储数据。

    image

    image

    我们需要在已经排好序的队员中插入被标记的队员。此时

    1.需要将标记队员位置“腾”出空位来。

    2.从标记队员左边第一个队员开始,将左边队员身高与标记队员的身高比较。

    (1)如果身高比标记的队员高,则将队员向右移动。

    (2)如果身高比标记的队员矮,则停止移动。

    3.重复步骤2,直到找到比标记队员矮的,或者没有队员比较为止,此时,就已经找到了标记队员应该处在的位置。

    代码:

        /**
         * 插入排序算法实现
         * 
         * @param arr 待排序数组
         */
        public static void insertSort(int[] arr)
        {
            for (int i = 1; i < arr.length; i++) // i从1开始,是因为认为arr[0]是已经排好序的
            {
                // 腾出的空位存储临时队员的身高
                 int temp = arr[i];
                
                // i为标记的队员位置
                 int j = i; 
                
                // 遍历左边已经排好的数据,查找到合适的位置
                  while (j > 0 && arr[j - 1] >= temp)
                {
                    // 将比标记的大的值右移
                    arr[j] = arr[j - 1];
                    --j;
                }
                
                //将临时存储的变量写入到数组中
                 arr[j] = temp;
            }
        }

    效率:

    插入排序算法中,平均比较了N*(N-1)/2次,交换了N次,所以时间复杂度为O(N2)。

    总结:

    简单排序需要用到步:

    1.比较两个数据项;

    2.交换两个数据项,或者复制其中一项;

    简单排序中插入排序效果是最好的,但是在完成数据量排序的时候消耗的时间还是很长。

    这三个排序方法很简单,对于一般小数据使用没问题,大数据量就需要高级排序方法了,比如希尔排序,快速排序,堆排序等。

  • 相关阅读:
    【实战】如何实现滚轮时间的显示
    NSDate的常用用法
    UIDatePicker的简单用法
    NSDateFormatter相关整理
    UIPickerView
    回家任务
    addTarget:self 的意思是说,这个方法在本类中
    2020/2/25
    树上启发式合并
    题解
  • 原文地址:https://www.cnblogs.com/winlrou/p/3481077.html
Copyright © 2011-2022 走看看