/*****************************************************************
  各種のソーティングアルゴリズムをメソッドとして持つクラス
  インスタンスメソッド
******************************************************************/


public class SORTER {
    int noOfSorters = 3;

    // 配列 a の第 i 要素と第 j 要素を入れ替える
    private void swap(int[] a, int i, int j) {
        int tmp;
        tmp = a[i];  a[i] = a[j];  a[j] = tmp;
    } 


    /***** #1: バブルソート *****/
    public void bubble_sort(int[] a) {
        for (int i=0; i<a.length-1; i++) {
            for (int j=i+1; j<a.length; j++) {
                if (a[i]>a[j]) swap(a,i,j);
            }
        }
    }


    /***** #2: クイックソート *****/
    public void quick_sort(int[] a) {
        quickSort(a, 0, a.length-1);
    }

    private void quickSort(int[] a, int left, int right) {
    // 配列aの添字範囲leftからrightをquicksortする。
    // a[left],a[left+1],...,a[right]以外の場所は使わず、
    // ソート結果もそこに得るようなソート法である。      
        int LEFT,RIGHT,splitter;

        if (left<right) {
            splitter = a[( (LEFT=left)+(RIGHT=right) )/2];
            do {
                while (a[LEFT]<splitter)  LEFT++;
                while (a[RIGHT]>splitter) RIGHT--;
                if (LEFT<=RIGHT) swap(a, LEFT++, RIGHT--);
            } while (RIGHT>=LEFT);

            if (left<RIGHT) quickSort(a,left,RIGHT);
            if (LEFT<right) quickSort(a,LEFT,right);
        }
    }


    /***** #3: ヒープソート *****/
    public void heap_sort(int[] a) {
        int i;

        for (i=1; i<a.length; i++) insert(a,i);
        for (i=a.length-1; i>0; i--) heap_reduction(a,i);
    }

    private void insert(int[] h, int i) {
    // h[0]〜h[i-1]がヒープ(h[0]が最大値)のとき、
    // h[i]を追加し、h[0]〜h[i]をヒープに再構成する
        int son,father;

        father = (son=i)/2;
        while (son>0 && h[father]<h[son]) {
            swap(h,father,son);
            father = (son=father)/2;
        }
    }
 
    private void heap_reduction(int[] h, int i) {
    // h[i+1]〜h[a.length-1]はすでにh[i+1]<...<h[a.length-1]とソート済み 
    // h[0]とh[i]を入れ替え(h[i]〜h[a.length-1]がソート済みとなる)
    // h[0]〜h[i-1]を再びヒープに再構成する
        int father,leftson,rightson,maxson;
 
        swap(h,0,i);
        father = 0;  leftson = 1;
        while (leftson<i) {
            rightson = leftson+1;
            if (rightson<i && h[leftson]<h[rightson]) maxson = rightson;
            else maxson = leftson;
            if (h[father]>=h[maxson]) break;
            swap(h,father,maxson);
            leftson = (father=maxson)*2;
        }
    }
}