<排序算法> 冒泡排序BubbleSort
1.核心思想:
根据要求,对数组进行相邻的两两元素之间的比较,如果反序就进行交换,直到数组没有反序的相邻的元素为止。
2.实现:
①非标准冒泡排序:
让每一个关键字arr[i],都和它后面的每一个关键字做比较(即从arr[i+1]开始比较,依次向后),如果大则交换,这样第一位置的关键字在一次循环之后一定会变成这个数组中的最小值。
但是,这种排序方法不算是标准的冒泡排序,因为它不符合两两比较相邻记录。当然这种排序方法也是有缺陷的,那就是在排序好了前面的部分位置后,对其余关键字的排序是没有帮助的,如:反而有可能把相对比较小的记录交换到了比较靠后的位置。也就是说,这种实现方法的效率非常低。
②正宗冒泡算法:
如当i=0时,变量j从倒数第二个即arr[len-2]反向循环到i,逐个比较,将最小值交换到前面,知道最后找到最小值放置在下标为0的位置。
这种算法在不断循环的过程中,除了把关键字最小的放到第一的位置,还让较小的数距离目标地点更近了一些,显然这是比第一种算法有进步的,在上十万条数据的排序过程中,这种差距就会体现出来。
1 int i,j; 2 for(i=0;i<len;i++) 3 { 4 for(j=len-2;j>=i;j--) 5 { 6 if(arr[j] > arr[j+1]) 7 { 8 int t = arr[j]; 9 arr[j] = arr[j+1]; 10 arr[j+1] = t; 11 } 12 } 13 }
③冒泡排序的优化:针对数组部分有序:
可以在进入循环之前定义一个bool类型的flag变量并且初始化为true,进入第一层循环将这个flag置为false,如果在进入第二层循环之后,进行了交换就将这个变量置为true,当再次进行外层循环的时候,通过flag来判断上次两两比较有没有发生交换,如果没有,则flag值为false,不能再继续进行循环,排序结束。通过这样使冒泡算法在性能上得到了提升,避免了有序情况下无意义的循环判断,减少了循环和交换的次数。
代码实现:
1 #include<iostream> 2 using namespace std; 3 4 void BubbleSort(int arr[],int len) 5 { 6 if(arr == NULL || len <= 0) return ; 7 int i,j; 8 bool flag = true; 9 for(i=0;i<len && flag;i++) 10 { 11 flag = false; 12 for(j=len-2;j>=i;j--) 13 { 14 if(arr[j] > arr[j+1]) 15 { 16 flag = true; 17 int t = arr[j]; 18 arr[j] = arr[j+1]; 19 arr[j+1] = t; 20 //cout << "当i为此值时进行了循环:" << i << endl; 21 } 22 } 23 } 24 25 return ; 26 } 27 28 void PrintArr(int arr[],int len) 29 { 30 for(int i=0;i<len;i++) 31 cout << arr[i] << " "; 32 cout << endl; 33 34 return ; 35 } 36 37 int main() 38 { 39 //int arr[10] = {1,0,2,3,4,5,6,7,8,9}; 40 int arr[10] = {4,8,6,3,7,2,9,5,0,1}; 41 BubbleSort(arr,sizeof(arr)/sizeof(arr[0])); 42 PrintArr(arr,sizeof(arr)/sizeof(arr[0])); 43 44 system("pause"); 45 return 0; 46 }
3.时间复杂度:
最好情况:排序本身就有序,比较次数n-1,没有数据交换,时间复杂度O(n);
最坏情况:即使是逆序,比较次数(n*(n-1))/2,时间复杂度O(n2);
因此,总的时间复杂度为O(n2)。