冒泡排序中的交换次数
Posted
技术标签:
【中文标题】冒泡排序中的交换次数【英文标题】:Number of swaps in Bubble Sort 【发布时间】:2012-07-05 02:08:29 【问题描述】:我有一个冒泡排序版本:
int i, j;
for i from n downto 1
for j from 1 to i-1
if (A[j] > A[j+1])
swap(A[j], A[j+1])
我想使用上述版本的冒泡排序来计算预期的交换次数。我使用的方法如下图:
// 0 based index
float ans = 0.0;
for ( int i = 0; i < n-1; i++ )
for ( int j = i+1; j < n; j++ )
ans += getprob( a[i], a[j]); // computes probability that a[i]>a[j].
我是走对了路还是错过了什么?
【问题讨论】:
为什么不在随机数据集上运行它并找出答案? “事物的数量”很少是float
。而且我根本不懂getprob()
,它得到了数字,所以它可以……准确回答,概率是多少?
这在纸上可能比在程序中更容易解决。
@unwind 这个数字是浮点数,因为我必须计算预期的交换次数,并且我必须为元素 a[i] > a[j] ( i
见this 回答。
【参考方案1】:
计算交换的最佳方法是在交换的 if 条件中包含计数器变量。
int swapCount=0;
for (i = 0; i < (length-1); ++i)
for (j = 0; j < (length-i-1); ++j)
if(array[j] > array[j+1])
temp = array[j+1];
array[j+1] = array[j];
array[j] = temp;
swapCount++;
printf("Swap count : %d" ,swapCount);
【讨论】:
【参考方案2】:也许这会有所帮助。基本上,这提供了一个框架来在一组模拟数据集上运行冒泡排序并计算交换概率。
让这个概率= p 然后要找到预期的交换操作数量,您需要将其应用于真实数据集。设 n 为该数据集的大小。 那么期望数 = swapProbability * n * n
n*n 的出现是因为冒泡排序有 n * n 次预期操作。
float computeSwapProbability()
int aNumSwaps = 0
int aTotalNumberOfOperations = 0
For all simulation datasets
int i, j;
for i from n downto 1
for j from 1 to i-1
aTotalNumberOfOperations++
if (A[j] > A[j+1])
swap(A[j], A[j+1])
aNumSwaps++
return (float)aNumSwaps/aTotalNumberOfOperations;
【讨论】:
【参考方案3】:获得答案的最佳方法是运行冒泡排序算法本身并在 swap() 调用之后包含一个计数器。您的计算函数 (a) 需要的时间几乎与排序本身一样长(取决于 swap() 与 getprob() 的运行时间),并且 (b) 错过了排序时元素顺序发生变化的点。
顺便说一句,swap() 调用的确切数量取决于您需要排序的数据 - 您有 n*(n-1)/2 个比较,其中任何一个都可能导致交换(平均而言,一半您需要交换比较元素的时间)。
【讨论】:
@C Stoll:我明白你的意思,平均一半的时间你需要交换比较的元素,但这假设每个元素 a[i] > a[j] ( i a[j] ( i @TheRock 交换次数是数组中的反转次数。如果所有数组条目都不同并且排列是均匀分布的,那么预期的交换次数就是n*(n-1)/4
。如果getprob()
独立于值/位置,p*n*(n-1)/2
。但是你似乎有一些更复杂的约束。
@DanielFischer:我不必为一般情况做实际上在我的情况下每个数组元素都可以以某种概率改变,我可以获得 a[i] > a[ 的概率j] ( i
@TheRock:当您知道排序所需的交换次数时,您想做什么? (顺便说一句,swap() 通常也可以在 O(1) 时间内工作 - 至少对于内置类型和 STL 类)
@C.Stoll :由于数组有不同的可能配置,所以我计算了使用冒泡排序对数组进行排序时可能发生的交换次数。我在这里列出了所有约束***.com/questions/11340223/…。以上是关于冒泡排序中的交换次数的主要内容,如果未能解决你的问题,请参考以下文章