001: import java.applet.Applet;
002: import java.awt.Color;
003: import java.awt.Graphics2D;
004: import java.awt.geom.Line2D;
005: 
006: public class MergeSorter
007: {
008:    public MergeSorter(int[] anArray, Applet anApplet)
009:    {
010:       a = anArray;
011:       applet = anApplet;
012:    }
013:    
014:    /**
015:       Sorts the array managed by this merge sorter
016:    */
017:    public void sort()
018:       throws InterruptedException
019:    {  
020:       mergeSort(0, a.length - 1);
021:    }
022: 
023:    /**
024:       Sorts a range of the array, using the merge sort
025:       algorithm.
026:       @param from the first index of the range to sort
027:       @param to the last index of the range to sort
028:    */
029:    public void mergeSort(int from, int to)
030:       throws InterruptedException
031:    {  
032:       if (from == to) return;
033:       int mid = (from + to) / 2;
034:        // sort the first and the second half
035:       mergeSort(from, mid);
036:       mergeSort(mid + 1, to);
037:       merge(from, mid, to);
038:    }
039: 
040:    /**
041:       Merges two adjacent subranges of the array
042:       @param from the index of the first element of the 
043:       first range
044:       @param mid the index of the last element of the 
045:       first range
046:       @param to the index of the last element of the
047:       second range
048:    */
049:    public void merge(int from, int mid, int to)
050:       throws InterruptedException
051:    {  
052:       startPosition = from;
053:       endPosition = to;
054: 
055:       int n = to - from + 1;
056:       // size of the range to be merged
057: 
058:       // merge both halves into a temporary array b 
059:       int[] b = new int[n];
060: 
061:       int i1 = from;
062:       // next element to consider in the first range
063:       int i2 = mid + 1;
064:       // next element to consider in the second range
065:       int j = 0; 
066:       // next open position in b
067:       
068:       // as long as neither i1 nor i2 past the end, move
069:       // the smaller element into b
070:       while (i1 <= mid && i2 <= to)
071:       {  
072:          if (a[i1] < a[i2])
073:          {  
074:             b[j] = a[i1];
075:             markedPosition = i1;
076:             i1++;
077:          }
078:          else
079:          {  
080:             b[j] = a[i2];
081:             markedPosition = i2;
082:             i2++;
083:          }
084: 
085:          pause(4);
086:          j++;
087:       }
088: 
089:       // note that only one of the two while loops
090:       // below is executed
091: 
092:       // copy any remaining entries of the first half
093:       while (i1 <= mid)
094:       {  
095:          b[j] = a[i1];
096:          markedPosition = i1;
097:          pause(2);
098:          i1++;
099:          j++;
100:       }
101:       
102:       // copy any remaining entries of the second half
103:       while (i2 <= to)
104:       {  
105:          b[j] = a[i2];
106:          markedPosition = i2;
107:          pause(2);
108:          i2++;
109:          j++;
110:       }
111: 
112:       // copy back from the temporary array
113:       for (j = 0; j < n; j++)
114:       {
115:          a[from + j] = b[j];
116:          markedPosition = from + j;
117:          pause(2);
118:       }
119:    }
120: 
121:    public void draw(Graphics2D g2)
122:    {
123:       if (a == null) return;
124:       int deltaX = applet.getWidth() / a.length;
125:       for (int i = 0; i < a.length; i++)
126:       {
127:          if (i == markedPosition)
128:             g2.setColor(Color.red);
129:          else if (startPosition <= i && i <= endPosition)
130:             g2.setColor(Color.blue);
131:          else
132:             g2.setColor(Color.black);
133:          g2.draw(new Line2D.Double(i * deltaX, 0, i * deltaX, a[i]));
134:       }
135:    }
136: 
137:    public void pause(int steps) 
138:       throws InterruptedException
139:    {
140:       if (Thread.currentThread().isInterrupted()) 
141:          throw new InterruptedException();
142:       applet.repaint();
143:       Thread.sleep(steps * DELAY);
144:    }
145: 
146:    private int[] a;
147: 
148:    // for animation
149:    private int markedPosition = -1;
150:    private int startPosition = -1;
151:    private int endPosition = -1;
152: 
153:    private Applet applet;
154:    private static final int DELAY = 100;
155: }