【算法】一般冒泡排序 O(n^2) 稳定的 C语言
冒泡排序
一、算法描述
假设序列中有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语言的更多相关文章
- 【算法】改进的冒泡排序 O(n^2) 稳定的 C语言
改进的冒泡排序 一.算法描述 基于原冒泡排序 每次选取第一个元素作为主元往后进行比较,若遇到比它小的则放到它左边(即进行交换),若遇到比它大的则选取大的作为主元进行后续比较,每趟选取了无序列中最大元素 ...
- java基础算法之冒泡排序
接触冒泡算法还是大一了,学习C语言的冒泡算法.现在唯一记得就是冒泡与选择了.出来刚刚工作的时候觉的算法基本没撒用处,现在发现这些都是很好的基础.因此自己也准备重新拾起这些知识. 冒泡排序 泡排序是一种 ...
- Java常见排序算法之冒泡排序
在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...
- 我的Java开发学习之旅------>Java经典排序算法之冒泡排序
冒泡排序(Bubble Sort)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已 ...
- java排序算法之冒泡排序和快速排序
总结一下Java排序算法,以便记忆. 各类排序的时间复杂度: 排序方法 时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性 复杂性 直接插入排序 O(n2)O(n2) O( ...
- Java中的经典算法之冒泡排序(Bubble Sort)
Java中的经典算法之冒泡排序(Bubble Sort) 神话丿小王子的博客主页 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一 ...
- java排序算法之冒泡排序(Bubble Sort)
java排序算法之冒泡排序(Bubble Sort) 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一趟:首先比较第1个和第2个数 ...
- Java中数组的几个常用算法:插入算法,删除算法,冒泡排序算法
前言: 在Java中我们常常会用数组,提到数组就不得不介绍数组中常用到的几个算法. 有插入算法,删除算法,冒泡排序算法等. 在学习这几个数组的算法前,我们先来了解一下关于数组一些基本知识. 数组的基本 ...
- 【DS】排序算法之冒泡排序(Bubble Sort)
一.算法思想 冒泡排序是排序算法中比较有意思的一种排序方法,也很简单.其算法思想如下: 1)比较相邻的元素.如果第一个比第二个大,就交换他们两个. 2)对每一对相邻元素作同样的工作,从开始第一对到结尾 ...
随机推荐
- Android.mk 的含义
LOCAL_PATH:=$(call my-dir) LOCAL_PATH是定义源文件在哪个目录用的. my-dir 是个定义的宏方法, $(call my-dir)就是调用这个叫 my-dir的宏方 ...
- c#调用api(FindFirstFile,FindNextFile)高效遍历目录文件【转载】
在c#下遍历目录,应用最多的应该就是 System.IO.DirectoryInfo.GetDirectories或GetFiles了,但是当目录特别大,文件特别多时,效率不尽人意,此时我们很容易想到 ...
- Android开发_控制硬加速hardwareAccelerated
控制硬加速 hardwareAccelerated也是一种优化的手段 从Android3.0 (API level11)开始,Android的2D显示管道被被设计得更加支持硬加速了.硬加速使用GPU承 ...
- [ES7] Descorator: evaluated & call order
When multiple decorators apply to a single declaration, their evaluation is similar to function comp ...
- 关于Opengl中将24位BMP图片加入�一个alpha通道并实现透明的问题
#include <windows.h>#include <GL/glut.h>#include <GL/glaux.h>#include <stdio.h& ...
- Android(java)学习笔记172:BroadcastReceiver之 Android广播机制
Android广播机制 android系统中有各式各样的广播,各种广播在Android系统中运行,当"系统/应用"程序运行时便会向Android注册各种广播.Android接收到广 ...
- Class Fxp\Composer\AssetPlugin\Repository\NpmRepository does not exist
使用 composer 安装 laravel 时报错, 如下: [ReflectionException] Class Fxp\Composer\AssetPlugin\Repository\NpmR ...
- HTML5本地化应用开发-HTML5 Web存储详解
文章不是简单的的Ctrl C与V,而是一个字一个标点符号慢慢写出来的.我认为这才是是对读者的负责,本教程由技术爱好者成笑笑(博客:http://www.chengxiaoxiao.com/)写作完成. ...
- 用Eclipse+xdebug调试PHP总是在首行自动断点解决方法
问题描述: 使用Eclipse+PDT+xdebug调试PHP程序时,总是在程序的第一行(首行)自动断点,不方便调试. 解决方法: 分别在下面3个位置配置,取消 Break at First Line ...
- 如何打包成jar包自己看呢?
第一步:选择你要导出的部分 第二步: