冒泡排序及其優化(C++實現)

#include<iostream>
#include<vector>
using namespace std;

//冒泡排序的特點:每一輪冒泡過後,在過去一輪遍歷中訪問過的元素中的最大元素
//一定會到達它最終應當處在的位置。 

//基礎版本的冒泡排序:雙循環。外層循環控制冒泡次數,內層循環實現每一輪的
//冒泡處理:先進行元素比較,再進行元素交換。 
void bubbleSort_1(vector<int> &nums){
	int length=nums.size();
	for(int i=0;i<length-1;i++){
		for(int j=0;j<length-1-i;j++){
			if(nums[j]>nums[j+1]){
				int temp=nums[j];
				nums[j]=nums[j+1];
				nums[j+1]=temp;
			}
		}
	}
	return;
}

//第一種版本的冒泡排序的問題是:序列可能會提前達到有序,所以該版本會出現不必要的時間開銷,
//所以第二種版本的優化思路是:記錄每輪冒泡過程中是否出現元素交換,若無,說明序列已有序,結束排序。
void bubbleSort_2(vector<int> &nums){
	int length=nums.size();
	for(int i=0;i<length-1;i++){
		//有序標記,每一輪的初始值都是true 
		bool isSorted=true;
		for(int j=0;j<length-1-i;j++){
			if(nums[j]>nums[j+1]){
				int temp=nums[j];
				nums[j]=nums[j+1];
				nums[j+1]=temp;
				//因爲有元素交換,所以不是有序的,標記變爲false 
				isSorted=false;
			}
		}
		//若isSorted=true,說明已有序,故跳出循環,排序結束 
		if(isSorted){
			break;
		}
	}
} 

//按照前兩種方法的邏輯,每輪冒泡結束後,序列最右側會形成一個有序區,且有序區的長度等於冒泡截止到當前所進行的輪數
//但是實際上右側的有序區的長度可能會大於輪數,因此會有不必要的比較發生,造成時間上的浪費。所以,針對此問題提出的優化方案是:
//維護一個變量,記錄下無序數列的邊界,邊界往後就是有序區
void bubbleSort_3(vector<int> &nums){
	int length=nums.size();
	//記錄最後一次交換的位置 
	int lastExchangeIndex=0;
	//無序區的邊界,每次只需比較到這裏爲止
	int sortBorder=length-1; 
	for(int i=0;i<length-1;i++){
		//有序標記:每一輪的初始值都是true
		bool isSorted=true;
		for(int j=0;j<sortBorder;j++){
			if(nums[j]>nums[j+1]){
				int temp=nums[j];
				nums[j]=nums[j+1];
				nums[j+1]=temp;
				//因爲有元素的交換。所以不是有序的,標記變爲false
				isSorted=false;
				//更新最後一次交換元素的位置
				lastExchangeIndex=j; 
			}
		} 
		//更新無序區的邊界
		sortBorder=lastExchangeIndex;
		if(isSorted){
			break;
		} 
	}
} 
void printArray(vector<int> nums){
	for(int i=0;i<nums.size();i++){
		cout<<nums[i]<<" ";
	}
	cout<<endl;
}
int main()
{
	vector<int> nums_1,nums_2,nums_3;
	//生成三個降序序列以備測試,設置成降序是爲了賦值方便,因爲本代碼旨在介紹冒泡排序這種算法
	//而不是用實例測試排序算法優化後的性能,所以採取這種簡便但是可能不夠合理的賦值方法 
	for(int i=0;i<5;i++){
		nums_1.push_back(5-i);
		nums_2.push_back(6-i);
		nums_3.push_back(7-i);
	} 
	bubbleSort_1(nums_1);
	//打印排序後的nums_1 
	printArray(nums_1);
	
	bubbleSort_2(nums_2);
	//打印排序後的nums_2 
	printArray(nums_2);
	
	bubbleSort_3(nums_3);
	//打印排序後的nums_3 
	printArray(nums_3);
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章