如何以不同方式实现此冒泡排序?

时间:2011-12-19 23:06:27

标签: c++ bubble-sort

我正在寻求实施冒泡排序。我编写了以下代码,它使用for循环内的do循环。如何将其转换为使用两个for循环的冒泡排序?

这是我的代码:

do {
    switched = false;
    for (int i = 1; i < size; i++) {
        if (a[i] < a[i-1]) {
            int temp = a[i];
            a[i] = a[i-1];
            a[i-1] = temp;
            switched = true;
        }
    }
} while (switched);

(这是标记的作业,但这是为期末考试而不是实际的作业。)

8 个答案:

答案 0 :(得分:6)

因为您知道列表中的最后一个元素将始终排序(因为它冒泡到顶部),您可以停在那里。

for(int x = size; x >= 0; x--) {
    bool switched = false;
    for(int i = 1; i < x; i++) {
        if(blah) {
            // swap code here
            switched = true;
        }

    }
    if(!switched) break; // not the biggest fan of this but it gets the job done
}

答案 1 :(得分:5)

有点专横,但是,嘿,你问过它:

for(bool switched=true; switched;)
{
    switched = false;
    for (int i = 1; i < size; i++) {
        if (a[i] < a[i-1]) {
            int temp = a[i];
            a[i] = a[i-1];
            a[i-1] = temp;
            switched = true;
        }
    }
}

两个for循环...

答案 2 :(得分:3)

由于内循环运行的最大次数是size次,因此您知道外循环只能被size绑定。

for (int x = 0; x < size; x++ )
{
    switched = false;
    for (int i = 1; i < size; i++)
    {
        if (a[i] < a[i - 1])
        {
            int temp = a[i];
            a[i] = a[i - 1];
            a[i - 1] = temp;
            switched = true;
        }
    }

    if(switched)
    {
        break;
    }
}

答案 3 :(得分:1)

对冒泡排序的一个简单改进是记住发生交换的最后位置。每次传递后,超出该点的元素将被排序。下一次循环只会迭代到之前的高水位线。

void bubble_sort(int *arr, int size)
{
    for (int hwm; size > 1; size = hwm)
    {
        hwm = 0;
        for (int i = 1; i < size; ++i)
        {
            if (arr[i] < arr[i-1])
            {
                std::swap(arr[i], arr[i-1]);
                hwm = i;
            }
        }
    }
}

答案 4 :(得分:0)

您可以运行内部循环size次,而不是通过外部循环switched来检查for(int j=0; j<size; ++j)。为了使效率稍微低一些,你可以每次使内循环缩短一步。

答案 5 :(得分:0)

第一次完整遍历循环(即外部do循环的第一次迭代)保证将最大元素放在位置a[size - 1]中。 (你知道为什么吗?)下一个完整传球保证不会改变,,另外,将第二大元素放在位置a[size - 2]。 (再次,你明白为什么?)等等。因此,第一次传递需要i1转到size - 1,但第二次只需要i1转到size - 2,第三个只需要i1转到size - 3,依此类推。总的来说,您最多需要size - 1次传递(最后一次传递仅覆盖位置1并将a[1]a[0]进行比较,以确保最小的元素到位。< / p>

因此,您的外部for - 循环需要变化max_i,最初设置为size - 1,最后设置为1,内部for - 循环需要从i1变化max_i

答案 6 :(得分:0)

考虑do循环可以执行的最大次数。

答案 7 :(得分:0)

使用两个for循环的一个非常愚蠢的方法如下:

for(bool switched=true;switched;)
{
    switched=false;
    for(int i=1; i<size; ++i)
    {
        if (a[i] < a[i-1]) 
        {
            int temp = a[i];
            a[i] = a[i-1];
            a[i-1] = temp;
            switched = true;
        }
    }
}

更严肃的答案可能如下......但是现在我想起来这可能不是冒泡的那种:

for(int i=0; i<(size-1); ++i)
{
    for(int j=(i+1); j<(size-1); ++j)
    {
        if(a[i]>a[j])
        {
            temp=a[i];
            a[i]=a[j];
            a[j]=temp;
        }
    }
}