实验目的:深入理解静态查找表的建立过程,以及顺序排序和折半排序算法的基本思想
实验内容:
1.建立静态查找表
2.实现顺序排序函数并完成功能测试
3.实现折半排序函数并完成功能测试
步骤1:包含必要的函数库,对结构体LNode中的常量和数据类型进行具体定义
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 //将关键字的类型实例化为整型
5 typedef int KeyType;
6 //设置静态表的最大长度
7 #define MAXSIZE 20
步骤2:定义结构体SSElement
1 /*利用结构体SSElement实现静态表中的每个元素*/
2 typedef struct{
3 KeyType key;
4 //可进一步地增加定义其他的域
5 }SSElement;
步骤3:定义结构体SSTable
1 /*利用结构体SSTable实现静态查找表*/
2
3 typedef struct{
4
5 SSElement *elem;
6
7 int length;//静态查找表的长度
8
9 int tablesize;//静态查找表的最大长度
10
11 }SSTable;
提示:结构体SSTable的定义方式与实验1中的结构体SqList类似
步骤4:定义函数InitSSTable(),用于对静态查找表进行初始化。
提示1:该函数利用malloc()函数为结构体的elem数组分配内存空间。
提示2:elem数组的0号单元用于保存哨兵元素,1至MAXSIZE号单元用于保存静态查找表中的数据元素。
1 /*函数InitSSTable()用于初始化静态表*/
2
3 int InitSSTable(SSTable *ST)
4
5 {
6
7 (*ST).elem=(SSElement *)malloc((MAXSIZE+1)*sizeof(SSElement));
8
9 if (!(*ST).elem) exit(-1);
10
11 (*ST).length=0;
12
13 (*ST).tablesize=MAXSIZE;
14
15 /*创建哨兵元素,并将其保存在数组单元(*ST).elem[0]中,将该元素的关键字初值设置为0*/
16
17 SSElement se;
18
19 se.key=0;
20
21 (*ST).elem[0]=se;
22
23 return 1;
24
25 }
步骤5:定义函数SSTableInsert(),用于向静态查找表中添加数据元素
提示:与实验1中的函数ListInsert_Sq()类似,最大的区别是第i个元素保存在elem数组的i号单元而非i-1单元。
1 /*函数SSTableInsert()用于向静态表中添加元素*/
2 int SSTableInsert(SSTable *ST,int i,
3 SSElement se)
4 {
5 SSElement *p,*q;
6 if (i<1||i>(*ST).tablesize)
7 return 0;
8 if((*ST).length>=(*ST).tablesize)
9 {
10 printf("静态查找表已满!");
11 return 0;
12 }
13 else
14 {
15 q=&((*ST).elem[i]);
16 for(p=&((*ST).elem[(*ST).length]);p>=q;--p)
17 *(p+1)=*p;
18 *q=se;
19 ++(*ST).length;
20 return 1;
21 }
22 }
步骤6:定义函数GetSSElem(),该函数的作用是对前两个函数InitSSTable()、SSTableInsert()的功能进行测试。
提示:与实验1中的函数GetElem_Sq()类似,最大的区别是第i个元素保存在elem数组的i号单元而非i-1单元。
1 /*函数GetSSElem()用于返回静态查找表指定位置上的元素*/
2 int GetSSElem(SSTable ST,int i,SSElement *se)
3 {
4 if(i<1||i>ST.length)
5 return -1;
6 *se=ST.elem[i];
7 return 1;
8 }
步骤7:在主函数main()中对前两个函数InitSSTable()、SSTableInsert()的功能进行测试。
测试代码:
1 int flag;//该标志表示函数执行是否成功
2
3 int i;//控制for循环的变量
4
5 SSElement se;
6
7 SSTable A;
8
9 InitSSTable(&A);//初始化静态查找表
10
11 /*向静态查找表中插入元素10,20,30,40,56,60,70,80*/
12 se.key=10;
13 SSTableInsert(&A,1,se);
14
15 …
16
17 se.key=80;
18 SSTableInsert(&A,8,se);
19
20 //测试插入的元素是否正确
21 printf("静态查找表中的元素为:\n");
22 for(i=1;i<=A.length;i++)
23 {
24 flag=GetSSElem(A,i,&se);
25 if(flag==1)
26 printf("%4d",se.key);
27 }
28 printf("\n");
步骤8:定义函数SSTableSearch_Seq(),实现顺序查找功能
提示:可以直接对课本216页的算法9.1进行改造,但是需要在for循环执行空操作,否则会在for循环过程中不断向外层返回位置i。
1 /*函数SSTableSearch_Seq()用于实现静态查找*/
2 int SSTableSearch_Seq(SSTable ST,KeyType key);
步骤9:对函数SSTableSearch_Seq()进行测试
测试代码:
1 //在主函数中追加定义如下变量
2 int pos;//保存匹配元素在静态查找表中的位置
3 int key;//保存待查找的关键字
4 //测试顺序查找函数SSTableSearch_Seq()
5 printf("函数SSTableSearch_Seq > 输入待查找的关键字:");
6 scanf("%d",&key);
7 pos=SSTableSearch_Seq(A,key);
8 if (pos==0) printf("函数SSTableSearch_Seq > 查找失败!\n");
9 else printf("函数SSTableSearch_Seq > 匹配元素在静态查找表中的位置为:%4d\n",pos);
步骤10:定义函数SSTableSearch_Bin(),实现顺序查找功能
提示:可以直接对课本220页的算法9.2进行改造
1 /*函数SSTableSearch_Bin()用于实现折半查找*/
2 int SSTableSearch_Bin(SSTable ST,KeyType key);
步骤11:对函数SSTableSearch_Bin()进行测试
1 //测试折半查找函数SSTableSearch_Bin()
2 printf("函数SSTableSearch_Bin > 输入待查找的关键字:");
3 scanf("%d",&key);
4 pos=SSTableSearch_Bin(A,key);
5 if (pos==0) printf("函数SSTableSearch_Bin > 查找失败!");
6 else printf("函数SSTableSearch_Bin > 匹配元素在静态查找表中的位置为:%4d\n",pos);
思考题
1.如何编程实现9.1.4节的索引顺序查找。
1 /*函数SSTableSearch_Seq()用于实现静态查找*/
2 int SSTableSearch_Seq(SSTable ST,KeyType key)
3 {
4 int i;
5 ST.elem[0].key=key;
6 for(i=ST.length;ST.elem[i].key!=key;--i)
7 {}//此处需要执行空操作,否则会在for循环过程中不断向外层返回位置i
8 /*
9 也可以采用书上的方式在for语句之后加分号,即
10 for(i=ST.length;ST.elem[i].key!=key;--i);
11 */
12 return i; //查找失败时返回0
13 }
14 /*函数SSTableSearch_Bin()用于实现折半查找*/
15 int SSTableSearch_Bin(SSTable ST,KeyType key)
16 {
17 int low,high,mid;
18 low=1;
19 high=ST.length;
20 while(low<=high)
21 {
22 mid=(low+high)/2;
23 if (key==ST.elem[mid].key) return mid;
24 else if(key<ST.elem[mid].key) high=mid-1;
25 else low=mid+1;
26 }
27 return 0; //查找失败时返回0
28 }