【算法】一般冒泡排序 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)对每一对相邻元素作同样的工作,从开始第一对到结尾 ...
随机推荐
- Java和Tomcat类加载机制
转自:http://blog.csdn.net/codolio/article/details/5027423 加载类是运行程序的基础,了解Java和Tomcat的类加载机制对更有效地开发.调试Web ...
- hdu 2821 Pusher(dfs)
Problem Description PusherBoy is an online game http://www.hacker.org/push . There is an R * C grid, ...
- Android开发:如何安全的中止一个自定义线程Thread
http://blog.csdn.net/yanzi1225627/article/details/8582078 经研究,我推荐这种写法: /*自定义线程*/ class MyThread impl ...
- 使用 OpenSSL API 进行安全编程
创建基本的安全连接和非安全连接 Kenneth Ballard ( kenneth.ballard@ptk.org), 自由程序员 Kenneth 是 Peru State College(位于 Pe ...
- tabhost中setup()和setup(LocalActivityManager activityGroup)
如果用系统默认的tabhost时, 直接用getTabhost()初始化,整个类继承tabActivity. 当没有选择系统tabhost默认id时,而是自己定义的id时,必须使用 findViewB ...
- There is an error while getting planid. No Free partitions available
问题概述 Oracle Advanced Supply Chain Planning最初的设置职责的时候有点问题,不知是不是要打什么补丁或其它配置什么东东,, 这个提示,,但我查到的分区是还有可用分区 ...
- TCP/IP 编程
http://www.cnblogs.com/ggjucheng/archive/2012/08/18/2645324.html
- myeclipse 编码问题
在使用eclipse+MyEclipse开发中,许多文件编码默认是ISO-8859-1,不支持中文(如常用的JSP),这样我们每次建文件都要手动改编码,其实我们可以在设置文件默认编码,今后再创建时就不 ...
- Android开发之手势滑动(滑动手势监听)详解
Android开发之手势滑动(滑动手势监听)详解 在Android应用中,经常需要手势滑动操作,比如上下滑动,或左右方向滑动,处理手势滑动通常有两种方法:一种是单独实现setOnTouchListen ...
- Python实战:美女图片下载器,海量图片任你下载
Python应用现在如火如荼,应用范围很广.因其效率高开发迅速的优势,快速进入编程语言排行榜前几名.本系列文章致力于可以全面系统的介绍Python语言开发知识和相关知识总结.希望大家能够快速入门并学习 ...