---
# System prepended metadata

title: wk14_1207_演算法_排序與搜尋

---

# 【wk14_1207】演算法_排序與搜尋
<pre>
8.3 搜尋
    1. 循序搜尋
    2. 二分搜尋
<pre/>

## 【inclass practice】

### {範例}
1. 由小排到大排序 \<bubble>
2. 追蹤泡沫排序法的過程 \<bubble_debuge>
3. 循序搜尋 : 中獎者姓名 \<sequential>
4. 二分搜尋 : 中獎者姓名 \<binary>


```python
# 1.由小排到大排序 <bubble>
def switch(i) :
    datas[i], datas[i+1] = datas[i+1], datas[i]
datas = [3, 5, 2, 89, 41, 17]

print("排序前 :", datas)

n = len(datas)

for i in range(n-1) : # i介於 0~n-1
    #print(f"i = {i}, j = {j}", end = "")
    for j in range(0, n-1-i) :
        print(f"i = {i}, j = {j} : [j] = {datas[j]}, [j+1] = {datas[j+1]}", end = "")
        if datas [j] < datas [j+1] :
            switch(j)
            print(f"交換後 : [j] = {datas[j]}, [j+1] = {datas[j+1]}", end = "\n")
        else :
            print(f"不交換 \n")
    print(f"{datas} \n")

print("排序後 :", datas)
```

    排序前 : [3, 5, 2, 89, 41, 17]
    i = 0, j = 0 : [j] = 3, [j+1] = 5交換後 : [j] = 5, [j+1] = 3
    i = 0, j = 1 : [j] = 3, [j+1] = 2不交換 
    
    i = 0, j = 2 : [j] = 2, [j+1] = 89交換後 : [j] = 89, [j+1] = 2
    i = 0, j = 3 : [j] = 2, [j+1] = 41交換後 : [j] = 41, [j+1] = 2
    i = 0, j = 4 : [j] = 2, [j+1] = 17交換後 : [j] = 17, [j+1] = 2
    [5, 3, 89, 41, 17, 2] 
    
    i = 1, j = 0 : [j] = 5, [j+1] = 3不交換 
    
    i = 1, j = 1 : [j] = 3, [j+1] = 89交換後 : [j] = 89, [j+1] = 3
    i = 1, j = 2 : [j] = 3, [j+1] = 41交換後 : [j] = 41, [j+1] = 3
    i = 1, j = 3 : [j] = 3, [j+1] = 17交換後 : [j] = 17, [j+1] = 3
    [5, 89, 41, 17, 3, 2] 
    
    i = 2, j = 0 : [j] = 5, [j+1] = 89交換後 : [j] = 89, [j+1] = 5
    i = 2, j = 1 : [j] = 5, [j+1] = 41交換後 : [j] = 41, [j+1] = 5
    i = 2, j = 2 : [j] = 5, [j+1] = 17交換後 : [j] = 17, [j+1] = 5
    [89, 41, 17, 5, 3, 2] 
    
    i = 3, j = 0 : [j] = 89, [j+1] = 41不交換 
    
    i = 3, j = 1 : [j] = 41, [j+1] = 17不交換 
    
    [89, 41, 17, 5, 3, 2] 
    
    i = 4, j = 0 : [j] = 89, [j+1] = 41不交換 
    
    [89, 41, 17, 5, 3, 2] 
    
    排序後 : [89, 41, 17, 5, 3, 2]
    


```python
# 3.循序搜尋 : 中獎者姓名 <sequential>
num = [256,731,943,389,142,645,829,945]
name = ["林小虎","王中森","邵木淼","李大同","陳子孔","鄭美麗","曾溫柔","錢來多"]
no = int(input("請輸入中獎者的編號 ："))
 
IsFound=False
for i in range(len(name)):  #逐一比對搜尋 
    if (num[i]==no):        #號碼相符 
        IsFound=True        #設旗標為 True
        break               #結束比對

if (IsFound==True):
    print("中獎者的姓名為 ：",name[i])
else:
    print("無此中獎號碼！")
print("共比對 %d次 " %(i+1))   
```

    請輸入中獎者的編號 ：829
    中獎者的姓名為 ： 曾溫柔
    共比對 7次 
    


```python
# 4.二分搜尋 : 中獎者姓名 <binary>
num=[256,731,943,389,142,645,829,945,371,418]
name=["林小虎","王中森","邵木淼","李大同","陳子孔","鄭美麗","曾溫柔","錢來多","賈天良","吳水品"] 

n=len(num)-1 # 串列長度-1
IsFound=False
min=0
max=n
c=0 #計算比對次數 

for i in range(0,n): 
    for j in range(0,n-i):         
        if (num[j]>num[j+1]): # 由小到大排序
            num[j],num[j+1]=num[j+1],num[j]     # 兩數互換
            name[j],name[j+1]=name[j+1],name[j] # 姓名互換
 
no = int(input("請輸入中獎者的編號："))

while(min<=max):
    mid=int((min+max)/2)
    c+=1  #比對次數加 1
    if (num[mid]==no):  #號碼相符 
        IsFound=True
        break

    if (num[mid]>no): #如果中間值大於輸入值 
       max=mid-1      #使用較小的一半區域繼續比對 
    else:             #如果中間值不大於輸入值 
       min=mid+1      #使用較大的一半區域繼續比對 
       
if (IsFound==True):
    print("中獎者的姓名為 ：",name[mid])
else:
    print("無此中獎號碼！")
print("共比對 ",c,"次")              
```

    請輸入中獎者的編號：829
    中獎者的姓名為 ： 曾溫柔
    共比對  2 次
    

### {綜合演練}
<pre>
實作2 :
俊民將中獎號碼建立成串列num=[67,12,9,52,91,3]，
讓妹妹輸入三個號碼，再以循序搜尋方法檢查這三個號碼種有幾個中獎，
並顯示其結果。
<pre/>

<pre>
實作3:
下列名單為本期大樂透的中獎名單names=["David","Lily","Chiou","Bear","Shantel","Chynthia"]，讓使用者輸入一個姓名，輸入的字元大小寫不分，例如輸入 david、David、DAVID 都是同一人，請以二分搜尋法檢查該名單是否中獎，並顯示查詢結果。
<pre/>


```python
names = ["David","Lily","Chiou","Bear","Shantel","Chynthia"] 
n = len(names)-1
for i in range(0,n) : 
    for j in range(0,n-i) :         
        if (names[j]>names[j+1]) : 
            names[j],names[j+1]=names[j+1],names[j] 
            
while True : 
    name = input("請輸入中獎者的名單(enter結束)：")
    if (name=="") :
        break
    
    IsFound=False
    min=0
    max=n
    while(min<=max) :
        mid=int((min+max)/2)
        if (names[mid].upper()==name.upper()) :
            IsFound = True
            break
        if (names[mid].upper()>name.upper()) :
            max=mid-1      
        else:             
            min=mid+1   

    if (IsFound==True) :
        print("恭喜您，",name,"中獎了!")
    else :
        print("可惜，",name,"未中獎!")
```

    請輸入中獎者的名單(enter結束)：lily
    恭喜您， lily 中獎了!
    請輸入中獎者的名單(enter結束)：amy
    可惜， amy 未中獎!
    請輸入中獎者的名單(enter結束)：shantel
    恭喜您， shantel 中獎了!
    請輸入中獎者的名單(enter結束)：
    

## 【afterclass practice】

1. OMP feedback
