• 分组排序的一个实现


    问题如下:

    有一排红黑混合的球,标有重复数字无序排列,例如:{R3, R1, B2, B4, R1, R4, R2, B1, B3, B2, B1}。现在希望进行先红后黑由小到大的排序,并且这些球原先所在位置的下标要由小到大(红黑区别)

    思路如下:

    1、此题目主要考察对排序算法中的稳定排序的熟悉程度
    2、稳定排序中主要考虑冒泡和归并(JDK中的Arrays.sort就是使用mergeSort)两种排序


    Ball类

    import lombok.Data;
    
    @Data
    public class Ball {
    
        private Integer id; // 球号码
    
        private String color; // red || black
    
        private Integer index; // 球下标
    
        public Ball() {}
    
        public Ball(Integer id, String color) {
            this.id = id;
            this.color = color;
        }
    
        public Ball(Integer id, String color, Integer index) {
            this.id = id;
            this.color = color;
            this.index = index;
        }
    
    }
    

    冒泡排序的实现如下:

    import com.alibaba.fastjson.JSON;
    import com.google.common.collect.Lists;
    import lombok.Data;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    @Data
    public class BallBubbleSort {
    
        private Map<String, Ball[]> result = new HashMap<String, Ball[]>();
    
        public Map<String, Ball[]> sort(Ball[] balls) {
            Ball[] reds = assemblyBallArray(balls, "Red");
            Ball[] blacks = assemblyBallArray(balls, "Black");
    
            bubbleSortLowAndHigh(reds);
            bubbleSortLowAndHigh(blacks);
    
            Map<String, Ball[]> result = new HashMap<String, Ball[]>();
            result.put("Red", reds);
            result.put("Black", blacks);
            return result;
        }
    
        public void sort2(Ball[] balls) {
            Ball[] reds = assemblyBallArray(balls, "Red");
            Ball[] blacks = assemblyBallArray(balls, "Black");
    
            bubbleSortLowAndHigh(reds);
            bubbleSortLowAndHigh(blacks);
    
            result.put("Red", reds);
            result.put("Black", blacks);
        }
    
        public Ball[] assemblyBallArray(Ball[] balls, String type) {
            List<Ball> res = Lists.newArrayList();
            for (Ball ball : balls) {
                if (ball.getColor().equals(type)) res.add(ball);
            }
            return res.toArray(new Ball[res.size()]);
        }
    
        /*public Ball[] assemblyBallArray(Ball[] balls, String type) {
            List<Ball> ballList = null;
            if (ballList == null) {
                ballList = Lists.newArrayList();
                for (Ball ball : balls) {
                    if (ball.getColor().equals(type)) ballList.add(ball);
                }
            }
            List<Ball> res = ballList;
            ballList = null;
            return res.toArray(new Ball[res.size()]);
        }*/
    
        public void bubbleSortBall(Ball[] balls) {
            for (int k = 0; k < balls.length; k++) {
                balls[k].setIndex(k);
            }
    
            for (int i = 0; i < balls.length - 1; i++) {
                for (int j = 0; j < balls.length - i - 1; j++) {
                    if(balls[j].getId() > balls[j+1].getId()) {
                        Ball tmp = balls[j];
                        balls[j] = balls[j+1];
                        balls[j+1] = tmp;
                    }
                }
            }
        }
    
        public void bubbleSortBallOptimizePos(Ball[] balls) {
            for (int k = 0; k < balls.length; k++) {
                balls[k].setIndex(k);
            }
    
            int arrLen = balls.length - 1; //初始时,最后位置保持不变
            while (arrLen > 0) {
                int pos = 0; //每趟开始时,无记录交换
                for (int i = 0; i < arrLen; i++) {
                    if(balls[i].getId() > balls[i + 1].getId()) {
                        pos = i; //记录交换的位置
                        Ball tmp = balls[i];
                        balls[i] = balls[i + 1];
                        balls[i + 1] = tmp;
                        System.out.println("pos -> " + pos);
                    }
                }
                arrLen = pos; //为下一趟排序作准备
                System.out.println("arrLen -> " + arrLen);
            }
        }
    
        public void bubbleSortLowAndHigh(Ball[] balls) {
            for (int k = 0; k < balls.length; k++) {
                balls[k].setIndex(k);
            }
    
            int low = 0;
            int high= balls.length-1; //设置变量的初始值
            int j = 0;
            Ball tmp = null;
            while (low < high) {
                for (j = low; j < high; ++j) { //正向冒泡,找到最大者
                    if (balls[j].getId() > balls[j + 1].getId()) {
                        tmp = balls[j]; balls[j]=balls[j + 1];balls[j + 1]=tmp;
                    }
                }
                --high; //修改high值, 前移一位
                for (j = high; j>low; --j) { //反向冒泡,找到最小者
                    if (balls[j].getId() <balls[j - 1].getId()) {
                        tmp = balls[j]; balls[j]=balls[j - 1];balls[j - 1]=tmp;
                    }
                }
                ++low; //修改low值,后移一位
            }
        }
    
        public static void main(String[] args) {
    
            Ball R1 = new Ball(1, "Red");
            Ball R2 = new Ball(3, "Red");
            Ball R3 = new Ball(4, "Red");
            Ball R4 = new Ball(2, "Red");
            Ball R5 = new Ball(1, "Red");
    
    
            Ball B1 = new Ball(2, "Black");
            Ball B2 = new Ball(4, "Black");
            Ball B3 = new Ball(1, "Black");
            Ball B4 = new Ball(3, "Black");
    
            Ball[] balls = {R3, R1, B2, B4, R4, B1, R2, B3, R5};
    
    
            BallBubbleSort ballBubbleSort = new BallBubbleSort();
    
            ballBubbleSort.sort2(balls);
    
            System.out.println(JSON.toJSONString(ballBubbleSort.getResult()));
    
    //        System.out.println(JSON.toJSONString(ballBubbleSort.sort(balls)));
    
            /* 默认冒泡算法复杂度 */
    
            int[] a = {3, 1, 4, 1, 2};
    
            int countOutside1 = 0;
            int countInside1 = 0;
            for(int i =0 ; i< a.length-1; i++) {
                countOutside1++;
                for(int j = 0; j < a.length-i-1; j++) {
                    countInside1++;
                    if(a[j] > a[j+1])
                    {
                        int tmp = a[j] ; a[j] = a[j+1] ;  a[j+1] = tmp;
                    }
                }
            }
            System.out.println(countOutside1);
            System.out.println(countInside1);
    
            /* 第一种改良冒泡算法复杂度 */
    
            int[] b = {3, 1, 4, 1, 2};
    
            int countOutside2 = 0;
            int countInside2 = 0;
            int arrLen = b.length - 1;
            while (arrLen > 0) {
                countOutside2++;
                int pos = 0;
                for (int i = 0; i < arrLen; i++) {
                    countInside2++;
                    if(b[i] > b[i + 1]) {
                        pos = i;
                        int tmp = b[i] ; b[i] = b[i+1] ;  b[i+1] = tmp;
                    }
                }
                arrLen = pos;
            }
            System.out.println("======");
            System.out.println(countOutside2);
            System.out.println(countInside2);
    
            /* 第二种改良冒泡算法复杂度 */
    
            int[] c = {3, 1, 4, 1, 2};
    
            int countOutside3 = 0;
            int countInside3To1 = 0;
            int countInside3To2 = 0;
            int low = 0;
            int high= c.length-1;
            int tmp,j;
            while (low < high) {
                countOutside3++;
                for (j= low; j< high; ++j) {
                    countInside3To1++;
                    if (c[j]> c[j+1]) {
                        tmp = c[j]; c[j]=c[j+1];c[j+1]=tmp;
                    }
                }
                --high;
                for (j=high; j>low; --j) {
                    countInside3To2++;
                    if (c[j]<c[j-1]) {
                        tmp = c[j]; c[j]=c[j-1];c[j-1]=tmp;
                    }
                }
                ++low;
            }
            System.out.println("======");
            System.out.println(countOutside3);
            System.out.println(countInside3To1);
            System.out.println(countInside3To2);
    
            System.out.println("POP Sort ->" + JSON.toJSONString(a));
            System.out.println("POP Sort ->" + JSON.toJSONString(b));
            System.out.println("POP Sort ->" + JSON.toJSONString(c));
        }
    }
    

    归并排序的实现如下:

    import com.alibaba.fastjson.JSON;
    import com.google.common.collect.Lists;
    import lombok.Data;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    @Data
    public class BallMergeSort {
    
        private Map<String, Ball[]> result = new HashMap<String, Ball[]>();
    
        public void mergearray(Ball[] balls, int first, int mid, int last, Ball[] temp) {
            int i = first, j = mid + 1;
            int m = mid,   n = last;
            int k = 0;
    
            while (i <= m && j <= n)
            {
                if (balls[i].getId() <= balls[j].getId())
                    temp[k++] = balls[i++];
                else
                    temp[k++] = balls[j++];
            }
    
            while (i <= m)
                temp[k++] = balls[i++];
    
            while (j <= n)
                temp[k++] = balls[j++];
    
            for (i = 0; i < k; i++)
                balls[first + i] = temp[i];
        }
    
        public void mergesort(Ball[] balls, int first, int last, Ball[] temp) {
            if (first < last)
            {
                int mid = (first + last) / 2;
                mergesort(balls, first, mid, temp);    //左边有序
                mergesort(balls, mid + 1, last, temp); //右边有序
                mergearray(balls, first, mid, last, temp); //再将二个有序数列合并
            }
        }
    
        public boolean MergeSort(Ball[] balls, int n) {
            for (int k = 0; k < balls.length; k++) {
                balls[k].setIndex(k);
            }
    
            Ball[] p = new Ball[n];
            if (p == null)
                return false;
            mergesort(balls, 0, n - 1, p);
            return true;
        }
    
        public void sort(Ball[] balls) {
            for (int k = 0; k < balls.length; k++) {
                balls[k].setIndex(k);
            }
    
            Ball[] reds = assemblyBallArray(balls, "Red");
            Ball[] blacks = assemblyBallArray(balls, "Black");
    
            Ball[] redsTmp = new Ball[reds.length];
            Ball[] blacksTmp = new Ball[blacks.length];
    
            mergesort(reds, 0, reds.length - 1, redsTmp);
            mergesort(blacks, 0, blacks.length - 1, blacksTmp);
    
            result.put("Red", reds);
            result.put("Black", blacks);
        }
    
        public Ball[] assemblyBallArray(Ball[] balls, String type) {
            List<Ball> res = Lists.newArrayList();
            for (Ball ball : balls) {
                if (ball.getColor().equals(type)) res.add(ball);
            }
            return res.toArray(new Ball[res.size()]);
        }
    
        public static void main(String[] args) {
    
            Ball R1 = new Ball(1, "Red");
            Ball R2 = new Ball(3, "Red");
            Ball R3 = new Ball(4, "Red");
            Ball R4 = new Ball(2, "Red");
            Ball R5 = new Ball(1, "Red");
    
    
            Ball B1 = new Ball(2, "Black");
            Ball B2 = new Ball(4, "Black");
            Ball B3 = new Ball(1, "Black");
            Ball B4 = new Ball(3, "Black");
    
            Ball[] balls = {R3, R1, B2, B4, R4, B1, R2, B3, R5};
    
    //        Ball[] balls = {R3, R1, R4, R2, R5};
    
            BallMergeSort ballMergeSort = new BallMergeSort();
    
    //        ballMergeSort.MergeSort(balls, balls.length);
    
            ballMergeSort.sort(balls);
    
            System.out.println(JSON.toJSONString(ballMergeSort.getResult()));
    
        }
    }
    
  • 相关阅读:
    Create方法失效而没有提示错误信息
    JS弹出窗口控制
    本周活动
    JavaScript的初步了解
    关于PHP接收文件的资料
    mvc模式改进网站结构
    一周动态
    排序
    Java的内存泄漏
    Android笔记
  • 原文地址:https://www.cnblogs.com/andy-zhou/p/6519729.html
Copyright © 2020-2023  润新知