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

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

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

posted on 2013-12-18 21:20  winlrou  阅读(215)  评论(0编辑  收藏  举报