1. 程式人生 > >C/C++ 折半查詢與順序查詢【對比分析】

C/C++ 折半查詢與順序查詢【對比分析】

線上性表的順序儲存結構中用到的查詢方式莫過於順序查詢和折半查詢;

儘管順序查詢的時間複雜度為O(n), 折半查詢的時間複雜度為O(log2n),相比之下折半查詢就顯得效率更高,

但是二者使用的場合不同,需要滿足的條件也不同,於是乎優劣之分便不再那麼重要。

 

首先博主對二者的效率做了一個簡單的測試:

對已經進行排序後的含有10000的隨機數的陣列分別進行順序查詢與折半查詢,查詢的值隨機賦予。

可結果卻不在我意料之中???意料之中後者應該慢一些才對?

 

文中用到的顯示函式呼叫的時間方法:

    cout << "Binary_Search :" << endl;
    start = clock();      // 1
    BinarySearch(data, search_data, length);    //這裡進行函式呼叫
    end = clock();     // 2
    cout << "Binary_Search spend " << (double)(end - start) / CLOCKS_PER_SEC << "s" << endl << endl;      // 3

 

 *文中給出了C語言的實現與C++的實現 (見後方原始碼)

****************************************************************************************************************************************
 

 

一:差異對比分析


1>   折半查詢要求查詢的資料是有序的,然而順序查詢卻對資料沒有要求(二者都是順序儲存結構);

2>   如果將兩種查詢方法對有序陣列實施操作:

       折半查詢可以在比較次數很少的情況下找到資料 (可開頭的實驗結果說明為什麼時間還要很久?),

       更加適合用於判斷某資料是否存在於所查詢的場所。

       文章開篇的實驗結果中查詢到的陣列下標也直接說明了:

       折半查詢只是為了快速確定某資料是否存在(查到的資料不是排序後的該資料的第一個)。

       如果想要查詢所有的資訊,因為資料有序,所以可以在找到第一個資料的時候向左右方向拓展搜尋,輸出一致的結果。

3>   如果將兩種方法對無序陣列進行操作:

       折半查詢此時已不再試用。

 

二:原始碼(基於C語言)

#include <bits/stdc++.h>
using namespace std;

void Simple_Search(int *array, int search_data, int length)
{
	bool Judge = false;
	for (int i = 0; i < length; i++)
	{
		if (array[i] == search_data)
		{
			cout << "Search_Successful!" << endl;
			cout << "array[" << i << "]=" << search_data << endl;
			//while (true)
			//{
			//	if (search_data == array[i + 1])
			//	{
			//		i++;
			//		cout << "array[" << i << "]=" << search_data << endl;
			//	}
			//	else
			//	{
			//		//cout << endl;
			//		break;
			//	}
			//}
			return;
		}
	}
	if (!Judge)
	{
		cout << "Cannot find " << search_data << "!" << endl;
	}
}

void BinarySearch(int *array, int search_data, int length)
{
	int low, mid, high;
	low = 0;
	high = length - 1;
	bool Judge = false;
	while (low <= high)
	{
		mid = (low + high) / 2;
		//Anchor:
		if (array[mid] == search_data)
		{
			Judge = true;
			cout << "Search_Data_Successful! \narray[" << mid << "]=" << search_data << endl;
		//	int remember_mid = mid;
		//	while (true)
		//	{
		//		if (search_data == array[mid + 1])
		//		{
		//			mid = mid + 1;
		//			cout << "array[" << mid << "]=" << search_data << endl;
		//		}
		//		else
		//		{
		//			//cout << endl;
		//			break;
		//		}
		//	}
		//	mid = remember_mid;
		//	while (true)
		//	{
		//		if (search_data == array[mid - 1])
		//		{
		//			mid = mid - 1;
		//			cout << "array[" << mid << "]=" << search_data << endl;
		//		}
		//		else
		//		{
		//			//cout << endl;
		//			break;
		//		}
		//	}
			return;
		}
		else if (array[mid] < search_data)
		{
			low = mid + 1;
		}
		else
		{
			high = mid - 1;
		}
	}
	if (!Judge)
	{
		cout << "Cannot find " << search_data << "!" << endl;
	}

}

void Bubble_Sorted(int *array,int length)
{
	int temp;
	for (int i = length-1; i>0; i--)
	{
		//bool exchange = false;
		for (int j = 0; j < i; j++)
		{
			if (array[j] > array[j + 1])
			{
				temp = array[j];
				array[j] = array[j + 1];
				array[j + 1] = temp;
				//exchange = true;
			}
		}
        //if (!exchange) return;
	}
}
int main()
{
	time_t start, end;
	//不加unsigned()的時候:warning C4244: “引數”: 從“time_t”轉換到“unsigned int”,可能丟失資料
	srand(unsigned(time(NULL)));
	int data[10000];
	int length = 10000;
	int search_data = rand() % 100;
	for (int i = 0; i < 10000; i++)
		data[i] = rand() % 1000;
	Bubble_Sorted(data, length);
	for (int i = 0; i < length; i++)
	{
		if (i % 10 == 0 && i != 0)
			cout << endl;
		printf("%-5d", data[i]);
	}
	cout << endl << endl;
	cout << "Binary_Search :" << endl;
	start = clock();
	BinarySearch(data, search_data, length);
	end = clock();
	cout << "Binary_Search spend " << (double)(end - start) / CLOCKS_PER_SEC << "s" << endl << endl;
	cout << "Simple_Search :" << endl;
	start = clock();
	Simple_Search(data, search_data, length);
	end = clock();
	cout << "Simple_Search spend " << (double)(end - start) / CLOCKS_PER_SEC << "s" << endl;
	
	return 0;
}

 

三:原始碼(基於C++)

1> Search_Simple+Binary.h

#include <iostream>
#include <string>
#include <time.h>
#define _CRT_SECCURE_NO_WARNINGS_

class Simple_Search{
private:
	int number[50];
public:
	void Get_Num();
	bool Search_data(int);
	void Judge(int);
	void Display_number(int);
};

class Binary_Search{
private:
	int number_binary[50];
public:
	void Sort_Bubble(int length);
	void Get_Num_binary();
	bool Search_data_binary(int,int);
	void Display_number_binary(int);
};

2> Search_Simple+Binary.cpp

#include "Search_Simple+Binary.h"
using namespace std;

void Simple_Search::Get_Num()
{
	srand(unsigned(time(NULL)));
	for(int i=0;i<50;i++)
	{
		number[i]=rand()%100;
	}
}

bool Simple_Search::Search_data(int search_data)
{
	bool ischanged = false;
	for(int i=0;i<50;i++)
	{
		if(search_data == number[i])
		{
			ischanged = true;
			return true;
		}
		else
		{
			i++;
		}
	}
	if(!ischanged)
	{
		return ischanged;
	}
	return ischanged;
}

void Simple_Search::Judge(int Search_data)
{
	cout << "Search_Result:" << endl;
	bool result = Simple_Search::Search_data(Search_data);
	if(result)
	{
		cout << "Search " << Search_data << " Successful!" << endl; 
	}
	else
	{
		cout << "Cannot find this number! (" << Search_data << ")" << endl;
	}
}
void Simple_Search::Display_number(int length)
{
	cout << "50 Test Data: " << endl;
	for(int i=0;i<length;i++)
	{
		printf("%-4d",number[i]);
		if((i+1)%5==0) 
			cout << endl;
	}
}

void Binary_Search::Get_Num_binary()
{
	srand(unsigned(time(NULL)));
	for(int i=0;i<50;i++)
	{
		number_binary[i]=rand()%100;
	}
}

bool Binary_Search::Search_data_binary(int search_data,int length)
{
	cout << "Search_Result:" << endl;
	int low,middle,high;
	low = 0;
	high = length-1;
	bool ischanged = false;
	while(low<=high)
	{
		middle = (low+high)/2;
		if(number_binary[middle]==search_data)
		{
			cout << "Search " << search_data << " Successful!" << endl;
			ischanged = true;
			return ischanged;
		}
		else if(number_binary[middle]<search_data)
		{
			low = middle+1;
		}
		else
		{
			high = middle-1;
		}
	}
	if(!ischanged)
	{
		cout << "Cannot find this number! (" << search_data << ")" << endl;
		return ischanged;
	}
	return ischanged;
}
void Binary_Search::Sort_Bubble(int length)    //冒泡優化
{
	int temp;
	int position = length-1;
	int position_temp = length-1;
	for(int i =length-1;i>0;i--)
	{
		bool ischanged = false;
		for(int j = 0;j<position;j++)
		{
			if(number_binary[j]>number_binary[j+1])
			{
				temp = number_binary[j];
				number_binary[j] = number_binary[j+1];
				number_binary[j+1] = temp;
				ischanged = true;
				position_temp = j;
			}
		}
		position = position_temp;
		if(!ischanged) return;
	}
}

void Binary_Search::Display_number_binary(int length)
{
	cout << "50 Test Data: " << endl;
	for(int i = 0;i<length;i++)
	{
		printf("%-4d",number_binary[i]);
		if((i+1)%5==0) 
			cout << endl;
	}
}

3> Main_Function.cpp

#include "Search_Simple+Binary.h"
using namespace std;

int main()
{
	cout << "Simple_Search:" << endl;
	Simple_Search S1;
	S1.Get_Num();
	S1.Display_number(50);
	S1.Judge(8);
	cout << "\nBinary_Search:" << endl;
	Binary_Search S2;
	S2.Get_Num_binary();
	S2.Sort_Bubble(50);
	S2.Display_number_binary(50);
	S2.Search_data_binary(8,50);
	return 0;
}

 

四:在Linux下使用Vim對標頭檔案進行封裝

< updating... >