选择,插入,冒泡,二分法,归并,希尔排序算法合集演示及标注

来源:互联网 发布:中兴通讯数据分析 编辑:程序博客网 时间:2024/06/05 08:12

1.选择排序


理解核心思想,取出一个元素,在它后面的每一位中进行比较,选择出一个最小/最大的元素,来与它交换。



代码示例

//比较    public static boolean less(int a, int b) {        if (a > b)            return true;        return false;    }    //交换    public static void exch(int[] num, int i, int j) {        int temp = num[i];        num[i] = num[j];        num[j] = temp;    }    //排序    public static void sort(int[] num) {        for (int i = 0; i < num.length; i++) {            int min = i;            // 除开i坐标的前面的元素            for (int j = i + 1; j < num.length; j++)                // 注意理解这里两个比较对象。                // 后面的每一个元素与min坐标比较。                // 目的是找出比min坐标还小/大的值                if (less(num[j], num[min]))                    min = j;            // 进行交换            exch(num, i, min);        }    }


总结

第一步,设置标记

比较出最小/最大

交换标记点下标与比较的元素。


2.插入排序


理解核心思想,取出一个元素,比较它之前的元素,进行两两交换。由于一开始就是这样操作,保证了前面的数组具有有序性,从而进行交换后一样保持有序。



代码示例


//比较    public static boolean less(int a, int b) {        if (a > b)            return true;        return false;    }    //交换    public static void exch(int[] num, int i, int j) {        int temp = num[i];        num[i] = num[j];        num[j] = temp;    }    //排序    public static void sort(int[] num) {        for (int i = 0; i < num.length; i++) {            //比较当前i,之前的元素,进行两两交换操作。(关键)            for (int j = i; j > 0 && less(num[j], num[j - 1]); j--)                exch(num, j, j - 1);        }    }


总结

比较两两元素,满足条件交换。


3.快速排序(二分法排序)


理解核心思想,选取第一位作为标记,经过一次排序后,将这个数组分为两个部分(无序的),左边的小于标记,右边的大于标记。选取第二位,重复上面操作。最终整个数组有序。


fd

public static void sort(int[] num) {        sort(num, 0, num.length - 1);    }    public static void sort(int[] num, int left, int right) {        int pos;        if (left < right) {            //算出中间位置            pos = pos(num, left, right);            //以中间位置进行分割成两部分            sort(num, left, pos - 1);            sort(num, pos + 1, right);        }    }    public static int pos(int[] num, int left, int right) {        int temp = num[left];        while (left < right) {            //右边开始寻找,与标记点比较            while (left < right && num[right] >= temp)                right--;            //发现比标记点小。将右边的小值赋值给左边,并且将左边的下标向前移位。因为下面代码要从左边搜索了。            if (left < right)                num[left++] = num[right];            //左边开始寻找,与标记点比较            while (left < right && num[left] <= temp)                left++;            //发现比标记点大,将左边的大值赋值给右边,并且将右边的下标--,因为代码要从右边搜索了。            if (left < right)                num[right--] = num[left];        }        //最终完成,最后一步是左边的值赋值给右边,所以此时的left就处于中间位置。我们将标记点值赋值给它,        num[left] = temp;        //返回分割点。        return left;    }    public static void main(String[] args) {        int[] num = new int[20];        Random random = new Random();        for (int i = 0; i < 20; i++) {            num[i] = random.nextInt(100);        }        sort(num);        for (int i :                num) {            System.out.print(i + "\t");        }        System.out.println();    }


总结

标记点

右边小的赋值给左边,左边大的赋值给右边

确定中间点,赋值标记点值,返回下标


4.希尔排序


理解核心思想,增量概念,每次在增量间比较,以及交换。缩小增量,重复比较,交换。利用的插入排序算法。

public void sort(int[] nums) {        /** 结合了插入排序 **/        /** 数字长度N **/        int N = nums.length;        /** 确认间隔长度 **/        int h = 3;        while (h < N / 3) h = 3 * h + 1;        while (h >= 1) {            /** 注意需要从i=h开始 i++ **/            for (int i = h; i < N; i++)            /** j=i开始 **/                for (int j = i; j >= h && less(nums[j], nums[j - h]); j -= h)//插入排序                    exch(nums, j, j - h);            h = h / 3;        }    }


总结

理解快速排序,改变其增量即可。


5.归并排序


理解核心思想,归并排序,类似于分支法解决问题,将一个长度很长的数组,从中间分开,分成两半,取一半,重复上述操作即可。最终变成长度为2的数组,比较后,进行交换,在末端保持了有序性。继而整体保持了有序性。


    /**     * @param nums     */    public void sort(int[] nums) {        sort(nums, 0, nums.length - 1);    }    public void sort(int[] nums, int low, int high) {        int mid = low + (high - low) / 2;        if (low < high) {            /** 左边排序 **/            sort(nums, low, mid);            /** 右边排序 **/            sort(nums, mid + 1, high);            merge(nums, low, mid, high);        }    }    private void merge(int[] nums, int low, int mid, int high) {        int[] temp = new int[high - low + 1];        int i = low;        int j = mid + 1;        int k = 0;        /** 两边合并**/        while (i <= mid && j <= high) {            if (nums[i] < nums[j]) {                temp[k++] = nums[i++];            } else {                temp[k++] = nums[j++];            }        }        /** 左边多余的合并 **/        while (i <= mid) {            temp[k++] = nums[i++];        }        /**  右边多余的合并 **/        while (j <= high) {            temp[k++] = nums[j++];        }        /** 拷贝合并后的数到原数组 **/        for (int k2 = 0; k2 < temp.length; k2++)            nums[low + k2] = temp[k2];    }

总结

实现末端长度为2的数组,进行比较交换,保持了底层有序,进而整体有序。


 6.堆排序

理解核心思想,将数组理解成逻辑完全二叉树结构。仅仅是逻辑结构,实际还是以数组形式保存。有逻辑关系式,父节点与子节点之间关系,p(i)=c(2*i+1)|c(2*i+2),很重要。

public static void sort(int[] n) {        for (int i = 0; i < n.length; i++) {            createMaxHeap(n, n.length - 1 - i);            exch(n, 0, n.length - 1 - i);        }    }    public static void createMaxHeap(int[] n, int lastIndex) {        int pIndex = (lastIndex - 1) / 2;        for (int i = pIndex; i >= 0; i--) {            int k = i;            while (2 * k + 1 <= lastIndex) {                int cIndex = 2 * k + 1;                if (cIndex < lastIndex)                    if (n[cIndex] < n[cIndex + 1])                        cIndex++;                if (n[k] < n[cIndex]) {                    exch(n, cIndex, k);                    k = cIndex;                } else {                    //关键的,跳过,上一级父节点                    break;                }            }        }    }

总结
堆排序,没什么的说的。自己跟着代码逻辑,自己画图,理解,自然就理会了。一定要自己跟着代码走一遍。化图解。


7.计数排序

理解核心思想,统计每个元素出现的个数,然后以n-m有序数,来排序。(讲起来有点难懂)

public static void sort(int[] n) {        int max = n[0];        int min = max;        for (int i = 0; i < n.length; i++) {            if (max < n[i])                max = n[i];            if (min > n[i])                min = n[i];        }        int[] c = new int[max - min + 1];        for (int i = 0; i < n.length; i++) {            c[n[i] - min] += 1;        }        for (int i = 0, index = 0; i < max - min + 1; i++) {            for (int j = 0; j < c[i]; j++) {                n[index++] = i + min;            }        }    }

总结
总结什么呢?看代码理会。不懂@我

阅读全文
0 0
原创粉丝点击