数据结构/PTA-二分查找-线性探测法的查找函数-分离链接法的删除操作函数/图/函数题
二分查找算法
函数接口定义:
Position BinarySearch( List L, ElementType X );
其中List
结构定义如下:
typedef int Position; typedef struct LNode *List; struct LNode { ElementType Data[MAXSIZE]; Position Last; /* 保存线性表中最后一个元素的位置 */ };
L
是用户传入的一个线性表,其中ElementType
元素可以通过>、==、<进行比较,并且题目保证传入的数据是递增有序的。函数BinarySearch
要查找X
在Data
中的位置,即数组下标(注意:元素从下标1开始存储)。找到则返回下标,否则返回一个特殊的失败标记NotFound
。
裁判测试程序样例:
#include <stdio.h> #include <stdlib.h> #define MAXSIZE 10 #define NotFound 0 typedef int ElementType; typedef int Position; typedef struct LNode *List; struct LNode { ElementType Data[MAXSIZE]; Position Last; /* 保存线性表中最后一个元素的位置 */ }; List ReadInput(); /* 裁判实现,细节不表。元素从下标1开始存储 */ Position BinarySearch( List L, ElementType X ); int main() { List L; ElementType X; Position P; L = ReadInput(); scanf("%d", &X); P = BinarySearch( L, X ); printf("%d\n", P); return 0; } /* 你的代码将被嵌在这里 */
输入样例1:
5 12 31 55 89 101 31
输出样例1:
2
输入样例2:
3
26 78 233
31
输出样例2:
分析:很简单的一道题,先是用正常的二分查找找了一遍,后来发现直接顺序查找也可以通过(老懒狗了
Position BinarySearch( List L, ElementType X ) { int low=1; int high=L->Last; int flag=-1; int mid; while(low<=high) { mid=(mid+high)/2; if(X==L->Data[mid]) { flag=mid; break; } else if(X<L->Data[mid]) high=mid-1; else low=mid; } if(flag>0) return flag; else return NotFound; }
Position BinarySearch( List L, ElementType X ) { int i=1; int flag=-1; for(i=1;i<=L->Last;i++) { if(L->Data[i]==X) { flag=i; break; } } if(flag>0) return flag; else return NotFound; }
线性探测法的查找函数
函数接口定义:
Position Find( HashTable H, ElementType Key );
其中HashTable
是开放地址散列表,定义如下:
#define MAXTABLESIZE 100000 /* 允许开辟的最大散列表长度 */ typedef int ElementType; /* 关键词类型用整型 */ typedef int Index; /* 散列地址类型 */ typedef Index Position; /* 数据所在位置与散列地址是同一类型 */ /* 散列单元状态类型,分别对应:有合法元素、空单元、有已删除元素 */ typedef enum { Legitimate, Empty, Deleted } EntryType; typedef struct HashEntry Cell; /* 散列表单元类型 */ struct HashEntry{ ElementType Data; /* 存放元素 */ EntryType Info; /* 单元状态 */ }; typedef struct TblNode *HashTable; /* 散列表类型 */ struct TblNode { /* 散列表结点定义 */ int TableSize; /* 表的最大长度 */ Cell *Cells; /* 存放散列单元数据的数组 */ };
函数Find
应根据裁判定义的散列函数Hash( Key, H->TableSize )
从散列表H
中查到Key
的位置并返回。如果Key
不存在,则返回线性探测法找到的第一个空单元的位置;若没有空单元,则返回ERROR
。
裁判测试程序样例:
#include <stdio.h> #define MAXTABLESIZE 100000 /* 允许开辟的最大散列表长度 */ typedef int ElementType; /* 关键词类型用整型 */ typedef int Index; /* 散列地址类型 */ typedef Index Position; /* 数据所在位置与散列地址是同一类型 */ /* 散列单元状态类型,分别对应:有合法元素、空单元、有已删除元素 */ typedef enum { Legitimate, Empty, Deleted } EntryType; typedef struct HashEntry Cell; /* 散列表单元类型 */ struct HashEntry{ ElementType Data; /* 存放元素 */ EntryType Info; /* 单元状态 */ }; typedef struct TblNode *HashTable; /* 散列表类型 */ struct TblNode { /* 散列表结点定义 */ int TableSize; /* 表的最大长度 */ Cell *Cells; /* 存放散列单元数据的数组 */ }; HashTable BuildTable(); /* 裁判实现,细节不表 */ Position Hash( ElementType Key, int TableSize ) { return (Key % TableSize); } #define ERROR -1 Position Find( HashTable H, ElementType Key ); int main() { HashTable H; ElementType Key; Position P; H = BuildTable(); scanf("%d", &Key); P = Find(H, Key); if (P==ERROR) printf("ERROR: %d is not found and the table is full.\n", Key); else if (H->Cells[P].Info == Legitimate) printf("%d is at position %d.\n", Key, P); else printf("%d is not found. Position %d is returned.\n", Key, P); return 0; } /* 你的代码将被嵌在这里 */
输入样例1:(注:-1表示该位置为空。下同。)
11
11 88 21 -1 -1 5 16 7 6 38 10
38
输出样例1:
38 is at position 9.
输入样例2:
11
11 88 21 -1 -1 5 16 7 6 38 10
41
输出样例2:
41 is not found. Position 3 is returned.
输入样例3:
11
11 88 21 3 14 5 16 7 6 38 10
41
输出样例3:
ERROR: 41 is not found and the table is full.
分析:注意题干中这句话即可:根据裁判定义的散列函数Hash( Key, H->TableSize )
从散列表H
中查到Key
的位置并返回
Position Find( HashTable H, ElementType Key ) { int flag=0; Position p,q; p=Hash(Key,H->TableSize); q=Hash(Key,H->TableSize); while(H->Cells[p].Data!=Key&&H->Cells[p].Info!=Empty) { flag++; if(flag==MAXTABLESIZE) { return ERROR; } p=(q+flag)%H->TableSize; } return p; }