繁体   English   中英

计数循环和比较

[英]Counting Loops and Comparisons

我需要计算在四种不同的排序方法上发生的循环和比较的次数。 我正在使用选择,冒泡,插入和快速排序方法。 理想情况下,每次循环/比较时,我都将放置一个int(例如loopCounter)并对其进行++编码。 尽管对于所有这些都是新手,但是我在区分何时需要包括此类计数器时遇到了麻烦。 正如您将在以下代码中看到的那样,我尝试创建多个计数器。 虽然,到目前为止,我认为只有选择计数器是正确的。

另外,我需要计算一个值被移位的次数。 换句话说,整数被交换了多少次。

任何帮助,将不胜感激!

谢谢

    ArrayList<Integer> list = new ArrayList<Integer>();

    //Counters for Selection Sort
    int loopCounter = 0;
    int compCounter = 0;
    //Counters for Bubble Sort
    int loopCounter2 = 0;
    int compCounter2 = 0;
    //Counters for Insertion Sort
    int loopCounter3 = 0;
    int compCounter3 = 0;
    //Counters for Quick Sort
    int loopCounter4 = 0;
    int compCounter4 = 0;

public void selectionSort(Integer[] a) {

    for(int i = 0; i < a.length; i++) {
        int smallestValue = a[i];
        int smallestIndex = i;
        if(ascButton.isSelected()){
            for(int j = i+1; j < a.length; j++) {
                if (smallestValue > a[j]) {
                    smallestValue = a[j];
                    smallestIndex = j;
                    loopCounter++;
                    compCounter++;
                }
            }
        a[smallestIndex] = a[i];
        a[i] = smallestValue;
        } else if(desButton.isSelected()){
            for(int j = i+1; j < a.length; j++) {
                if (smallestValue < a[j]) {
                    smallestValue = a[j];
                    smallestIndex = j;
                    loopCounter++;
                    compCounter++;
                }
        }
        a[smallestIndex] = a[i];
        a[i] = smallestValue;
        }
    }
}

public void bubbleSort(Integer[] a) {

    int temp;

    for (int i = a.length - 1; i > 0; i--) {
        if(ascButton.isSelected()) {
            for(int j = 0; j < i; j++) {
                loopCounter2++;
                compCounter2++;
                if(a[j] > a[j + 1]) {
                    temp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = temp;
                }
            }
            } else if(desButton.isSelected()) {
                for(int j = 0; j < i; j++) {
                    loopCounter2++;
                    compCounter2++;
                    if(a[j] < a[j + 1]) {
                        temp = a[j];
                        a[j] = a[j + 1];
                        a[j + 1] = temp; 
                    }
                }
            }

    }
}

public void insertionSort(Integer[] a) {
    for(int i = 1; i < a.length; i++) {
        loopCounter3++;
        compCounter3++;
        int temp = a[i];
        int j = i - 1;

        if(ascButton.isSelected()) {
            while(j >= 0 && a[j] > temp) {
            a[j + 1] = a[j];
            j--;
        }
        a[j + 1] = temp;
        } else if(desButton.isSelected()) {
            while(j >= 0 && a[j] < temp) {
            a[j + 1] = a[j];
            j--;
        }
        a[j + 1] = temp;
        }

    }
}

public void quickSort(Integer[] a, int left, int right) {
    int i = left;
    int j = right;
    int temp;
    int pivot = a[(left + right)/2];
    while(i <= j) {
    if(ascButton.isSelected()) {
        while(a[i] < pivot)
            i++;
        while(a[j] > pivot)
            j--;
    } else if(desButton.isSelected()) {
        while(a[i] > pivot)
            i++;
        while(a[j] < pivot)
            j--;
    }
        if(i <= j) {
            temp = a[i];
            a[i] = a[j];
            a[j] = temp;
            i++;
            j--;
        }
    }
    if(left < j) {
        quickSort(a,left,j);
    }  
    if(i < right) {
        quickSort(a, i, right);
    }            
}

使用计数器,您只想在要编程计算某物时就“计数”。 因此,如果您不理解自己的代码,那么很难知道何时要“计数”某些内容。 我建议您弄清楚什么时候发生交换,代码中什么时候发生,也就是您想执行以下某种操作:

    swapCount++;//Each time a swap happens increment by 1
    iterationCount++//A full pass has happened increment by 1

注意:以上只是因为一次完整的通过已经发生了很多次,您可能知道这并不意味着它已被排序,而是说它已经完成了1次通过。

我不确定该理论是否对您有帮助。 给我一些有关您仍然遇到的问题的反馈,我将看看是否可以更改答案以更好地反映您的期望。

如@Andreas所建议,您的循环计数器和比较计数器已正确放置。 就交换计数器而言,请以这种方式考虑-如果没有临时变量,则无法交换。 结果,无论何时涉及到临时变量,您都想增加交换计数器。 例如,对于您的快速排序,它看起来像这样:

public void quickSort(Integer[] a, int left, int right) {
    int i = left;
    int j = right;
    int temp;
    int pivot = a[(left + right)/2];
    while(i <= j) {
    if(ascButton.isSelected()) {
        while(a[i] < pivot)
            i++;
        while(a[j] > pivot)
            j--;
    } else if(desButton.isSelected()) {
        while(a[i] > pivot)
            i++;
        while(a[j] < pivot)
            j--;
    }
        if(i <= j) {
            temp = a[i];
            a[i] = a[j];
            a[j] = temp;
            i++;
            j--;
            swapCounterForQuickSort++;
        }
    }
    if(left < j) {
        quickSort(a,left,j);
    }  
    if(i < right) {
        quickSort(a, i, right);
    }            
}

其他类型也要遵循相同的逻辑。

另外,一些一般性建议:

  • 始终命名变量,以便它们告诉您它们的用途。 而不是loopCounter1尝试使用loopCounterForSelectionSort等等。 不要害怕长变量名。 信息就是力量!
  • 使您的函数尽可能短并且可重用。 例如,您在代码中频繁交换整数。 也许您可以只复制交换代码并将其粘贴到swapIntegers()函数中。 然后,每当您要交换时只要调用此函数! 另外,请注意,这可以使您的交换计数器问题更容易回答,因为您可以在交换方法中放置一个计数器来为您进行计数。 (尽管请注意,因为有多个方法将调用交换计数器,所以您可能希望将其作为参数传递,等等。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM