9.1静态查找表
- 格式:doc
- 大小:100.50 KB
- 文档页数:7
数据结构——第五章查找:01静态查找表和动态查找表1.查找表可分为两类:(1)静态查找表:仅做查询和检索操作的查找表。
(2)动态查找表:在查询之后,还需要将查询结果为不在查找表中的数据元素插⼊到查找表中;或者,从查找表中删除其查询结果为在查找表中的数据元素。
2.查找的⽅法取决于查找表的结构:由于查找表中的数据元素之间不存在明显的组织规律,因此不便于查找。
为了提⾼查找效率,需要在查找表中的元素之间⼈为地附加某种确定的关系,⽤另外⼀种结构来表⽰查找表。
3.顺序查找表:以顺序表或线性链表表⽰静态查找表,假设数组0号单元留空。
算法如下:int location(SqList L, ElemType &elem){ i = 1; p = L.elem; while (i <= L.length && *(p++)!= e) { i++; } if (i <= L.length) { return i; } else { return 0; }}此算法每次循环都要判断数组下标是否越界,改进⽅法:加⼊哨兵,将⽬标值赋给数组下标为0的元素,并从后向前查找。
改进后算法如下:int Search_Seq(SSTable ST, KeyType kval) //在顺序表ST中顺序查找其关键字等于key的数据元素。
若找到,则函数值为该元素在表中的位置,否则为0。
{ ST.elem[0].key = kval; //设置哨兵 for (i = ST.length; ST.elem[i].key != kval; i--) //从后往前找,找不到则返回0 { } return 0;}4.顺序表查找的平均查找长度为:(n+1)/2。
5.上述顺序查找表的查找算法简单,但平均查找长度较⼤,不适⽤于表长较⼤的查找表。
若以有序表表⽰静态查找表,则查找过程可以基于折半进⾏。
算法如下:int Search_Bin(SSTable ST, KeyType kval){ low = 1; high = ST.length; //置区间初值 while (low <= high) { mid = (low + high) / 2; if (kval == ST.elem[mid].key) { return mid; //找到待查元素 } else if (kval < ST.elem[mid].key) { high = mid - 1; //继续在前半区间查找 } else { low = mid + 1; //继续在后半区间查找 } } return 0; //顺序表中不存在待查元素} //表长为n的折半查找的判定树的深度和含有n个结点的完全⼆叉树的深度相同6.⼏种查找表的时间复杂度:(1)从查找性能看,最好情况能达到O(logn),此时要求表有序;(2)从插⼊和删除性能看,最好情况能达到O(1),此时要求存储结构是链表。
第9章查找9.1知识点:静态查找表一、填空题1.在数据的存放无规律而言的线性表中进行检索的最佳方法是。
2.查找表是由构成的集合。
3.若对查找表只做“查询某个特定的数据元素是否在查找表中”和“查询某个特定的数据元素的各种属性”操作,则称此类查找表为。
若在查找过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已存在的某个数据元素,则称此类查找表为。
4.在n个记录的有序顺序表中进行折半查找,最大的比较次数为。
5.是顺序查找的一种改进方法,又称索引顺序查找,具体实现为将一个主表分成n个子表,要求子表之间元素是按,而子表中元素可以无序的,用每个子表最大关键字和指示块中第一个记录在表中位置建立。
6.分块查找的时间复杂度是。
7.顺序查找n个元素的顺序表,若查找成功,则比较关键字的次数最多为次;当使用监视哨时,若查找失败,则比较关键字的次数为次。
8.由于查找运算的主要运算是关键字的比较,所以通常把______________作为衡量一个查找算法效率优劣的标准。
它的计算公式为________________________________________。
二、选择题1.()在表长为n的链表中进行顺序查找,它的平均查找长度为()。
A. ASL=nB. ASL=(n+1)/2C. ASL=+1D. ASL≈log2(n+1)-12.()采用折半查找方法查找长度为n的线性表时,平均时间复杂度为()。
A.O(n2)B.O(nlogn)C.O(n)D.O(logn)3.()折半查找有序表(4,6,10,12,20,30,50,70,88,100)。
若查找表中元素58,则它将依次与表中()比较大小,查找结果是失败。
A.20,70,30,50 B.30,88,70,50 C.20,50 D.30,88,504.()有序线性表(a1,a2,a3,…,a256)是从小到大排列的,对一个给定的值k,用二分法检索表中与k相等的元素,在查找不成功的情况下,最多需要检索()次。
9.1静态查找表
关键字类型说明:
typedef float KeyType; //实型。
typedef int KeyType; //整型。
typedef char *KeyType; //字符串型。
数据元素类型定义:
typedef struct{
KeyType key; //关键字域。
... //其它域。
}ElemType;
对两个关键字的比较:
//--对数值型关键字---
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)>=(b))
//--对字符串型关键字---
#define EQ(a,b) (!strcmp((a),(b)))
#define LT(a,b) (strcmp((a),(b))<0)
#define LQ(a,b) (strcmp((a),(b))>=0)
...
9.1.1顺序表的查找
//---静态查找表的顺序存储结构-------
typedef struct
{
ElemType *elem; //数据元素存储空间基址,建表时按实际长度分配,0号单元留空。
int length; //表长度。
}SSTable;
程序:
int Search_Seq(SSTable ST,KeyType key)
//在顺序表ST中顺序查找其关键字等于key的数据元素,若找到,则函数值为
//该元素在表中的位置,否则为0。
{
ST.elem[0].key=key;
for(i=ST.length;!EQ(ST.elem[i].key,key);--i);//从后往前找。
return i; //找不到时,i为0。
}//Search_Seq
9.1.2有序表的查找。
①折半查找实例:
(05,13,19,21,37,56,64,75,80,88,92)查找21和85.
(1)找21.
low=1,high=11 ,mid=(low+high)/2=6,ST.elem[mid]=56>21;
low=1,high=mid-1=5,mid=(low+high)/2=3,ST.elem[mid]=19<21;
low=mid+1=4,high=5,mid=(low+high)/2=4,ST.elem[mid]=21=21;
(2)找85.
(05,13,19,21,37,56,64,75,80,88,92)
low=1,high=11 ,mid=(low+high)/2=6,ST.elem[mid]=56<85; low=mid+1=7 ,high=11,mid=(low+high)/2=9,ST.elem[mid]=80<85; low=mid+1=10,high=11,mid=(low+high)/2=10,ST.elem[mid]=88>85; low=10,high=mid-1=9 ,low>high;
②程序
int Search_Bin(SSTable ST,KeyType key)
{
//在有序表ST中折半查找其关键字等于key的数据元素。
若找到,则函数值为//该元素在表中的位置,否则为0。
low=1;high=ST.length; //置区间初值。
while(low<=high)
{
mid=(low+high)/2;
if EQ(key,ST.elem[mid].key) return mid; //找到待查元素。
else if LT(key,ST.elem[mid].key) high=mid-1; //继续在前半区间进行查找。
else low=mid+1; //继续在后半区间进行查找。
}// while
return 0; //顺序表中不存在待查元素。
}//Search_Bin
③折半查找判定树,及找21的过程。
④加上外部节点的判定树,及查找85的过程。
9.1.3静态树表的查找1.公式。
2.程序。
Status SecondOptimal(BiTree &T,ElemType R[],float sw[],int low,int high)
{
//由有序表R[low..high]及其累计权值表sw(其中sw[0]==0)递归构造次优查找树T。
i=low;min=abs(sw[high]-sw[low]);dw=sw[high]+sw[low-1];
for(j=low+1;j<=high;++j) //选择最小的ΔPi值。
{
if(abs(dw-sw[j]-sw[j-1])<min)
{
i=j;min=abs(dw-sw[j]-sw[j-1]);
}// if
}// for(j=low+1;j<=high;++j)
if(!(T=(BiTree)malloc(sizeof(BiTNode)))) return ERROR;
T->data=R[i]; //生成节点。
if(i==low) T->lchild=NULL; //左子树空。
else SecondOptimal(T->lchild,R,sw,low,i-1); //构造左子树。
if(i==high) T->rchild=NULL; //右子树空。
else SecondOptimal(T->rchild,R,sw,i+1,high); //构造右子树。
return OK;
}// SecondOptimal
3.实例。
例9-1:已知含9个关键字的有序表及其相应权值为:
关键字:A B C D E F G H I
权值:1 1 2 5 3 4 4 3 5
00000000000000000000000累计权值和及ΔP值
j 0 1 2 3 4 5 6 7 8 9
A B C D E F G H I
key
j
w
0 1 1 2 5 3 4 4 3 5
j
0 1 2 4 9 12 16 20 23 28
sw
j
ΔPj 27 25 22 15 7 0 8 15 23
(根) ↑i
ΔPj 11 9 6 1 9 8 1 7
(根) ↑i ↑i
ΔPj 3 1 2 0 0 0
(根) ↑i ↑i ↑i ↑i
ΔPj 0 0
(根) ↑i ↑i
00000000000000000000000
例9-2:已知含5个关键字的有序表及其相应权值为
关键字:A B C D E
权值: 1 30 2 29 3
4.程序。
//---静态查找表的顺序存储结构-------
typedef struct
{
ElemType *elem; //数据元素存储空间基址,建表时按实际长度分配,0号单元留空。
int length; //表长度。
}SSTable;
typedef BiTree SOSTree; //次优查找树采用二叉链表的存储结构
Status CreateSOSTree(SOSTree &T,SSTable ST)
{
//由有序表ST构造一棵次优查找树T。
ST的数据元素含有权域weight.
if(ST.length==0) T=NULL;
else
{
FindSW(sw,ST);//按照由有序表ST中各数据元素的weight域求累计权值表sw. SecondOptimal(T,ST.elem,sw,1,ST.length);
}
return OK;
}//CreateSOSTree
9.1.4索引顺序表的查找。
略。
--end--。