选择排序算法能否像冒泡排序那样提前终止其循环?
Can a selection sort algorithm terminate from its loop early the way a bubble sort is able to?
如果我不包含提前终止标志,这个程序会 运行 没问题,但它只需要 10 次排序就可以完全排序列表,而不是完整的 12 次。但是,当包含终止标志时,它过早地终止排序。按照逻辑,我可以看到会发生这种情况,因为在第三遍之后,数组的排序如下:
当前索引 i 为 7,没有更小的值可以与之交换,因此标志没有得到分配给它的值 1,循环终止。所以我想我的问题是,是否有可能提前突破选择排序算法并仍然完全完成排序?
#include<stdio.h>
int main()
{
int list[13]= {23,8,4,7,22,18,39,42,5,88,16,11,3};
int temp,min,flag;
printf( "Before Sorting\n" );
printf( "23 8 4 7 22 18 39 42 5 88 16 11 3\n" );
for( int i=0; i<12; i++ )
{
flag = 0;
min = i;
for( int j=i+1; j<13; j++ )
{
if( list[j]<list[min] )
{
flag = 1;
min = j ;
}
}
if( !flag )
break;
temp = list[i];
list[i]=list[min];
list[min]=temp;
printf( "\nAfter Pass %d.\n",i+1 );
for( int i=0; i<13; i++ )
printf( "%d ",list[i] );
printf( "\n" );
}
return 0;
}
冒泡排序几乎没有任何可取之处,最好的地方就是它的名字。 Donald Knuth 曾说过
the bubble sort seems to have nothing to recommend it, except a catchy name and the fact that it leads to some interesting theoretical problems
事实上,来自维基百科关于 selection sort:
Among simple average-case Θ(n²) algorithms, selection sort almost always outperforms bubble sort and gnome sort.
选择排序没有变化 - 它的 运行 时间不取决于排序。对于另一个具有可变 运行 时间的简单 O(n²) 算法,请参见 insertion sort.
确实可以。这是这样一个实现,
int selsort(int v[], int n){
bool sorted = false; // v not known to be sorted
int i = 0; // i smallest elements in place
while(!sorted){
// find min v[i..n-1]
// check if v[i..n-1] is sorted
int j = i+1;
int min = i; // position of minimum of v[i..j-1]
sorted = true; // v[i..j-1] sorted
while(j<n){
if(v[j]<v[min]) min = j; // update min
if(v[j]<v[j-1]) sorted = false; // update sorted
j++;
}
if (!sorted){
// place min v[i..n-1] in v[i]
int aux = v[i];
v[i] = v[min];
v[min] = aux;
i++;
}
}
return EXIT_SUCCESS;
}
像往常一样,在迭代 i
中,我们从 v[0..i-1]
开始,在正确的位置对数组的 i
最小元素进行排序。所以我们要找到min v[i..n-1]
放在位置i
。在这个变体中,当我们这样做时,我们还会检查 v[i..n-1]
是否已排序。如果它被排序,那么就没有别的事可做。
您的实施
在您的实现中,您测试有序段的方式是错误的。
if( list[j]<list[min] )
{
flag = 1;
min = j ;
}
只要您不必更新内部循环中的最小值,您的标志就会保持在 0
。因此,任何在第一个位置具有最小值的段都将被视为已排序。
如果我不包含提前终止标志,这个程序会 运行 没问题,但它只需要 10 次排序就可以完全排序列表,而不是完整的 12 次。但是,当包含终止标志时,它过早地终止排序。按照逻辑,我可以看到会发生这种情况,因为在第三遍之后,数组的排序如下:
当前索引 i 为 7,没有更小的值可以与之交换,因此标志没有得到分配给它的值 1,循环终止。所以我想我的问题是,是否有可能提前突破选择排序算法并仍然完全完成排序?
#include<stdio.h>
int main()
{
int list[13]= {23,8,4,7,22,18,39,42,5,88,16,11,3};
int temp,min,flag;
printf( "Before Sorting\n" );
printf( "23 8 4 7 22 18 39 42 5 88 16 11 3\n" );
for( int i=0; i<12; i++ )
{
flag = 0;
min = i;
for( int j=i+1; j<13; j++ )
{
if( list[j]<list[min] )
{
flag = 1;
min = j ;
}
}
if( !flag )
break;
temp = list[i];
list[i]=list[min];
list[min]=temp;
printf( "\nAfter Pass %d.\n",i+1 );
for( int i=0; i<13; i++ )
printf( "%d ",list[i] );
printf( "\n" );
}
return 0;
}
冒泡排序几乎没有任何可取之处,最好的地方就是它的名字。 Donald Knuth 曾说过
the bubble sort seems to have nothing to recommend it, except a catchy name and the fact that it leads to some interesting theoretical problems
事实上,来自维基百科关于 selection sort:
Among simple average-case Θ(n²) algorithms, selection sort almost always outperforms bubble sort and gnome sort.
选择排序没有变化 - 它的 运行 时间不取决于排序。对于另一个具有可变 运行 时间的简单 O(n²) 算法,请参见 insertion sort.
确实可以。这是这样一个实现,
int selsort(int v[], int n){
bool sorted = false; // v not known to be sorted
int i = 0; // i smallest elements in place
while(!sorted){
// find min v[i..n-1]
// check if v[i..n-1] is sorted
int j = i+1;
int min = i; // position of minimum of v[i..j-1]
sorted = true; // v[i..j-1] sorted
while(j<n){
if(v[j]<v[min]) min = j; // update min
if(v[j]<v[j-1]) sorted = false; // update sorted
j++;
}
if (!sorted){
// place min v[i..n-1] in v[i]
int aux = v[i];
v[i] = v[min];
v[min] = aux;
i++;
}
}
return EXIT_SUCCESS;
}
像往常一样,在迭代 i
中,我们从 v[0..i-1]
开始,在正确的位置对数组的 i
最小元素进行排序。所以我们要找到min v[i..n-1]
放在位置i
。在这个变体中,当我们这样做时,我们还会检查 v[i..n-1]
是否已排序。如果它被排序,那么就没有别的事可做。
您的实施
在您的实现中,您测试有序段的方式是错误的。
if( list[j]<list[min] )
{
flag = 1;
min = j ;
}
只要您不必更新内部循环中的最小值,您的标志就会保持在 0
。因此,任何在第一个位置具有最小值的段都将被视为已排序。