2017-12-04 3 views
0

한 번에 모든 바 정렬 : Java swing repainting while computing: animating sorting algorithm바 데모 일종의 내가 허용 대답 여기에이 코드를 발견 -Java

그리고 나는 그것이 흔드는 정렬 작동되도록 수정하려고 노력했지만 내 코드를 정렬 모든 것을 한 번에.

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.Arrays; 
import java.util.Collections; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

public class ShakerSortAnimate extends JPanel { 
private static final int NUM_OF_ITEMS = 20; 
private static final int DIM_W = 400; 
private static final int DIM_H = 400; 
private static final int HORIZON = 350; 
private static final int VERT_INC = 15; 
private static final int HOR_INC = DIM_W/NUM_OF_ITEMS; 

private JButton startButton; 
private Timer timer = null; 
private JButton resetButton; 

Integer[] list; 
int currentIndex = NUM_OF_ITEMS - 1; 

public ShakerSortAnimate() { 
    list = initList(); 

    timer = new Timer(200, new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      if (isSortingDone()) { 
       ((Timer) e.getSource()).stop(); 
       startButton.setEnabled(false); 
      } else { 
       sortOnlyOneItem(); 
      } 
      repaint(); 
     } 
    }); 

    //button to run the program 
    startButton = new JButton("Start"); 
    startButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      timer.start(); 
     } 
    }); 

    //resets screen 
    resetButton = new JButton("Reset"); 
    resetButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      list = initList(); 
      currentIndex = NUM_OF_ITEMS - 1; 
      repaint(); 
      startButton.setEnabled(true); 
     } 
    }); 
    add(startButton); 
    add(resetButton); 
} 

//boolean checks when array is sorted 
public boolean isSortingDone() { 
    return currentIndex == 0; 
} 

//initializes the array 
public Integer[] initList() { 
    Integer[] nums = new Integer[NUM_OF_ITEMS]; 
    for (int i = 1; i <= nums.length; i++) { 
     nums[i - 1] = i; 
    } 
    Collections.shuffle(Arrays.asList(nums)); //shuffles array 
    return nums; 
} 

//draws each bar 
public void drawItem(Graphics g, int item, int index) { 
    int height = item * VERT_INC; 
    int y = HORIZON - height; 
    int x = index * HOR_INC; 
    g.fillRect(x, y, HOR_INC, height); 
} 


//My shaker sort code 
public void sortOnlyOneItem() 
{ 
    boolean swapped = true; 
    int start = 0; 
    int end = currentIndex; 

    while (swapped==true) 
    { 
     swapped = false; 

     for (int i = start; i < end; ++i) 
     { 
      if (list[i] > list[i + 1]) 
      { 
       int temp = list[i]; 
       list[i] = list[i+1]; 
       list[i+1] = temp; 
       swapped = true; 
      } 
     } 

     if (swapped==false) 
      break; 

     swapped = false; 

     end = end-1; 

     for (int i = end; i >=start; i--) 
     { 
      if (list[i] > list[i+1]) 
      { 
       int temp = list[i]; 
       list[i] = list[i+1]; 
       list[i+1] = temp; 
       swapped = true; 
      } 
     } 

     start = start + 1; 
    } 

    currentIndex--; //currentIndex is updated each time shaker sort runs 
} 






//draws all bars 
@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    for (int i = 0; i < list.length; i++) { 
     drawItem(g, list[i], i); 
    } 
} 

@Override 
public Dimension getPreferredSize() { 
    return new Dimension(DIM_W, DIM_H); 
} 

public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      JFrame frame = new JFrame("Sort"); 
      frame.add(new ShakerSortAnimate()); 
      frame.pack(); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.setLocationRelativeTo(null); 
      frame.setVisible(true); 
     } 
    }); 
} 
    } 

나는 나의 셰이커 분류 코드는 각각의 비교, 전체가 아닌 일을 위해 그것을하는 것을 깨닫게 않지만 솔직히, 난 그 코딩을 시작하는 방법을 모르겠어요. 여기있는 사람이 셰이커 정렬 방식으로 각 비교 코드를 코딩하는 방법을 알고 있다면 나를 도울 수 있습니까?

Btw, 전 게시 했으므로이 프로그램도 실행 해 볼 수 있습니다.

미리 감사드립니다.

+1

당신은'동안 (교환) 루프 할 필요가 공급 알고리즘을 모방하기 위해 최선의 노력을 만 수행하는 것이, 어떠한 주장도 이상하지 않습니다'문,이에 필요 의사 루프 (pseudo loop) 인 '타이머 (Timer)'가 처리해야합니다. 다른 반복 작업이 필요한지 여부를 결정해야하며, 그렇다면'sortOnlyOneItem' 메소드를 호출해야합니다. 이것은 또한'swapped','start'와'end'가 인스턴스 필드가되어야 함을 의미합니다. – MadProgrammer

답변

1

그래서, 당신은 단지 호출 당 한 번만 실행에

public void sortOnlyOneItem() 
{ 
    boolean swapped = true; 
    int start = 0; 
    int end = currentIndex; 

    while (swapped==true) 
    { 
     swapped = false; 

     for (int i = start; i < end; ++i) 
     { 
      if (list[i] > list[i + 1]) 
      { 
       int temp = list[i]; 
       list[i] = list[i+1]; 
       list[i+1] = temp; 
       swapped = true; 
      } 
     } 

     if (swapped==false) 
      break; 

     swapped = false; 

     end = end-1; 

     for (int i = end; i >=start; i--) 
     { 
      if (list[i] > list[i+1]) 
      { 
       int temp = list[i]; 
       list[i] = list[i+1]; 
       list[i+1] = temp; 
       swapped = true; 
      } 
     } 

     start = start + 1; 
    } 

    currentIndex--; //currentIndex is updated each time shaker sort runs 
} 

...이 필요합니다. 지금 그 일을하지는 않습니다. 왜냐하면 while-loop이 그렇게한다면, 우리는 그것을 제거 할 필요가 있기 때문입니다. ... swappedtrue 경우

는이 과정에서 두 번째 루프는 실행해야합니다 및 swapped 여전히 같은 우리에게 가져다 true

경우 currentIndex은 감소한다

public void sortOnlyOneItem() { 
    boolean swapped = true; 
    int start = 0; 
    int end = currentIndex; 

    for (int i = start; i < end; ++i) { 
     if (list[i] > list[i + 1]) { 
      int temp = list[i]; 
      list[i] = list[i + 1]; 
      list[i + 1] = temp; 
      swapped = true; 
     } 
    } 

    if (swapped) { 
     swapped = false; 

     end = end - 1; 

     for (int i = end; i >= start; i--) { 
      if (list[i] > list[i + 1]) { 
       int temp = list[i]; 
       list[i] = list[i + 1]; 
       list[i + 1] = temp; 
       swapped = true; 
      } 
     } 
    } 

    if (swapped) { 
     currentIndex--; //currentIndex is updated each time shaker sort runs 
    } 
} 

2 개의 for-loop이 여러 변경을 할 수 있기 때문에 여전히 올바르지 않습니다.

대신, 우리는 기껏해야 두 가지 변경, 시작 하나와 말

어느 하나가, 같이 보일 수도, 만들 것입니다 반복을 필요 ...

protected void swap(int a, int b) { 
    int tmp = list[a]; 
    list[a] = list[b]; 
    list[b] = tmp; 
} 

int endIndex = NUM_OF_ITEMS - 1; 

//My shaker sort code 
public void sortOnlyOneItem() { 

    int startIndex = 0; 
    while (startIndex < NUM_OF_ITEMS - 1 && list[startIndex] < list[startIndex + 1]) { 
     startIndex++; 
    } 

    if (startIndex < NUM_OF_ITEMS - 1 && list[startIndex] > list[startIndex + 1]) { 
     swap(startIndex, startIndex + 1); 
     int end = endIndex; 
     while (end > 0 && list[end - 1] < list[end]) { 
      end--; 
     } 
     if (end > 0 && list[end - 1] > list[end]) { 
      swap(end - 1, end); 
     } else { 
      endIndex--; 
     } 
    } else { 
     endIndex = 0; 
    } 
} 

자, 이것은 기본적으로 (startend에서) 변경 가능하고 가능한 경우 swap 인 두 개의 인덱스를 찾습니다. 변경하지 않고 start에서 끝까지 반복 할 수 있으면 정렬이 완료됩니다. 이 정확한지 아닌지

지금, 나는 당신이

+0

답을 고맙게 생각합니다! 그러나이 코드는 셰이커 정렬 방식과는 다른 방식으로 작동합니다. 이유는 무엇입니까? – TheDeadline

+1

부분적으로 예상했던대로, 알고리즘을 한 단계로 내림차순으로 처리했습니다. 접근 방식을 사용했지만 이전에 "셰이커"정렬을 구현 한 적이 없었으므로 계속 진행할 코드 만 만들었습니다. 당신은 당신의 필요를 충족시키기 위해 제시된 것과 장치의 기본 아이디어를 취할 필요가 있습니다. – MadProgrammer

+0

좋습니다, 도움을 주셔서 감사합니다 : DD – TheDeadline

관련 문제