2017-03-12 25 views
1

Introsortを実装しようとしましたが、これはquicksortアルゴリズムで始まりますが、再帰の深さが2 * log(array length)になるとすぐにheapsortに変更されます。Intro Sort(クイックソート+ヒープソート)は永続的ではありませんか?

(配列サイズ= 20)と、&のヒープまたはクイックソートの使用回数を表示しました。問題は、私がそれを実行するたびに、私は異なる統計を取得することです。 E.Gは最初にクイックソートを6回、ヒーサーソートを6回使用し、次回は11回と14回になります。何故ですか?ここで

は私のテストクラスである:ここで

public class TestClass { 

public static void main(String[] args) { 
    int[] myArray = randomIntArray(); 
    IntroSort.sort(myArray); 
} 

private static int[] randomIntArray() { 
    Random rand = new Random(); 
    int[] newIntArray = new int[20]; 
    for(int i = 0; i < newIntArray.length; i++){ 
     newIntArray[i] = rand.nextInt((1000 - 0) + 1) + 0; 
    } 
    return newIntArray; 
} 

}

は私のイントロソートクラスです:

public class IntroSort { 

private static int quick = 0; 
private static int heap = 0; 

/* 
* ------------------------------------------------------ 
* Interface to the outer world, takes an array as 
* parameter, and calculates the max depth allowed. 
* ------------------------------------------------------ 
*/ 
public static void sort(int[] arrayToSort){  
    int depth = ((int) Math.log(arrayToSort.length))*2; 
    sort(arrayToSort, depth, 0, arrayToSort.length-1); 
    System.out.println("Total QuickSorts: "+quick); 
    System.out.println("Total HeapSorts: "+heap); 
} 

/* 
* ------------------------------------------------------ 
* Sorting loop, decides whether to use quicksort or 
* heapsort. 
* ------------------------------------------------------ 
*/ 
private static void sort(int[] arrayToSort, int depth, int start, int end){ 
    int length = arrayToSort.length; 
    if(length <= 1){ 
     return; 
    }else if(depth == 0){ 
     heap++; 
     heapSort(arrayToSort, start, end); 
    }else{ 
     if(start >= end) 
      return; 
     quick++; 
     int pivot = arrayToSort[(start + end)/2]; 
     int index = partition(arrayToSort, start, end, pivot); 
     sort(arrayToSort, depth-1, start, index-1); 
     sort(arrayToSort, depth-1, index, end); 
    } 
} 

/* 
* ------------------------------------------------------ 
* Heap sort implementation, taken and modified from 
* HeapSort.java 
* ------------------------------------------------------ 
*/ 
private static void heapSort(int[] arrayToSort, int start, int end){ 
    for (int i = end/2 - 1; i >= start; i--) 
     heapify(arrayToSort, end, i); 
    for (int i=end-1; i>=start; i--){ 
     int temp = arrayToSort[start]; 
     arrayToSort[start] = arrayToSort[i]; 
     arrayToSort[i] = temp; 
     heapify(arrayToSort, i, start); 
    } 
} 

/* 
* ------------------------------------------------------ 
* Heapify implementation, taken and modified from 
* HeapSort.java 
* ------------------------------------------------------ 
*/ 
private static void heapify(int[] arrayToSort, int n, int i){ 
    int largest = i; 
    int l = 2*i + 1; 
    int r = 2*i + 2; 
    if (l < n && arrayToSort[l] > arrayToSort[largest]) 
     largest = l; 
    if (r < n && arrayToSort[r] > arrayToSort[largest]) 
     largest = r; 
    if (largest != i){ 
     int swap = arrayToSort[i]; 
     arrayToSort[i] = arrayToSort[largest]; 
     arrayToSort[largest] = swap; 
     heapify(arrayToSort, n, largest); 
    } 
} 

/* 
* ------------------------------------------------------ 
* Partition for Quick sort implementation, taken and modified from 
* QuickSort.java 
* ------------------------------------------------------ 
*/ 
private static int partition(int[] arrayToSort, int start, int end, int pivot){ 
    while(start <= end){ 
     while(arrayToSort[start] < pivot){ 
      start++; 
     } 
     while(arrayToSort[end] > pivot){ 
      end--; 
     } 
     if(start <= end){ 
      int temp = arrayToSort[start]; 
      arrayToSort[start] = arrayToSort[end]; 
      arrayToSort[end] = temp; 
      start++; 
      end--; 
     } 
    } 
    return start; 
} 

}

+1

多分あなたはそれにランダムな入力を与えますか? –

+0

@AndyTurnerを説明してもらえますか? – Carlton

+1

'myArray'がランダムに生成されます。これは、ランダムな配列をソートされた順序にするためには、異なる量の作業を行わなければならないという意味ではありませんか? –

答えて

1

myArrayはランダムに生成されます。

これは、ランダム配列をソートされた順序にするためにアルゴリズムが異なる量の作業を行わなければならないことを意味します。

同じ配列を複数回渡すと、同じカウントが得られます。

これらを静的変数として使用すると、呼び出し間のカウントをリセットする必要があります。また、並列呼び出しには安全ではありません。そのようなグローバルな状態の変化を伴わない代替案を検討したいかもしれません。