搜尋資料結構 Search Structures.

Slides:



Advertisements
Similar presentations
第 8 章 数组 计算机科学学院 李淮 Tel QQ
Advertisements

河內塔(Hanoi)問題.
C语言程序设计 主讲教师 :张群燕 电话:
Introduction 基本概念 授課老師:蕭志明
软件工程 周志钊
資料結構與演算法 課程教學投影片.
第 九 章 搜尋(Search) 課程名稱:資料結構 授課老師:_____________.
计算机三级考试C语言上机试题专题.
“八皇后”问题 崔萌萌 吕金华.
主讲:计算机工程学院 李兰 答疑地点:主教学楼B区213
第八章 查找.
第8章 查找 数据结构(C++描述).
第8章 字串與陣列 8-1 字串處理 8-2 一維陣列的處理 8-3 建立多維陣列 8-4 不規則陣列與參數傳遞 8-5 陣列排序與搜尋.
Chapter 7 Search.
C语言程序设计 第十二章 位运算.
C语言程序设计 课程 第5章 数组 主讲:李祥 博士、副教授 单位:软件学院软件工程系.
高级语言程序设计 主讲人:陈玉华.
循环结构又称为重复结构:用来处理需要重复处理的问题,它是程序中一种很重要的结构。
佇列 (Queue).
Course 4 搜尋 Search.
排序 Sorting.
快速排序法 (Quick Sort).
If … else 選擇結構 P27.
第 7 章 陣列 (Array).
第 1 章 演算法分析.
Introduction to the C Programming Language
Introduction to the C Programming Language
第一章 C語言概論 本章投影片僅供本書上課教師使用,非經同意請勿拷貝或轉載.
程式撰寫流程.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
计算机网络讲义 第5章 批量数据处理—数组 一维数组 排序和查找 二维数组 字符串.
第九章 查找 2018/12/9.
Chap 3 分支结构 3.1 简单的猜数游戏 3.2 四则运算 3.3 查询自动售货机中商品的价格.
C语言 程序设计基础与试验 刘新国、2012年秋.
数据结构 -Maple Related- 牟克典 数学科学学院信息科学系 2012秋季 1/16/2019.
数据结构 第9章 查找 什么是查找?? 静态查找 动态查找 哈希表 数据结构.
第九章 查找 2019/2/16.
計數式重複敘述 for 迴圈 P
数据结构 第八章 查找.
第十章 指针.
第七章 函数及变量存贮类型 7.1 函数基础与C程序结构 7.2 函数的定义和声明 7.3 函数的调用 7.4 函数的嵌套与递归
網路遊戲版 幸福農場168號.
鄧姚文 資料結構 第一章:基本概念 鄧姚文
C语言概述 第一章.
資料結構與C++程式設計進階 排序與搜尋 講師:林業峻 CSIE, NTU 6/ 14, 2010.
程式結構&語法.
9.1 基本概念 9.2 线性表的查找 9.3 树表的查找 9.4 哈希表的查找 9.5 各种查找方法的比较
第一章 程序设计和C语言 主讲人:高晓娟 计算机学院.
C程序设计.
Main() { Dfas Asdfasf fasdfa } #include <stdio.h> void main( ) {
第2章 算法与C语言程序 程序 (1)数据的描述:数据的类型和组织形式(数据结构) (2)操作的描述:操作步骤(算法) 沃思指出:
Introduction to the C Programming Language
Instructor:Po-Yu Kuo 教師:郭柏佑
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
Chap 5 函数 5.1 计算圆柱体积 5.2 数字金字塔 5.3 复数运算.
程式的時間與空間 Time and Space in Programming
輸出與輸入(I/O).
演算法時間複雜度 (The Complexity of Algorithms)
第一章 C语言概述 教师:周芸.
資料結構與C++程式設計進階 遞迴(Recursion) 講師:林業峻 CSIE, NTU 6/ 17, 2010.
第二章 类型、对象、运算符和表达式.
Introduction to the C Programming Language
累堆排序法 (Heap Sort).
第三章 基本的輸出與輸入函數 (Basic Output & Input Function)
第五章 逻辑运算和判断选取控制 §5.1 关系运算符和关系表达式
程式設計--linear search 通訊一甲 B 楊穎穆.
第1章 数据结构基础概论 本章主要介绍以下内容 数据结构研究的主要内容 数据结构中涉及的基本概念 算法的概念、描述方法以及评价标准.
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
函式庫補充資料 1.
隨機函數.
Presentation transcript:

搜尋資料結構 Search Structures

學習目標 在學習本章之後,讀者們要能夠瞭解: 搜尋的定義。 搜尋的種類及不同搜尋的資料結構及演算法。 電腦程式如何處理資料的搜尋。

搜尋 主要目的是從一組資料中尋找符合某種條件的資料,若是以資料的值來搜尋,可以把這個值當作搜尋鍵 (Search key),根據搜尋鍵找到的是所有和搜尋鍵等值的資料。 電腦搜尋資料的優點是快速 當資料量很龐大時,如何快速搜尋到資料是本章所要探討的 一般電腦檔案是記錄的集合,每一筆記錄包含許多欄位,其中必須至少有一個欄位可當作關鍵值(key),從資料檔案中找出滿足某些關鍵值的記錄之動作稱之為搜尋(search)

搜尋的分類 在最短時間內有效的找到所需資料,是一個相當重要的課題 影響插搜尋時間長短的主要因素包括有演算法、資料儲存的方式及結構

內部搜尋與外部搜尋 內部搜尋: 外部搜尋: 欲找尋的資料或檔案較小,可以直接全部載入記憶體中來進行搜尋的動作。 若要找尋的資料數目很大,無法一次將全部內容置於主記憶體內,而需使用到外部的輔助記憶體來分次處理。

靜態搜尋及動態搜尋 靜態搜尋(Static Search) : 動態搜尋(Dynamic Search) : 在搜尋過程中,資料不會有增加、刪除或更新等行為。例如符號表的搜尋。 動態搜尋(Dynamic Search) : 在搜尋過程中,資料會經常有增加、刪除或更新等行為。

循序搜尋法 Sequential search

定義 循序搜尋 (Sequential search),又稱為線性搜尋(Linear Searching),是最單純亦是最基本的搜尋方式 不需事先將被搜尋的檔案記錄按其鍵值排序,只需依照資料儲存的順序,逐一比較資料值是否與指定的值相等,若找到則傳回陣列的索引值,否則傳回0。

演算法 =>虛擬碼 //n指a[ ]中的元素個數,key為欲比對的資料// procedure seqsch(int a[ ], int n, int key) { index i ; for (a [ ]的第一個元素至最後一個元素) if(key = = a [i]) 顯示找到的訊息並跳出迴圈; } if (到最後的元素仍找不到) 顯示找不到的訊息;

=>C語言程式碼 int seqsch(int a[ ], int n, int key) { int i = 0; a[n] = key; while (a[i] != key) i + +; if (i < n) printf(“%d 在陣列中的第 %d 筆.\n”,key,i+1) ; return(i); else printf(“找不到資料!!\n”) ; return(-1); }

=>時間複雜度分析 最差狀況指的是必須搜尋整個陣列,即資料並未出現在陣列中,在此情況下演算法必須做n次比較。

程式實作 #include <stdio.h> void main ( ) { int data [10] = {75, 33, 98, 44, 56, 24, 65, 48, 83, 12} int i, input ; printf ( “\n<< Squential search >>\n”) ; printf ( “\nData: “ ) ; for ( i= 0; i < 10; i + +) { printf ( “%d “, data [i] ); puts(“ “); printf ( “\nPlease enter a number from data: “ ) ; scanf ( “%d”, &input); printf ( “\nSearch…..\n” ) ;

for ( i = 0; i < 10; i ++) { printf ( “nData when searching %2d time(s) is %d !”, i+1, data[i]); if ( input = = data [i] ) break ; } if ( i = = 10 ) printf ( “\n\nSorry, %d not found ! “, input ) ; else printf ( “\n\nSorry, %d is the %dth record in data! “, input, i+1 ) ;

二分搜尋法 Binary Search

定義 假如資料本身是經過排序的,在搜尋時可以利用二分的方法,每次都把陣列分成兩半,然後從其中的一半繼續搜尋,這種方法叫做「二分搜尋」(Binary search)

二分搜尋的演算法

演算法則 檔案中的資料須按鍵值排序,並找出檔案中間位罝的鍵值Km用來作比較,其中m = (1+u)/2,1及u表示資料的開始及結束位址。 搜尋方式分下面三種情形進行: Key < Km:則表示欲尋找的資料在檔案的前半部。 Key = Km:則表示搜尋成功,傳回搜尋到的位置。 Key > Km:則表示欲尋找的資料在檔案的後半部。 重新調整1及u,並重複上述步驟,直到搜尋成功或資料已全部搜尋完畢為止。

演算法 =>虛擬程式碼 int binsch(int a[ ], int low, int high, int key) { int mid; if (low <= high mid = (low+high)/2; if (a[mid] = = key) return(mid); else if (a [mid] > key) return(binsch(a,low,mid – 1,key)); else return return(binsch(a,low,mid + 1,key)); } else return(-1);

=>C語言程式碼 int binsch(int a[ ], int low, int high, int key) { int mid; if (low <= high mid = (low+high)/2; if (a[mid] = = key) return(mid); else if (a [mid] > key) return(binsch(a,low,mid – 1,key)); else return return(binsch(a,low,mid + 1,key)); } else return(-1);

=>時間複雜度分析 【分析】 由於二分搜尋每一次搜尋都要比上一次少一半的範圍,所以要找出資料的位置,最多只需要比較[log2n] +1或[log2(n+1)]次。

程式實作 #include <stdio.h> void main ( ) { int data [10] = {12, 24, 29, 38, 44, 57, 64, 75 ,82, 98} int i, l = 1, u = 10, m, cnt = 0, input, ok = 0 ; printf ( “\n<< Binary search >>\n”) ; printf ( “\nSorted Data: “ ) ;

for ( i= 0; i < 10; i + +) printf ( “%d “, data [i] ); puts(“ “); printf ( “\nPlease enter a number from data: “ ) ; scanf ( “%d”, &input); printf ( “\nSearch…..\n” ) ; m = (1 +u)/2 while ( l <= n && ok = = 0 ) { printf ( “nData when searching %2d time(s) is %d !”, ++cnt, data[m]); if (data [i] > input ) u = m – 1 print ( “ --->Choice number is smaller than %d, data[m] ) ; } else

if ( data [m] < input ) { l = m +1; printf ( “--->Choice number is bigger than %d”, data [m] ); } else printf ( “\n\nfound, %d is the %dth record in data ! “, input, m) ; ok = 1; m = (1+u)/2 if ( ok = = 0) printf ( “\n\nSorry, %d not found ! “, input ) ;

內插式搜尋法

定義 內插式搜尋法是二分搜尋法的改良,它能更準確地預測資料位置所在,若假設所有資料是平均分佈在整個陣列之中,也就是每一筆資料值的差距是很接近的。

資料key位置的合理假設為: 或 其中key是要尋找之鍵值 Max(high)和Min(low)分別是剩餘待尋找之記錄中值最小和最大者。 Middle = Min + ( target - List(Min) ) * ( Max - Min ) / ( List(Max) - List(Min) 或 Middle = low + ( key – a [low] )* ( high - low ) / ( a[high] – a[low] ) 其中key是要尋找之鍵值 Max(high)和Min(low)分別是剩餘待尋找之記錄中值最小和最大者。

插補搜尋之步驟 先將記錄按鍵值不遞減之順序加以排序並編號,編號為1,2,3,…,N。 令a = 1,b = N。 令m = Min +。 若key < keym,且List(Max) ≠ m - 1,則令List(Max) = m - 1。 若key = keym,則成功。 若key > keym,且List(Min) ≠ m + 1,則令List(Min) = m + 1。

演算法 =>虛擬程式碼 int intpsch(int a[ ], int n, int key) { int mid, high, low ; high = n – 1 ; low = 0 ; while (low <= high)

{ mid = low + (high - low)*(key –a [low] ) / (a [high ] – a[low]); if (a[mid] = = key) return(mid); else if (a [mid] > key) high = mid –1 ; else low = mid +1 ; } return(-1);

=>C語言程式碼 int intpsch(int a[ ], int n, int key) { int mid, high, low ; high = n – 1 ; low = 0 ; while (low <= high) mid = low + (high - low)*(key –a [low] ) / (a [high ] – a[low]);

=>時間複雜度分析 if (a[mid] = = key) return(mid); else if (a [mid] > key) high = mid –1 ; else low = mid +1 ; } return(-1); =>時間複雜度分析 【分析】 一般而言,內插式搜尋法優於循序法,但與其他方法的優劣勝負則完全決定於鍵值分佈平均與否,通常N > 500且鍵值分佈均勻時會優於二元搜尋法。

程式實作 #include <stdio.h> void main ( ) { int data [10] = {12, 24, 29, 38, 44, 57, 64, 75 ,82, 98} int i, l = 1, n = 10, m, cnt = 0, input, ok = 0 ; printf ( “\n<< Interpolation search >>\n”) ; printf ( “\nSorted Data: “ ) ;

for ( i= 0; i < 10; i + +) printf ( “%d “, data [i] ); puts(“ “); printf ( “\nPlease enter a number from data: “ ) ; scanf ( “%d”, &input); printf ( “\nSearch…..\n” ) ; m = (1 +u)/2

while ( (n-l) > 1 && ok = = 0 ) { m = l + ( input – data [l] * (n – l -1) / ( data [n] – data [l] + 1; if ( m > n | | m < l ) break ; printf ( “nData when searching %2d time(s) is %d !”, ++cnt, data[m]);

if ( data [m] > input ) { n = m ; printf ( “ --->Choice number is smaller than %d, data[m] ) ; } else if ( data [m] < input ) l = m ; printf ( “--->Choice number is bigger than %d”, data [m] );

else { printf ( “\n\nfound, %d is the %dth record in data ! “, input, m) ; ok = 1; } if ( ok = = 0) printf ( “\n\nSorry, %d not found ! “, input ) ;