数据结构学习笔记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.交换两个数据项,或者复制其中一项;

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

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

你可能感兴趣的:(数据结构)