数据结构--python 第九章 查找

看了这么久的数据结构,今天终于来到了最后一个章节的总结,虽然前面有两章(树形结构和图形结构)还没有写总结,因为没怎么理解,需要再看一遍之后再写总结。好了,言归正传,下面介绍数据结构中的最后一章的内容:查找

9.1 常见的查找方法:

内部查找与外部查找

静态查找和动态查找

顺序查找、二分法查找、插值查找法、斐波那契查找法、哈希查找法

9.2 哈希查找法

9.3 常见的哈希函数

除留余数法、平方取中法、折叠法、数字分析法、

9.4 碰撞与溢出问题的解决

线性探测法、平方探测法、再哈希法、链表法、

 

在数据处理过程中,能否在最短时间内查找到所需要的数据是一个相当值得信息从业人员关心的问题。所谓查找(Search)指的是从数据文件中找出满足某些条件的记录。用以查找的条件称为‘键值’(key),就如同排序所用到的键值一样。通常查找时间长短的主要因素包括:算法的选择、数据存储的方式和结构

9.1 常见的查找方法:

根据数据量的大小,可将查找法分为:内部查找和外部查找

内部查找:数据量较小的文件可以一次性全部加载到内存中进行查找

外部查找:数据量大的文件无法一次性加载到内存中处理,需要使用辅助存储器(硬盘)来分次处理

根据查找的技巧可将查找法分为:静态查找和动态查找

静态查找:指的是在查找过程中,查找的表格或文件的内容不会被改动。例如符号表的查找就是一种静态查找

动态查找:指的是在查找过程中,查找的表格或文件的内容可能会被改动。例如在树形结构中所谈的B-Tree查找就属于一种动态查找。

9.1.1 顺序查找法

顺序查找法又称为线性查找法,是一种简单的查找法。它的方法是将数据一项一项地按照顺序逐个查找,所以无论数据的顺序如何,都得从头到尾遍历一次。

优点:文件在查找前不需要进行任何处理与排序

缺点:查找速度较慢

如果数据没有重复,找到数据就可以终止查找,在最差的情况下是没有找到数据,而需要进行n次比较。最好的情况就是一次查找就找到了数据,仅仅只需要比较1次。

#### 顺序查找法的分析:

1) 时间复杂度:如果数据没有重复,找到数据就可以中止查找,在最差情况下是没有找到数据,而需要进行n次比较,时间复杂度为o(n)。

2)在平均情况下,假设数据出现的概率相等,则需要进行(n+1)/2次比较

3)当数据量很大时,不适合使用顺序查找法。但如果预估所查找的数据在文件的前端,选择这种查找法则可以减少查找的时间。

例子:设计一个python程序,以随机数生成1~150之间的80个整数,然后实现顺序查找法的过程。

# CH09-01.PY
import random

val=0
data=[0]*80
for i in range(80):
    data[i]=random.randint(1,150)
while val!=-1:
    find=0
    val=int(input('请输入查找键值(1-150),输入-1离开:'))
    for i in range(80):
        if data[i]==val:
            print('在第 %3d个位置找到键值 [%3d]' %(i+1,data[i]))
            find+=1
    if find==0 and val !=-1 :
        print('######没有找到 [%3d]######' %val)
print('数据内容为:')
for i in range(10):
    for j in range(8):
        print('%2d[%3d]  ' %(i*8+j+1,data[i*8+j]),end='')
    print('')

# 结果
请输入查找键值(1-150),输入-1离开:76
在第  23个位置找到键值 [ 76]
请输入查找键值(1-150),输入-1离开:78
######没有找到 [ 78]######
请输入查找键值(1-150),输入-1离开:79
######没有找到 [ 79]######
请输入查找键值(1-150),输入-1离开:-1
数据内容为:
 1[140]   2[119]   3[ 30]   4[ 46]   5[  9]   6[136]   7[ 42]   8[128]  
 9[ 54]  10[ 56]  11[ 39]  12[105]  13[ 62]  14[ 49]  15[118]  16[ 12]  
17[ 85]  18[ 71]  19[ 26]  20[125]  21[133]  22[ 41]  23[ 76]  24[108]  
25[ 25]  26[ 20]  27[ 45]  28[136]  29[108]  30[107]  31[ 81]  32[ 73]  
33[139]  34[ 54]  35[ 35]  36[125]  37[ 71]  38[136]  39[106]  40[133]  
41[ 63]  42[ 40]  43[ 13]  44[ 25]  45[ 36]  46[ 21]  47[ 27]  48[ 45]  
49[ 35]  50[102]  51[  7]  52[130]  53[ 35]  54[ 87]  55[ 60]  56[116]  
57[ 22]  58[ 89]  59[117]  60[140]  61[ 87]  62[  6]  63[146]  64[109]  
65[129]  66[ 56]  67[ 89]  68[ 35]  69[ 63]  70[150]  71[ 42]  72[147]  
73[ 21]  74[ 99]  75[ 91]  76[ 74]  77[ 74]  78[130]  79[113]  80[ 68] 

9.1.2 二分法查找法(已排好顺序的数据+内部查找+静态查找)

如果要查找的数据已经事先排好顺序了,就可以使用二分法查找法来进行查找。二分法查找是将数据分割成两等分,再比较键值与中间值的大小:如果键值大于中间值,就可以确定查找的数据在后半部分,如果键值小于中间值,则可以确定要查找的数据在前半部分。

### 二分法查找法的分析

1)时间复杂度:因为每次查找都会比上次少一半的范围,最多只需要比较[log_{2}n]+1 OR [log_{2}(n+1)],时间复杂度是o(logn)

2)二分法查找必须事先经过排序,且要求所有备查数据都必须加载到内存中方能进行(内部查找)

3)此方法适用于不需要增删的静态数据

例子:设计一个python程序,以随机数生成1~150之间的80个整数,然后实现二分法查找法的过程与步骤

# CH09-02.py
import random

def bin_search(data,val):
    low=0
    high=49
    while low <= high and val !=-1:
        mid=int((low+high)/2)
        if val<data[mid]:
            print('%d 介于位置 %d[%3d] 和中间值 %d[%3d] 之间,找左半边' \
                   %(val,low+1,data[low],mid+1,data[mid]))
            high=mid-1
        elif val>data[mid]:
            print('%d 介于中间值位置 %d[%3d] 和 %d[%3d] 之间,找右半边' \
                  %(val,mid+1,data[mid],high+1,data[high]))
            low=mid+1
        else:
            return mid
    return -1

val=1
data=[0]*50
for i in range(50):
    data[i]=val
    val=val+random.randint(1,5)

while True:
    num=0
    val=int(in
1.对于二叉排序树,下面的说法( )是正确的。 A.二叉排序树是动态树表,查找不成功时插入新结点时,会引起树的重新分裂和组合 B.对二叉排序树进行层序遍历可得到有序序列 C.用逐点插入法构造二叉排序树时,若先后插入的关键字有序,二叉排序树的深度最大 D.在二叉排序树中进行查找,关键字的比较次数不超过结点数的1/2 2.在有n个结点且为完全二叉树的二叉排序树中查找一个键值,其平均比较次数的数量级为( )。 A.O(n) B.O(log2n) C.O(n*log2n) D.O(n2) 3.静态查找与动态查找的根本区别在于( )。 A. 它们的逻辑结构不一样 B. 施加在其上的操作不同 C. 所包含的数据元素类型不一样 D. 存储实现不一样 4.已知一个有序表为{12,18,24,35,47,50,62,83,90,115,134},当折半查找值为90的元素时,经过( )次比较后查找成功。 A.2 B.3 C.4 D.5 5.已知数据序列为(34,76,45,18,26,54,92,65),按照依次插入结点的方法生成一棵二叉排序树,则该树的深度为( )。 A. 4 B. 5 C. 6 D. 7 6.设散列表表长m=14,散列函数H(k)=k mod 11 。表中已有15,38,61,84四个元素,如果用线性探测法处理冲突,则元素49的存储地址是( )。 A. 8 B. 3 C. 5 D. 9 7. 平衡二叉树的查找效率呈( )数量级。 A. 常数阶 B. 线性阶 C. 对数阶 D. 平方阶 8. 设输入序列为{20,11,12,…},构造一棵平衡二叉树,当插入值为12的结点时发生了不平衡,则应该进行的平衡旋转是( )。 A. LL B. LR C. RL D. RR 二、填空题(每空3分,共24分)。 1.在有序表A[1..18]中,采用二分查找算法查找元素值等于A[7]的元素,所比较过的元素的下标依次为 。 2.利用逐点插入法建立序列(61,75,44,99,77,30,36,45)对应的二叉排序树以后,查找元素36要进行 次元素间的比较,查找序列为 。 3. 用顺序查找法在长度为n的线性表中进行查找,在等概率情况下,查找成功的平均比较次数是 。 4. 二分查找算法描述如下: intSearch_Bin(SST ST, KT key) { low=1 ; high=ST. length; while(low<=high) { mid=(low+high)/2; if(key==ST.elem[mid].key) return mid; else if(key<ST.elem[mid].key) ; else ; } return 0; } 5.链式二叉树的定义如下: typedef struct Btn{ TElemType data; ; }BTN ,*BT; 6.在有n个叶子结点的哈夫曼树中,总结点数是 。 三、综合题(共52分)。 1. (共12分)假定关键字输入序列为19,21,47,32,8,23,41,45,40,画出建立二叉平衡树的过程。 2. (共15分)有关键字{13,28,31,15,49,36,22,50,35,18,48,20},Hash 函数为H=key mod 13,冲突解决策略为链地址法,请构造Hash表(12分),并计算平均查找长度(3分)。 ASL= 3. (共10分)设关键字码序列{20,35,40,15,30,25},给出平衡二叉树的构造过程。 4. (共15分)设哈希表长为m=13,散列函数为H(k)=k mod 11,关键字序列为5,7,16,12,11,21,31,51,17,81;试求:散列后的表中关键字分布(假定解决冲突的方法为线性探测再散列法);求平均查找长度ASL;计算该表的装填因子。 (1)按要求求哈希表(10分): 0 1 2 3 4 5 6 7 8 9 10 11 12 (2)计算ASL(3分): ASL= (3)计算装填因子(2分):装填因子=
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值