基础排序算法学习

学习三种简单排序(冒泡排序,选择排序,插入排序)

  • 三种排序算法都假定了数组作为数据存储结构

冒泡排序

代码如下

public class bubbleSort {

    public static class ArrayBub {
        private long[] a;
        private int nElmes;

        public ArrayBub(int max) {
            a = new long[max];
            nElmes = 0;
        }

        public void insert(long value) {
            a[nElmes] = value;
            nElmes++;
        }

        public void display() {
            for (int j = 0; j < nElmes; j++) {
                System.out.print(a[j] + " ");
            }
            System.out.println("");
        }

        public void bulleSort() {
            int out, in;

            for (out = nElmes - 1; out > 1; out--) {
                for (in = 0; in < out; in++) {
                    if (a[in] > a[in + 1])
                        swap(in, in + 1);
                }
            }
        }

        private void swap(int one, int two) {
            long temp = a[one];
            a[one] = a[two];
            a[two] = temp;
        }

    }

    public static void main(String[] args) {
        int maxSize = 100;
        ArrayBub arr;
        arr = new ArrayBub(maxSize);

        arr.insert(77); // insert 10 items
        arr.insert(99);
        arr.insert(44);
        arr.insert(55);
        arr.insert(22);
        arr.insert(88);
        arr.insert(11);
        arr.insert(00);
        arr.insert(66);
        arr.insert(33);

        arr.display();

        arr.bulleSort();
        arr.display();
    }
}

其中冒泡算法的核心代码

public void bulleSort() {
            int out, in;

            for (out = nElmes - 1; out > 1; out--) {
                for (in = 0; in < out; in++) {
                    if (a[in] > a[in + 1])
                        swap(in, in + 1);
                }
            }
        }

这个算法的思路是将最小的数据放在数组的最开始(数组的下标为0),并将最大的数据项放在数组的最后(数组下标为nElems-1)。外层for循环计数器out从数组的最后开始,即out等于nElems-1,没经过依次循环out减一。下标大于out的数据项都是已经排序号的。变量out子啊每完成一次内循环(计数器为in)后就左移一位,因此算法就不在处理那些已经排好序的数据了。
内层for循环计数器in从数据的最开始算起,即in= 0,每完成一次,内部循环体就加一,当它等于out时就结束一次循环。在内层for循环体中,数组下标为in和in+1的两个数据项进行比较,如果下标为in的数据项大于下标为in+1的数据项,则交换两个数据项。

一般来说,数组中有N个数据项,则第一趟排序中有N-1次比较,第二趟中有N-2次,以此类推,这种序列求和的公式为:
(N-1)+(N-2)+(N-3)+。。。+(N-N) =N*(N-1)/2

冒泡排序的运行需要O(N^2)时间级别。

大O表示法为比较算法的速度提供了一种方便的方法。
O(1)级时间的算法是最好的,O(logN)次之,O(N)为一般,O(N^2)最差
这里写图片描述

选择排序

代码如下:

package com.exercise.dataStructureTest;

import com.exercise.dataStructureTest.bubbleSort.ArrayBub;

public class selectSort {

    public static class ArraySel {
        private long[] a;
        private int nElmes;

        public ArraySel(int max) {
            a = new long[max];
            nElmes = 0;
        }

        public void insert(long value) {
            a[nElmes] = value;
            nElmes++;
        }

        public void display() {
            for (int j = 0; j < nElmes; j++) {
                System.out.print(a[j] + " ");
            }
            System.out.println("");
        }

        public void selectionSort() {
            int out, in, min;
            for (out = 0;  out< nElmes; out++) {
                min = out;
                for (in = out+1;  in< nElmes; in++) {
                    if(a[in]<a[min]){
                        min = in;
                    }
                    swap(out,min);
                }
            }
        }

        private void swap(int one, int two) {
            long temp = a[one];
            a[one] = a[two];
            a[two] = temp;
        }

    }

    public static void main(String[] args) {
        int maxSize = 100;
        ArraySel arr;
        arr = new ArraySel(maxSize);

        arr.insert(77); // insert 10 items
        arr.insert(99);
        arr.insert(44);
        arr.insert(55);
        arr.insert(22);
        arr.insert(88);
        arr.insert(11);
        arr.insert(00);
        arr.insert(66);
        arr.insert(33);

        arr.display();

        arr.selectionSort();
        arr.display();
    }
}

核心代码如下:

public void selectionSort() {
            int out, in, min;
            for (out = 0;  out< nElmes; out++) {
                min = out;
                for (in = out+1;  in< nElmes; in++) {
                    if(a[in]<a[min]){
                        min = in;
                    }
                    swap(out,min);
                }
            }
        }

外层循环用循环变量out,从数组开头开始(数组下标为0)向高位增长。内层循环用循环变量in,从out所致的位置开始,同样是向右移动。
在每一个in的新位置,数据项a[in],和a[min]进行比较。如果a[in]更小,则min被赋值为in的值。在内层循环的最后,min指向最小的数据项,然后交换out和min指向的数组数据项。

选择排序的效率

选择排序和冒泡排序执行了相同此数的比较N*(N-1)/2.所以结论是选择排序和冒泡排序一样运行了O(N^2)时间。但是排序无疑更快,因为他进行的交换少得多。当N值较小时,特别是如果交换的时间级比比较的时间大的多时选择排序实际上是相当快的的。

插入排序

public class InsertSortApp {

    public static class ArrayIns {
        private long[] a;
        private int nElmes;

        public ArrayIns(int max) {
            a = new long[max];
            nElmes = 0;
        }

        public void insert(long value) {
            a[nElmes] = value;
            nElmes++;
        }

        public void display() {
            for (int j = 0; j < nElmes; j++) {
                System.out.print(a[j] + " ");
            }
            System.out.println("");
        }

        public void insertionSort() {
            int out, in;
            for (out = 1; out < nElmes; out++) {
                long temp = a[out];
                in = out;
                while (in > 0 && a[in - 1] >= temp) {
                    a[in] = a[in - 1];
                    --in;
                }
                a[in] = temp;
            }
        }
    }

    public static void main(String[] args) {
        int maxSize = 100;
        ArrayIns arr;
        arr = new ArrayIns(maxSize);

        arr.insert(77); // insert 10 items
        arr.insert(99);
        arr.insert(44);
        arr.insert(55);
        arr.insert(22);
        arr.insert(88);
        arr.insert(11);
        arr.insert(00);
        arr.insert(66);
        arr.insert(33);

        arr.display();

        arr.insertionSort();
        arr.display();
    }

核心代码如下

public void insertionSort() {
            int out, in;
            for (out = 1; out < nElmes; out++) {
                long temp = a[out];
                in = out;
                while (in > 0 && a[in - 1] >= temp) {
                    a[in] = a[in - 1];
                    --in;
                }
                a[in] = temp;
            }
        }

在外层的for循环中,out变量从1开始,向右移动,他标记了未排序部分的最左端的数据。而在内层的while循环中,in变量从out变量开始,向左移动,知道temp变量小于in所指的的数组数据项。或者它已经不能再往左移动为止。while循环的每一趟都向右移动了一个已排序的数据项。

在每趟结束时,在将temp位置的项插入后,比outer变量下标号小的数据项都是局部有序的。

插入排序的效率

对于随机顺序的数据进行插入排序也需要O(N^2)的时间级
对于已经有序或基本有序的数据来说,插入排序要好得多。当数据有序的时候,while循环的条件总是加,所以它变成了外层循环中的一个简单语句,执行N-1次。在这种情况下。算法运行只需要O(N)时间。如果数据基本有序,插入排序只需要O(N)的时间,这对于一个基本有序的文件进行排序是一个简单而有效的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fighting_Boss_Hao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值