冒泡排序是选择排序中最为简单的一种,也是最为基础的一种。
他的规则是将第一个元素与第二个比较,比较后移动元素,再用第二个与第三个比较,直至最后一个元素,这是完成一趟排序,将最大的元素排到了最后。依此进行第二趟,第三趟直至排序完成。
先看下实际例子:
一般情况:
i值 原序列:10 3 7 8 5 2 1 4 9 6 交换范围
1 第1遍: 3 7 8 5 2 1 4 9 6 10 [0—10-1)
2 第2遍: 3 7 5 2 1 4 8 6 9 10 [0—10-2)
3 第3遍: 3 5 2 1 4 7 6 8 9 10 [0—10-3)
4 第4遍: 3 2 1 4 5 6 7 8 9 10 [0—10-4)
5 第5遍: 2 1 3 4 5 6 7 8 9 10 [0—10-5)
6 第6遍: 1 2 3 4 5 6 7 8 9 10 [0—10-6)
7 第7遍: 1 2 3 4 5 6 7 8 9 10 [0—10-7)
8 第8遍: 2 1 3 4 5 6 7 8 9 10 [0—10-8)
9 第9遍: 1 2 3 4 5 6 7 8 9 10 [0—10-9)
那普通的冒泡排序就是如下这种写法
#include <iostream>
typedef int ElemType;
void BubbleSort(ElemType *arr,int length);
int main() {
using namespace std;
std::cout << "BubbleSort!" << std::endl;
ElemType arr[] = {90,80,70,60,30,20,10};
int length = sizeof(arr)/ sizeof(arr[0]);
BubbleSort(arr,length);
for (int i = 0; i < length; ++i) {
cout<<"The "<<i+1<<"th element is "<<arr[i]<<endl;
}
return 0;
}
void BubbleSort(ElemType *arr,int length){
ElemType temp;
for (int i = 1; i < length ; ++i) {//进行n-1趟排序
for (int j = 0; j < length-i; ++j) {//在前n-i个未完成的排序中进行比较和元素移动
if(arr[j] > arr[j+1]){//交换
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
时间复杂度:最好情况若表中的元素已经符合正向排序,那么只需比较n-1次即可排序完成,但是程序并不知道这已经完成了,于是会继续执行,那么执行次数为n-1+n(n-1)/2+交换次数,最好情况交换次数为0,最坏为3*n(n-1)/2,最终拟合时间复杂度为O(n^2)
那么对于已经基本有序的表能否更快一点呢?意思是让系统知道这个表已经排完序的时候,不用每次都执行完浪费时间呢?
我想唯一能让计算机知道这一点的就是用计算机的语言去告知他,就是设置标志位。
我的构想是,若在交换的内外设置标志位,标志不同的状态,每次只要进入了if语句,改变了元素,证明这次就没有排序完成;若没有进入if语句,那么就意味着其实已经完成排序可以不用继续进行下去了。
代码如下:
#include <iostream>
#include <curses.h>
typedef int ElemType;
void BubbleSort(ElemType *arr,int length);
int main() {
using namespace std;
std::cout << "BubbleSort!" << std::endl;
ElemType arr[] = {90,80,70,60,30,20,10};
int length = sizeof(arr)/ sizeof(arr[0]);
BubbleSort(arr,length);
for (int i = 0; i < length; ++i) {
cout<<"The "<<i+1<<"th element is "<<arr[i]<<endl;
}
return 0;
}
void BubbleSort(ElemType *arr,int length){
ElemType temp;
bool CHANGE = true;//初始化为true
for (int i = 1; i < length && CHANGE ; ++i) {//进行n-1趟排序,判断条件为true
CHANGE = FALSE;//外部判断先为false
for (int j = 0; j < length-i; ++j) {//在前n-i个未完成的排序中进行比较和元素移动
if(arr[j] > arr[j+1]){//交换
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
CHANGE = true;//如果还有元素进行交换,那么就置为true
}
}
}
}
对于最坏的情况,冒泡排序当然无力改变时间复杂度,但对于最好的情况或是已经基本有序的数列,可以有效缩短时间。拿最好情况来比较,假设数列已经简单有序,则只需比较n-1次就结束函数了,无需再进行后面的操作。
1万+

被折叠的 条评论
为什么被折叠?



