【问题标题】:Compare sorting algorithm比较排序算法
【发布时间】:2013-05-21 13:44:26
【问题描述】:

我实现了不同类型的排序(冒泡、插入、选择)。知道我想为每种排序比较它们的实现,如下所示(这里是冒泡排序的示例):

例如,这是我的冒泡排序:

private static int[] bubbleSort(int[] tabToSort) {
   int [] tab = tabToSort.clone();
   boolean tabSort = false;
   while(!tabSort){
        tabSort = true;
        for(int i = 0; i < tab.length -1; i++){
            if(tab[i]> tab[i+1]){
                int temp = tab[i+1];
                tab[i+1] = tab[i];
                tab[i] = temp;
                tabSort = false;
            }
        }
    }
    return tab;
}

我启动了 GUI,并在其上放置了 1000 个随机点和线 y=x

@Override
    public void paintComponent (Graphics g){
        super.paintComponent(g);
        Graphics2D g2d  = (Graphics2D) g;
        g2d.setColor(Color.BLACK);
        Dimension size = getSize();
        Insets  insets= getInsets();
        int w =  size.width - insets.left - insets.right;
        int h =  size.height - insets.top - insets.bottom;
        
        g2d.drawLine(size.width ,0, 0, size.height);
        Random r = new Random();

        for (int i  =0; i < 1000; i++) {
           int x = Math.abs(r.nextInt()) % w;
           int y = Math.abs(r.nextInt()) % h;
           Point p = new Point(x, y);
           g2d.drawLine(p.x, p.y, p.x, p.y);
        }
    }

这是我所做的:

现在我被卡住了,我不知道如何开始。谁能告诉我要遵循的步骤/提示来实现它吗?

谢谢:)

【问题讨论】:

    标签: java swing sorting user-interface paintcomponent


    【解决方案1】:

    我已经为我的学士学位做了这个,我是这样做的(它并不完美,但它可能会帮助你):

    (我从下面的代码中删除了一些不重要的方法/函数。主要是为了说明我是如何可视化它的。例如,您可以将 GRectangle 类替换为简单的 java.awt.Point 。)

    初始化方法为您提供了一个示例,说明如何找到数据的最大值和最小值,以便您了解如何转换 datavalues => 坐标。

    public class DotVisualisation extends Visualisation {
    
        private ArrayList<GRectangle> m_points;
    
        private Comparable[] m_data;
    
        private Comparable m_maxValue;
        private Comparable m_minValue;
    
        private int MAX_HEIGHT; // max height in pixels of visualization
    
        /**
         * Creates a new DotVisualisation.<br>
         * <br>
         * This class is a runnable JComponent that will visualize data as a function. 
         * The visualisation will plot the data with X and Y coordinates on the window. 
         * The X coordinate of the point is index of the dataelement. 
         * The Y coordinate of the point is relative to the value of the dataelement.<br>
         * <br>
         * This visualisation should be used for medium and large arrays.
         * 
         * @author David Nysten
         */
        public DotVisualisation()
        {
            m_points = new ArrayList<GRectangle>();
            MAX_HEIGHT = 150;
        }
    
        /**
         * Returns the maximum supported dimension by this visualisation.
         * 
         * @return The supported dimension.
         */
        public static int getSupportedDimension()
        {
            return 1;
        }
    
        @Override
        public Dimension getMaximumSize() 
        {
            return getPreferredSize();
        }
    
        @Override
        public Dimension getPreferredSize() 
        {
            return new Dimension(m_points.size() + 2, MAX_HEIGHT + 6);
        }
    
        @Override
        public Dimension getMinimumSize() 
        {
            return getPreferredSize();
        }
    
        @Override
        public void paintComponent(Graphics g)
        {
            for(int i = 0; i < m_points.size(); ++i)
                m_points.get(i).paintComponent(g);
        }
    
        private void swap(int index, int index2) { // See below }
    
        private void initialise()
        {
            findMinimum();
            findMaximum();
            m_points.clear();
            double multiplier;
            int x = 0, y = 0, h;
            for(int i = 0; i < m_data.length; ++i)
            {
                if(m_data[i].compareTo(-1) <= 0)
                    h = 0;
                else
                {
                    Integer value = (Integer) m_data[i];
                    Integer min = (Integer) m_minValue;
                    Integer diff = (Integer) m_maxValue - min;
                    multiplier = MAX_HEIGHT / diff.doubleValue();
                    h = (int) ((value - min) * multiplier);
                }
                y = (int) (MAX_HEIGHT - h);
                GRectangle r = new GRectangle(x, y, 1, 1); // 1, 1 = width and height
                r.setColor(Color.BLACK);
                m_points.add(r);
                ++x;
            }
        }
    
        private void findMaximum()
        {
            Comparable max = null;
            if(m_data.length > 0)
            {
                max = m_data[0];
                for(int i = 1; i < m_data.length; ++i)
                    if(m_data[i].compareTo(max) > 0)
                        max = m_data[i];
            }
            m_maxValue = max;
        }
    
        private void findMinimum()
        {
            Comparable min = null;
            if(m_data.length > 0)
            {
                min = m_data[0];
                for(int i = 1; i < m_data.length; ++i)
                    if(m_data[i].compareTo(min) < 0)
                        min = m_data[i];
            }
            m_minValue = min;
        }
    }
    

    考虑到这一点: 在 150 像素的高度上可视化 0 到 150 之间的整数很简单。在 150 的高度上可视化一组介于 565 和 3544545 之间的整数有点少。

    PS:代码使用 inputarray 中元素的索引作为 X 坐标。
    PS:该类保留对输入数组(m_​​data 变量)的引用,但这当然不是必需的,您只需要它来初始化您的点。
    PS:我的所有可视化扩展的“可视化”类基本上是一个JPanel。
    PS:上面的代码是为正整数编写的,所以可能还需要一些额外的编码来处理负整数;)。

    然后为了可视化算法的动作,我使用了观察者模式。该算法(例如冒泡排序)如下所示:

        for(int i = 0; i < size(); ++i)
            for(int j = 1; j < size(); ++j)
                if(greaterThan(j - 1, j))
                    swap(j - 1, j);
    

    其中swap函数定义如下(又是简化版):

    protected void swap(int index1, int index2)
    {
        if(index1 != index2)
        {
            incrementSwap(); // counting swaps and visualizing counter
    
            m_command.clear();
            m_command.setAction(Action.SWAP);
            m_command.addParameter(index1);
            m_command.addParameter(index2);
            setChanged();
            notifyObservers(m_command);
    
            E temp = m_data[index1];
            m_data[index1] = m_data[index2];
            m_data[index2] = temp;
        }
    }
    

    我通知我的观察者(可视化)在 index1 和 index2 上发生了交换。 m_command 变量是 Command 类的一个实例(我自己编写的),它只是可视化所需信息的包装器。即:发生的动作和相关信息(例如交换动作的索引)。

    所以在可视化中我交换了这些索引上的 GRectangle 以及它们的 X 坐标;

    private void swap(int index, int index2)
    {
        if(index == index2)
            return;
        GRectangle r1 = m_points.get(index);
        GRectangle r2 = m_points.get(index2);
    
        int tempX = r1.getX();
        r1.setLocation(r2.getX(), r1.getY());
        r2.setLocation(tempX, r2.getY());
    
        m_points.set(index, r2);
        m_points.set(index2, r1);
    }
    

    你可以像这样添加行:

            try {
                Thread.sleep(100);
            } catch(InterruptedException ignore) {}
    

    让线程在继续之前休眠 100 毫秒。如果可视化太快,这可能会派上用场。

    因此,对于具有随机整数的数组,它可能如下所示:

    排序后: (当然这不是一条直线,因为在这种情况下输入数组中的值是随机生成的)

    因此,如果您必须 - 就像我必须 - 允许多个算法使用相同的可视化,我可以建议您将可视化类和算法类分开,并使用观察者模式来让可视化在任何时候更新操作发生(设置、交换、...)。

    然后你可以创建这样的东西进行比较;

    http://i445.photobucket.com/albums/qq179/ultddave/DotVisualizationMany_zps63269d2a.png http://i445.photobucket.com/albums/qq179/ultddave/DotVisualizationMany2_zps65e96fa9.png

    祝你好运!

    【讨论】:

      【解决方案2】:

      你需要

      1. 创建一个int[] 数组,其中随机值作为成员变量。我们称数组为data。您可能希望从一个固定的数组大小和每个 100 的范围开始。当一个简单的版本正在运行时,您可以稍后将这些值调整为窗口大小。坚持固定的大小和范围可能会更好,只需缩放到paintComponent 中的可用空间,从而使行为独立于窗口大小。
      2. paintComponent 更改为循环data。循环索引是您的 x 值,data[x] 确定 y 值。
      3. 测试代码是否仍然绘制初始随机数组。不在乎它现在是否在左上角,您可以在动画运行时修复它。
      4. 您需要在排序方法的最内层循环中添加某种sleep() 调用,这样您就有机会观察这些步骤。否则,即使是冒泡排序也会太快而无法观察。我建议从一秒开始(参数值 1000)。等一切正常后加快速度。
      5. 在新线程中启动bubbleSort 方法,并确保您的组件在每一步都被重新绘制。这可能是最棘手的部分。或许将组件交给bublleSort 方法(或者让bubbleSort 成为组件的非静态方法),让它在每一步都请求一个repaint()(幸运的是,这是少数几个线程安全的方法之一)摇摆)。
      6. 微调您的代码:通过乘以可用空间然后除以数组大小或值范围来缩放 x 和 y 坐标。根据需要调整睡眠时间。添加对不同排序算法的支持....

      如果有任何步骤不清楚,请添加评论。

      【讨论】:

        【解决方案3】:

        您必须定义这些点的含义。查看动画,看起来 y 轴代表 value,而 x 轴代表该值数组中的 position

        在您的 paint 方法中,您将浏览项目列表并绘制一个点,其中 x 点是数组中的位置,y 点是 y 轴上的位置。假设值在已知范围内。

        另外,请记住,图形中的 y 轴从 顶部处的 0 开始,因此您可能需要将值转换为坐标(取决于您希望它的外观)。

        【讨论】:

          【解决方案4】:

          最简单的方法是将您的绘制方法转换为使用预定义的List 点作为参数而不是随机点的方法。在您的 sort 方法的每次迭代中,将排序后的数组传递给 paint 方法并重新绘制点。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多