冒泡、選擇、快排、插入排序—效能簡單測試/rand()邊界值——c++資料結構

kuLong_x發表於2020-12-10

四種排序演算法效能比較(冒泡、選擇、快排、插入排序——資料結構)

rand()函式的邊界處理

  1. 模組一:四類排序演算法
  2. 模組二:問題解決
    一、四類排序都採用了模板的處理方法
    二、快速排序採用了遞迴的方式
    三、利用一個函式CreateArray生成一個vector去傳入四個動態陣列中進行深拷貝,通過對同一資料的排序,來觀測四種排序的效能比較
    四、資料規模有一定的講究,一開始我用100個數的陣列去觀測,結果跑出來都是0ms,因為資料規模小,幾乎是在同一時間完成。所以要麼擴大資料的規模,要麼增倍同一排序的次數使時間更明顯,這裡我採用擴大資料規模的方式。

具體程式碼如下:

#include<iostream>
#include<vector>
#include <windows.h> 
#include<map>
#include <algorithm>
using namespace std;
template<class T>
int length(T& arr);
template<typename elementType>
void maopao(elementType* a, int size);//氣泡排序 傳引數組,陣列長度
template<typename elementType>
void xuanze(elementType* a, int size);//選擇排序 傳引數組,陣列長度
template<typename elementType>
void insert(elementType* a, int size);//插入排序 傳引數組,陣列長度
template<typename elementType>
void quick(elementType* a, int first, int last);//快速排序 傳引數組,陣列起始點、結束點
template<typename elementType>
int split(elementType* a, int first, int last);
template<typename elementType>
vector<elementType> CreateArray(int size);
int main() {
	ULONGLONG start, end;//定義GetTickCount_t變數
	int size = 32768;
	int index = 0;
	vector<int> array = CreateArray<int>(size);
	int* a = new int[size],
		* b = new int[size],
		* c = new int[size],
		* d = new int[size];
	for (vector<int>::iterator it = array.begin(); it != array.end(); it++) {
		a[index] = *it;
		b[index] = *it;
		c[index] = *it;
		d[index] = *it;
		index++;
	}
	start = GetTickCount64();    //開始時間
	xuanze(a, size);
	end = GetTickCount64();   //結束時間
	cout << "選擇排序所需時間 = " << ((end - start) * 1.0 ) << "ms" << endl;  //輸出時間(單位:s)
	start = GetTickCount64();
	maopao(b, size);
	end = GetTickCount64();   //結束時間
	cout << "氣泡排序所需時間 = " << ((end - start) * 1.0) << "ms" << endl;  //輸出時間(單位:s)
	start = GetTickCount64();
	quick(c, 0, size-1);
	end = GetTickCount64();   //結束時間
	cout << "快速排序所需時間 = " << ((end - start) * 1.0 ) << "ms" << endl;  //輸出時間(單位:s)
	start = GetTickCount64();
	insert(d, size);
	end = GetTickCount64();   //結束時間
	cout << "插入排序所需時間 = " << ((end - start) * 1.0) << "ms" << endl;  //輸出時間(單位:s)
	
	return 0;
}

template<typename elementType>
void xuanze(elementType* a, int size) {
	elementType temp;
	for (int i = 0; i < size; i++) {
		int minNumIndex = i;
		for (int k = i + 1; k < size; k++) {
			if (a[minNumIndex] > a[k]) {
				minNumIndex = k;
			}
		}
		if (minNumIndex != i) {
			temp = a[minNumIndex];
			a[minNumIndex] = a[i];
			a[i] = temp;
		}/*
		for (int p = 0; p < size; p++) {
			cout << a[p] << " ";
		}
		cout << endl;*/
	}
}
template<typename elementType>
void insert(elementType* a, int size)
{
	elementType temp;
	for (int i = 0; i < size; i++) {
		for (int k = i + 1; k < size; k++) {
			if (a[i] > a[k]) {
				temp = a[k];
				a[k] = a[i];
				int p = i;
				while (a[p] < temp && p>1) {
					a[p] = a[p - 1];
				}
				a[p] = temp;
			}
		}
		/*for (int p = 0; p < size; p++) {
			cout << a[p] << " ";
		}
		cout << endl;*/
	}

}
template<typename elementType>
void quick(elementType* a, int first, int last)
{
	int pos = 0;
	if (first < last) {
		pos = split(a, first, last);
		quick(a, first, pos - 1);
		quick(a, pos + 1, last);
	}

}
template<typename elementType>
int split(elementType* x, int first, int last)
{
	elementType pivot = x[first];
	int left = first,
		right = last;
	while (left < right) {
		while (pivot < x[right]) {
			right--;
		}
		while (left < right && (x[left] < pivot || x[left] == pivot)) {
			left++;
		}
		if (left < right) {
			int temp = x[left];
			x[left] = x[right];
			x[right] = temp;
		}
	}
	int pos = right;
	x[first] = x[pos];
	x[pos] = pivot;
	return pos;
}
template<typename elementType>
vector<elementType> CreateArray(int size)
{
	vector<elementType> Array;
	map<elementType, int>ArrayMap;
	typename  map<elementType, int > ::iterator it;
	for (int i = 0; i < size; i++) {
		elementType num = rand() % size;
		it = ArrayMap.find(num);
		while (it != ArrayMap.end()) {
			num = rand() % size;
			it = ArrayMap.find(num);
		}
		Array.push_back(num);
		ArrayMap[num] = 1;
	}
	
	return Array;
}
template<typename elementType>
void maopao(elementType* a, int size) {
	bool flag = true;
	for (int i = 0; i < size && flag; i++) {
		flag = false;
		for (int k = 1; k < size; k++) {
			if (a[k] < a[k - 1]) {
				elementType temp = a[k];
				a[k] = a[k - 1];
				a[k - 1] = temp;
				flag = true;
			}
		}
		/*for (int p = 0; p < size; p++) {
			cout << a[p] << " ";
		}
		cout << endl;*/
	}

}
template<class T>
int length(T& arr)
{
	return (sizeof(arr) / sizeof(arr[0]));
}



跑出來的截圖如下:
四類排序測試資料結果(資料規模大小:32768)
在規模相對適中的時候,不過這規模也比較小,跑出來很明顯是快排效能比較好,選擇次之

關於快排的一些介紹和演算法內容,是比較好理解的,就是不斷拆分比較左右
在這裡插入圖片描述但是過程中一直遇到一個問題,我想測試更大規模的資料去更深一步的瞭解快排在遇到大資料時候的效能,比如去處理十萬個資料的資料時候,它的呼叫棧的遞迴會不會顯得其效能弱勢起來,相比較其他的基本排序手段,反而基本的排序手段會技高一籌。

但我一直測不出來!介面卡住了!!資料只要超過32769就會介面卡住,經過不斷除錯,查語句,廢話不多說,後來發現是rand()最大能隨機產生32767的數,於是一直while出不來,實在是對很多基本的內容都不熟悉。
解決辦法就是擴大我能產生的隨機數的範圍,可以寫個函式來產生指定大範圍的隨機數。歐克,今天到這裡,謝謝。

這篇部落格是我的第一篇部落格,單純用於記錄一些碼程式碼時候的注意事項,希望我的一些蠢笨的經驗可以幫助到大家。如果有誤,歡迎指正!

相關文章