C语言—冒泡排序及其优化

原始冒泡排序实现

  • #include<stdio.h>
    int main(void){
        //定义数组大小
        int N=8;
    	//用于计算交换的次数
    	int sum=0;
        //定义数组元素
        int array[]={5,8,6,3,9,2,1,7};
        
        //使用冒泡的方式进行排序
        for(int i=0;i<N;i++){
        	for(int j=0;j+i<N-1;j++){
        		if(array[j]>array[j+1]){
        			int temp=array[j];
        			array[j]=array[j+1];
        			array[j+1]=temp;
        		}
        	}
    		sum++;
        }
    
        //输出
        for(i=0;i<N;i++){
    	    printf("%d ",array[i]);
        }
        printf("\n");
    	printf("大循环的次数为:%d",sum);
    	printf("\n");
        return 0;
    }

 优化一

  • 如果在原始冒泡排序的后边几轮已经不需要排序了,但是按照原先的排序算法,还是要进行执行,针对这种情况进行改进,增加一个判断的变量 isSorted = true,如果这有元素发生交换,那么会将 isSorted 变为 false,否则的话表示已经排序好了不需要进行后边的交换了,那么直接 break
  • #include<stdio.h>
    int main(void){
        //定义数组大小
        int N=8;
    	//用于计算交换的次数
    	int sum=0;
        //定义数组元素
        int array[]={5,8,6,3,9,2,1,7};
        
        //使用冒泡的方式进行排序
    	for(int i=0;i<N;i++){
    		//有序标记,每一轮的初始值都是true
    		bool isSorted=true;
    		for(int j=0;j+i<N-1;j++){
    			if(array[j]>array[j+1]){
    				int temp=array[j];
    				array[j]=array[j+1];
    				array[j+1]=temp;
    				//因为有元素交换,索引数组还不是有序的,标记变为false
    				isSorted=false;
    			}
    		}
    		if(isSorted){
    			break;
    		}
    		sum++;
    	}
    
    	//输出
    	for(i=0;i<N;i++){
    		printf("%d ",array[i]);
    	}
    	printf("\n");
    	printf("交换的次数为:%d",sum);
    	printf("\n");
    	return 0;
    }

优化二

  • 如果在某次交换中还没有交换到边界,但是后边的数据已经是有序的了,这种情况我们可以进行优化
  • #include<stdio.h>
    int main(void){
        //定义数组大小
        int N=8;
    	//用于计算交换的次数
    	int sum=0;
        //定义数组元素
        int array[]={2,1,3,4,5,6,7,8};
        
        //使用冒泡的方式进行排序
    	for(int i=0;i<N;i++){
    		//有序标记,每一轮的初始值都是true
    		bool isSorted=true;
    		//下次要进行交换的边界
    		int sortBorder=N-1;
    		for(int j=0;j+i<sortBorder;j++){
    			if(array[j]>array[j+1]){
    				int temp=array[j];
    				array[j]=array[j+1];
    				array[j+1]=temp;
    				//因为有元素交换,索引数组还不是有序的,标记变为false
    				isSorted=false;
    				//确定边界
    				sortBorder=j;
    			}
    		}
    		if(isSorted){
    			break;
    		}
    		sum++;
    	}
    
    	//输出
    	for(i=0;i<N;i++){
    		printf("%d ",array[i]);
    	}
    	printf("\n");
    	printf("大循环次数为:%d",sum);
    	printf("\n");
    	return 0;
    }

鸡尾酒排序

  • 鸡尾酒排序的元素比较和交换过程是双向的
  • 大致思想:奇数轮,从左向右比较和交换,偶数轮,从右向左比较和交换
  • #include<stdio.h>
    int main(void){
        //定义数组大小
        int N=8;
    	//用于计算交换的次数
    	int sum=0;
        //定义数组元素
        int array[]={2,3,4,5,6,7,8,1};
        
        //使用冒泡的方式进行排序
    	for(int i=0;i<N/2;i++){
    		//有序标记,每一轮的初始值都是true
    		bool isSorted=true;
    		//奇数轮,从左向右比较和交换
    		for(int j=i;j<N-i-1;j++){
    			//交换
    			if(array[j]>array[j+1]){
    				int t1=array[j];
    				array[j]=array[j+1];
    				array[j+1]=t1;
    				//因为有元素交换,索引数组还不是有序的,标记变为false
    				isSorted=false;
    			}
    		}
    		if(isSorted){
    			break;
    		}
    		//在偶数轮之前,将isSorted重新标记为true
    		isSorted=true;
    		for(j=N-i-1;j>i;j--){
    			//交换
    			if(array[j]<array[j-1]){
    				int t2=array[j];
    				array[j]=array[j-1];
    				array[j-1]=t2;
    				//因为有元素交换,索引数组还不是有序的,标记变为false
    				isSorted=false;
    			}
    		}
    		if(isSorted){
    			break;
    		}
    		sum++;
    	}
    
    	//输出
    	for(i=0;i<N;i++){
    		printf("%d ",array[i]);
    	}
    	printf("\n");
    	printf("大循环次数为:%d",sum);
    	printf("\n");
    	return 0;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值