(十二)查詢和排序 1 查詢

2021-10-14 03:55:39 字數 4564 閱讀 3804

在 pig latin:乙個模組化開發的案例研究 小節的piglatin.c中,函式findfirstvowel的功能,是在乙個字串中查詢第乙個母音字母。

函式實現為:

static

intfindfirstvowel

(string word)

return-1

;}

該實現採用簡單直接的演算法來解決查詢問題,即:

從字串的第乙個字母開始,該函式依次檢查每乙個字母。

可以利用以上方法在乙個陣列中查詢某個資料項。

例如,函式findintegerinarray在乙個有效長度為n的整數陣列中查詢整數key:

static

intfindintegerinarray

(int key,

int array,

int n)

return-1

;}

使用findintegerinarray函式寫乙個程式findcoin.c來顯示美國的硬幣名稱和它對應的值。

其中,findintegerinarray函式返回陣列coinvalues中相應硬幣值對應的下標。

如果硬幣是美國鑄造的五種標準硬幣之一,返回的下標再用來在coinnames陣列中選擇相應的元素。即,得到硬幣的名稱。

具體實現如下:

#include

#include

#include

#include

"strlib.h"

/* function prototype */

static

intfindintegerinarray

(int key,

int array,

int n)

;static

int coinvalues=

;static string coinnames=

;/* main program */

main()

else

}/* function */

static

intfindintegerinarray

(int key,

int array,

int n)

return-1

;}

介紹乙個更複雜的查詢的應用。

假設要在程式中表示一張表(如下所示),給出各城市之間的距離(用英里表示):

宣告乙個全域性變數mileagetable,並用上表資料進行靜態初始化:

#define ncities 12

static

int mileage table[ncities]

[ncities]=,

,,,,

,,,,

,,,}

;

對應的城市名稱可以被儲存在乙個一維陣列citytable中,該陣列的宣告和初始化過程如下:

static string citytable[ncities]

=;

如何寫乙個程式讀入兩個城市的名字,顯示它們之間的距離,執行結果如下所示:

步驟如下:

(1) 以字串的形式讀入兩個城市的名字。

(2) 在陣列citytable中找到該城市名字所對應的下標位置。

(3) 用下標值在陣列mileagetable中找到對應的值,這個值就是兩城市之間的距離。

假設能夠實現乙個在字串陣列中查詢的函式findstringinarray,那麼,程式的其餘部分可以寫成:

main()

static

intgetcity

(string prompt)

return idx;

}

如果遵循實現findintegerinarray的邏輯,只需要改變引數型別,在迴圈中使用stringequal比較字串的值。相應的**如下:

static

intfindstringinarray

(string key, string array,

int n)

return-1

;}

函式findstringinarray(和前文的findintegerinarray)中使用的演算法均為線性查詢。

現實中,是否會從表頭開始,按順序找下去呢?

很可能不會。因為表中所列的城市名是按照字母順序排列的。

san francisco一定接近表的尾部,而boston一定接近表的頭部。

這種差異使得能很快找到這個值,而不需要檢查整張表的大部分城市名。

為了利用陣列citytable已經按照字母順序排列這個條件,需要採用乙個新的演算法。

假定所要查詢的是下圖所示陣列中的san francisco:

如果不再採用從陣列第乙個元素開始的線性搜尋方法,而從陣列的接近中間的位置取乙個值,中間元素的下標值可以通過計算下標範圍的兩個端點的均值得到,即:

0 +11

2\frac

20+11​

當使用整數進行運算時,該表示式的值為5。

儲存在cityarray[5]中的城市名是houston。由於san francisco所在位置一定在houston的後面,因此可以立即排除下標值從0~5的城市名。

下面的查詢中,可以採用相同的方法:

由此,整個搜尋過程只需要三步。

為了實現這種演算法,需要記錄兩個下標值,即,表示要進行搜尋的範圍的兩個端點的下標值。

在函式中,這兩個下標值分別儲存於變數lhrh中,表示左邊界(小的下標值)和右邊界(大的下標值)。

使用二分查詢的函式findstringinsortedarray的**如下:

static

intfindstringinsortedarray

(string key, string array,

int n)

if(val <0)

else

}return-1

;}

對於查詢演算法來說,乙個能對演算法效能進行很好評估的比較方便的方法,就是計算呼叫stringequalstringcompare的次數,每次呼叫都是比較鍵值和陣列中的某些元素。

假設在乙個長度為n

nn的陣列中用線性查詢演算法進行搜尋,在最壞的情況下,findstringinarray函式將呼叫n

nn次stringequal函式,即,對陣列中的每乙個元素都要呼叫一次。

在函式findstringinsortedarray實現中所用的二分查詢演算法,每經過一次呼叫,可能的元素數都減半,最終搜尋區間將變為1。

達到這一點所需的步數等於將n

nn依次除以2並最終得到1所需要的次數,該過程可用如下公式表示:

將所有的2相乘可得以下方程:

n =2

kn = 2^k

n=2k

取對數可得k值:

k =l

og2n

k = log_2n

k=log2

​n因此,使用線性查詢演算法查詢由n

nn個元素組成的陣列需要n

nn次的比較,而使用二分查詢演算法只需要log

2nlog_2n

log2​n

次比較就可以了。

二分查詢演算法唯一的問題是,陣列必須是嚴格地按照某個順序排列的。

如果不是,則必須採用線性查詢演算法。或者自己先把該陣列按要求進行排序。

參考《c語言的科學和藝術》 —— 第12章 查詢和排序

模糊查詢和排序查詢

1.表示任意一位字元 2.表示任意位數的任意字元 3.要實現模糊查詢需要使用到關鍵字 like 基本語法 3 select 1 from 資料 2 where 模糊查詢的字段 like 模糊查詢的關鍵字 注意 模糊查詢要在where字句中使用。查詢姓名是以a開頭的雇員資訊select from em...

查詢和排序

二分查詢演算法 def search list,m low 0 high len list 1 while low high mid low high 2 if list mid m high mid 1 elif list mid m low mid 1 else return mid retur...

排序和查詢

1 氣泡排序 雞尾酒排序 選擇排序 插入排序 快速排序 include 氣泡排序 voidmaopao int a,int n int i,j for i 0 i n 1 i for j 0 j n 1 i j if a j a j 1 swap a,j,j 1 交換兩個數 void swap in...