zoukankan      html  css  js  c++  java
  • 【算法】一般冒泡排序 O(n^2) 稳定的 C语言

    冒泡排序

     一、算法描述                                                     

    假设序列中有N个元素:

    第一趟选取第一个元素作为关键字,从左至右比较,若遇到比它小的则放到它左边(也即两数进行交换),若遇到比它大的,则改为选取该元素作为关键字完成后续的比较,第一趟则将最大的数调整至序列的最末位置

    第二趟选取第一个元素作为关键字,从左至右比较,若遇到比它小的则放到它左边(也即两数进行交换),若遇到比它大的,则改为选取该元素作为关键字完成后续的比较,第二趟则将倒数第二大的数调整至序列的倒数第二位置

    第三趟选取第一个元素作为关键字,从左至右比较,若遇到比它小的则放到它左边(也即两数进行交换),若遇到比它大的,则改为选取该元素作为关键字完成后续的比较,第三趟则将倒数第三大的数调整至序列的倒数第三位置

    m趟选取第一个元素作为关键字,从左至右比较,若遇到比它小的则放到它左边(也即两数进行交换),若遇到比它大的,则改为选取该元素作为关键字完成后续的比较,第m趟则将倒数第m大的数调整至序列的倒数第m位置

    N趟选取第一个元素作为关键字,从左至右比较,若遇到比它小的则放到它左边(也即两数进行交换),若遇到比它大的,则改为选取该元素作为关键字完成后续的比较,第N趟(即最后一次)则将倒数第N大(即最小的)的数调整至序列的倒数第N位置(即首位)

    注:当没有发生过记录交换,则算法终止

    即每次选取第一个元素作为主元往后进行比较,若遇到比它小的则放到它左边(即进行交换),若遇到比它大的则选取大的作为主元进行后续比较,每趟选取了无序队列中最大元素放置无序列最后位,当一趟比较没有发生交换则为有序序列,即像吐泡泡一样第一次把最大的数吐到最末位,第二趟把倒数第二大的数吐到倒数第二位。。。。。

     二、算法分析                                                     

    当原始数据正向有序时为最好情况,此时只需进行一趟排序,作n-1次比较,因此最好情况下的时间复杂度是On

     

    当原始数据反向有序时为最坏情况,此时需进行n-1趟排序,这样需nn-1/2次比较,移动元素3nn-1/2次,因此最坏情况下时间复杂度为On^2

     

    综上,因此冒泡排序总的平均时间复杂度为 On^2) ,且只需定义一个临时变量用于交换,因此空间复杂度为O(1)

     

    冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法

     三、算法实现代码                                                 

    定义顺序表代码:

    typedef struct list {
    	int Size;//大小 
    	int Elements[MaxSize];//用数组存放 
    }List;//定义顺序表


    定义冒泡排序代码:

    void Maopaopaixu(List*lst)
    {
    	int i, j;
    	int temp;//用于交换
    	bool sorted;//用于判别是否发生过交换
    	sorted = false;
    	i = lst->Size - 1;//用于记录趟数
    	while (i > 0 && !sorted) //当i<=0时(已经完成了N趟排序)或sorted为ture时(某趟没有发生交换)退出
    	{   
    		sorted = true;
    		for (j = 0; j < i; j++)//完成0到i期间的比较,i逐渐变小
    		{                                               
    			if (lst->Elements[j + 1] < lst->Elements[j])//若主元大于需比较的也即其后面的元素,进行交换,也即
    			{                             //放到他左边若小于或等于,不做任何处理,也即换取了后一个数作为主元
    				temp = lst->Elements[j + 1];
    				lst->Elements[j + 1] = lst->Elements[j];
    				lst->Elements[j] = temp;
    
    				sorted = false;//若发生交换则为false,若该趟不发生一次交换,则sorted一直为true
    			}
    		}			
    		i--;//完成一次趟数减一
    	}
    }



     四、实例测试代码                                                 

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <stdbool.h>//布尔类型头文件,需支持C99
    #define MaxSize 99
    
    
    typedef struct list {
    	int Size;//大小 
    	int Elements[MaxSize];//用数组存放 
    }List;//定义顺序表
    
    void Maopaopaixu(List*lst);//冒泡排序函数声明
    
    int main(void) {
    	List a;//定义一个顺序表对象a
    	int i;
    	srand((unsigned)time(NULL)); //随机数种子
    	a.Size = 10;//定义大小为10
    
    	for (i = 0; i<10; i++)
    	{
    		a.Elements[i] = rand() % 10;//初始化顺序表
    	}
    
    	printf("初始原表为:");
    	for (i = 0; i < 10; i++)
    	{
    		printf("%d  ", a.Elements[i]);
    	}
    	printf("
    ");
    
    	Maopaopaixu(&a);//调用冒泡排序函数,修改值需传入地址
    
    	printf("经冒泡排序:");
    	for (i = 0; i < 10; i++)
    	{
    		printf("%d  ", a.Elements[i]);
    	}
    	getchar();
    	return 0;
    }
    
    
    void Maopaopaixu(List*lst)
    {
    	int i, j;
    	int temp;//用于交换
    	bool sorted;//用于判别是否发生过交换
    	sorted = false;
    	i = lst->Size - 1;//用于记录趟数
    	while (i > 0 && !sorted) //当i<=0时(已经完成了N趟排序)或sorted为ture时(某趟没有发生交换)退出
    	{   
    		sorted = true;
    		for (j = 0; j < i; j++)//完成0到i期间的比较,i逐渐变小
    		{                                               
    			if (lst->Elements[j + 1] < lst->Elements[j])//若主元大于需比较的也即其后面的元素,进行交换,也即
    			{                             //放到他左边若小于或等于,不做任何处理,也即换取了后一个数作为主元
    				temp = lst->Elements[j + 1];
    				lst->Elements[j + 1] = lst->Elements[j];
    				lst->Elements[j] = temp;
    
    				sorted = false;//若发生交换则为false,若该趟不发生一次交换,则sorted一直为true
    			}
    		}			
    		i--;//完成一次趟数减一
    	}
    }




  • 相关阅读:
    货币系统
    纸牌
    活动
    KKT-黑白球
    POJ2676-Sudoku
    POJ1717-Dominoes
    POJ1088-滑雪
    POJ1862-Stripies
    POJ2531-Network Saboteur
    2019.12.13 数的划分
  • 原文地址:https://www.cnblogs.com/Ahair/p/5005560.html
Copyright © 2011-2022 走看看