冒泡排序bubblesort

以前对冒泡排序不够重视。依照算法书硬背下来似乎也就够了。算法依次扫描序列中的逆序对,把它交换过来。那么n 个元素的序列,可以划分出 n-1个邻接的序对,这是不言而喻的。从左到右扫描逆序对的时候,每次交换,都把较大的那个交换进下一个序对, n-1个序对扫描完的时候,最后一个序对的最后一个元素就是整个序列的最大者。

所以冒泡排序的第一趟扫描确定了最终序列的第n个元素,把它排除之后,序列缩短为 n-1个元素的序列,这样就可以继续套用前面的做法,直到序列缩短为只有2个元素,2个元素如果逆序,交换一下任务完成,如果不逆序,即为所求任务也完成,总共进行了n-1趟扫描。

组织成代码的时候,随之每一趟扫描,序列是逐步缩小的。用循环代码
for(i=n-1; i>0; i–)
来示意"每次剔除最大一个元素,使序列规模缩小1",最为自然。因为c语言的数组从0开始编码,最后一个下标是n-1,i=n-1就表示这一趟就是要确定第n-1的数据。看到大家都写
for(i=0; i<n-1; i++)
这样虽然也是可以,但仔细推敲究竟已经作了一步换算。

下面给出代码,用for(i=n-1; i>0; i–) 缩小规模,用邻接的序对(k,j), k等于j-1,来比较和交换,这样翻译比较直接,不易出错:

void print(int a[], int n)
{
    
    
    int k;
    for (k=0; k<n; k++)
        printf("%d ", a[k]);
    printf("\n");
}
void printp1(int a[], int n, int i)
{
    
    
        int j;
        printf (":");
        for(j=0;j<n;j++) {
    
    
                if (j>=i)  printf(" %d", a[j]);
                else printf(" *");
        }
        printf("\n");
}

void bubble(int a[], int n)
{
    
    
    int i, k, j;
    int t;
	
	print(a, n);
	printp(a,n, n);

    for (i=n-1; i>0; i--) {
    
    
        for (k=0, j=1; j<=i; k=j++) {
    
    
            if (a[k] > a[j]) {
    
    
                t = a[j];
                a[j] = a[k];
                a[k] = t;
		        print(a, n);
            }
			printp(a,n, i);
        }
    }
}

Guess you like

Origin blog.csdn.net/aaasssdddd96/article/details/120447692