冒泡排序

一、算法描述

假设序列中有N个元素:

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

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

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

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

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

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

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

二、算法分析

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

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

综上,因此冒泡排序总的平均时间复杂度为 O(n^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("\n"); 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--;//完成一次趟数减一
}
}

【算法】一般冒泡排序 O(n^2) 稳定的 C语言的更多相关文章

  1. 【算法】改进的冒泡排序 O(n^2) 稳定的 C语言

    改进的冒泡排序 一.算法描述 基于原冒泡排序 每次选取第一个元素作为主元往后进行比较,若遇到比它小的则放到它左边(即进行交换),若遇到比它大的则选取大的作为主元进行后续比较,每趟选取了无序列中最大元素 ...

  2. java基础算法之冒泡排序

    接触冒泡算法还是大一了,学习C语言的冒泡算法.现在唯一记得就是冒泡与选择了.出来刚刚工作的时候觉的算法基本没撒用处,现在发现这些都是很好的基础.因此自己也准备重新拾起这些知识. 冒泡排序 泡排序是一种 ...

  3. Java常见排序算法之冒泡排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  4. 我的Java开发学习之旅------>Java经典排序算法之冒泡排序

    冒泡排序(Bubble Sort)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已 ...

  5. java排序算法之冒泡排序和快速排序

    总结一下Java排序算法,以便记忆. 各类排序的时间复杂度: 排序方法 时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性 复杂性 直接插入排序 O(n2)O(n2) O( ...

  6. Java中的经典算法之冒泡排序(Bubble Sort)

    Java中的经典算法之冒泡排序(Bubble Sort) 神话丿小王子的博客主页 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一 ...

  7. java排序算法之冒泡排序(Bubble Sort)

    java排序算法之冒泡排序(Bubble Sort) 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一趟:首先比较第1个和第2个数 ...

  8. Java中数组的几个常用算法:插入算法,删除算法,冒泡排序算法

    前言: 在Java中我们常常会用数组,提到数组就不得不介绍数组中常用到的几个算法. 有插入算法,删除算法,冒泡排序算法等. 在学习这几个数组的算法前,我们先来了解一下关于数组一些基本知识. 数组的基本 ...

  9. 【DS】排序算法之冒泡排序(Bubble Sort)

    一.算法思想 冒泡排序是排序算法中比较有意思的一种排序方法,也很简单.其算法思想如下: 1)比较相邻的元素.如果第一个比第二个大,就交换他们两个. 2)对每一对相邻元素作同样的工作,从开始第一对到结尾 ...

随机推荐

  1. Java和Tomcat类加载机制

    转自:http://blog.csdn.net/codolio/article/details/5027423 加载类是运行程序的基础,了解Java和Tomcat的类加载机制对更有效地开发.调试Web ...

  2. hdu 2821 Pusher(dfs)

    Problem Description PusherBoy is an online game http://www.hacker.org/push . There is an R * C grid, ...

  3. Android开发:如何安全的中止一个自定义线程Thread

    http://blog.csdn.net/yanzi1225627/article/details/8582078 经研究,我推荐这种写法: /*自定义线程*/ class MyThread impl ...

  4. 使用 OpenSSL API 进行安全编程

    创建基本的安全连接和非安全连接 Kenneth Ballard ( kenneth.ballard@ptk.org), 自由程序员 Kenneth 是 Peru State College(位于 Pe ...

  5. tabhost中setup()和setup(LocalActivityManager activityGroup)

    如果用系统默认的tabhost时, 直接用getTabhost()初始化,整个类继承tabActivity. 当没有选择系统tabhost默认id时,而是自己定义的id时,必须使用 findViewB ...

  6. There is an error while getting planid. No Free partitions available

    问题概述 Oracle Advanced Supply Chain Planning最初的设置职责的时候有点问题,不知是不是要打什么补丁或其它配置什么东东,, 这个提示,,但我查到的分区是还有可用分区 ...

  7. TCP/IP 编程

    http://www.cnblogs.com/ggjucheng/archive/2012/08/18/2645324.html

  8. myeclipse 编码问题

    在使用eclipse+MyEclipse开发中,许多文件编码默认是ISO-8859-1,不支持中文(如常用的JSP),这样我们每次建文件都要手动改编码,其实我们可以在设置文件默认编码,今后再创建时就不 ...

  9. Android开发之手势滑动(滑动手势监听)详解

    Android开发之手势滑动(滑动手势监听)详解 在Android应用中,经常需要手势滑动操作,比如上下滑动,或左右方向滑动,处理手势滑动通常有两种方法:一种是单独实现setOnTouchListen ...

  10. Python实战:美女图片下载器,海量图片任你下载

    Python应用现在如火如荼,应用范围很广.因其效率高开发迅速的优势,快速进入编程语言排行榜前几名.本系列文章致力于可以全面系统的介绍Python语言开发知识和相关知识总结.希望大家能够快速入门并学习 ...