数据结构编程笔记二十四:第九章 查找 顺序表和有序表(静态查找表)查找算法的实现
来源:互联网 发布:性格缺陷 知乎 编辑:程序博客网 时间:2024/05/16 19:20
上次我们介绍了图的关键路径算法的实现,这次介绍查找这一章的第一个程序:顺序表和有序表(静态查找表)查找算法的实现。
还是老规矩:
程序在码云上可以下载。
地址:https://git.oschina.net/601345138/DataStructureCLanguage.git
图这一章的程序做完以后,后面的程序就明显好做多了。
这次的程序没啥好说的,就是顺序表每个数据元素加了一个关键字。其他操作差不多,仅此而已。
关于顺序表的实现,可以参考:《 数据结构编程笔记三:第二章 线性表 顺序表的实现》,我就是拿这个程序改造之后变成了第九章的程序。
直接看代码吧:
//*********************引入头文件**********************************#include <stdio.h>#include <stdlib.h> //使用了malloc、free函数 //********************自定义符号常量******************************** #define OVERFLOW -2 //内存溢出错误常量#define ILLEGAL -1 //非法操作错误常量 #define OK 1 //表示操作正确的常量 #define ERROR 0 //表示操作错误的常量#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量#define EQ(a,b) ((a)==(b)) //相等 #define LT(a,b) ((a)< (b)) //小与#define LQ(a,b) ((a)<= (b)) //小与等于 //*********************自定义数据类型*******************************typedef int Status; //状态码类型为int typedef int KeyType; //关键字类型为int typedef struct{ //元素类型 //关键字域 KeyType key;}ElemType; //------------------静态查找表的顺序存储结构------------------- typedef struct{ //数据元素存储空间基址,建表时按实际长度分配,0号单元留空 ElemType *elem; //表长度,表中记录数 int length;}SSTable;//**************************顺序表的主要操作************************* //1.--------------------静态查找表的初始化操作---------------------------- /* 函数:InitSSTable_Seq 参数:SSTable &ST 静态查找表引用 返回值:状态码,操作成功返回OK 作用:初始化静态查找表,构造一个空静态查找表*/Status InitSSTable_Seq(SSTable &ST){ //申请查找表内存空间,0号单元留空。 ST.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType) + 1); //若内存分配失败,退出程序 if(!ST.elem){ printf("内存申请失败!\n"); exit(OVERFLOW); }//if //设置静态查找表ST的长度为0 ST.length = 0; //操作成功 return OK; }//InitSSTable_Seq//2.----------------------输入静态查找表元素的操作-------------------/* 函数:SSTableInput_Seq 参数:SSTable &ST 静态查找表引用 返回值:状态码,操作成功返回OK 作用:顺序表插入元素的函数*/Status SSTableInput_Seq(SSTable &ST) { //n代表元素的个数,i用作循环变量 int n, i; //直到用户输入正确为止 while(1){ //先确定元素的个数 printf("->您想输入几个元素,请输入个数,最多不可以超过100 "); scanf("%d", &n); //检查元素个数n是否合法 if(n < 1 || n > 100) { //如果输入非法数据,就提醒用户重新输入 printf("您的输入非法,请重新输入!!!\n"); }//if //若输入合法则退出循环 break; }//while //输入静态查找表数据 printf("请输入静态查找表ST的元素,中间用空格隔开,最多不可以超过100个元素\n"); for(i = 1; i <= n; i++) { //初始化每一个元素 scanf("%d", &ST.elem[i].key); }//for //静态查找表个数为元素个数n ST.length = n; //操作成功 return OK;}//SSTableInput_Seq//3.------------------判断静态查找表是否为空-------------------/* 函数:SSTableEmpty_Seq 参数:SSTable ST 静态查找表ST 返回值:状态码,若静态查找表为空表返回TRUE,否则返回FALSE 作用:判断静态查找表是否为空 */Status SSTableEmpty_Seq(SSTable ST){ //查看表长是否为0 return ST.length == 0;}//SSTableEmpty_Seq//4.----------------------静态查找表的输出操作------------------/* 函数:Print 参数:KeyType e 关键字的值e 返回值:状态码,操作成功返回OK,否则返回ERROR 作用:元素访问函数*/Status Print(KeyType e){ //采用控制台输出方式打印关键字e printf("%3d ", e); //操作成功 return OK;}//Print/* 函数:SSTableTraverse_Seq 参数:SSTable ST 静态查找表ST Status(* Visit)(KeyType) 函数指针,指向元素访问函数 返回值:状态码,操作成功返回OK,否则返回ERROR 作用:遍历静态查找表函数*/Status SSTableTraverse_Seq(SSTable ST, Status(* Visit)(KeyType)){ //访问静态查找表中每一个元素一次且仅一次 for(int i = 1; i <= ST.length; ++i) { //一旦访问失败则遍历失败 //if(!Visit(ST.elem[i].key)) <=> if(Visit(ST.elem[i].key) == ERROR) if(!Visit(ST.elem[i].key)) { return ERROR; }//if }//for //输出换行使结果美观 printf("\n"); //操作成功 return OK;}//SSTableTraverse_Seq//5.----------------------顺序表的顺序查找算法------------------ /* 函数:SSTableTraverse_Seq 参数:SSTable ST 静态查找表ST KeyType key 被查找的关键字 返回值:若找到,则函数值为该元素在表中的位置,否则为0 作用:在顺序表ST中顺序查找其关键字等于key的数据元素。*/int Search_Seq(SSTable ST, KeyType key){ //i是循环变量,存储了关键字在表中的位置 int i; //0号单元不放被查找数据元素,放关键字,作用相当于"哨兵", //好处在于不必时时提防数组越界问题 ST.elem[0].key = key; //从后向前查找,直至找到元素或遇到哨兵为止 for(i = ST.length; !EQ(ST.elem[i].key, key); --i); //返回关键字在表中的位置i return i; }//Search_Seq //6.-----------------------静态查找表的排序操作-------------------/* 函数:SortSSTable_Seq 参数:SSTable &ST 静态查找表引用 返回值:若找到,则函数值为该元素在表中的位置,否则为0 作用:排序顺序表中元素,使顺序表变为有序表,以便于对有序表进行查找 */Status SortSSTable_Seq(SSTable &ST) { //将线性表中的元素排序,使用冒泡法, /*传统冒泡排序中每一趟排序操作只能找到一个最大值或最小值, 我们考虑利用在每趟排序中进行正向和反向两遍冒泡的方法 一次可以得到两个最终值(最大者和最小者),从而使排序趟数几乎减少了一半*/ //对空表做排序没意义 if(SSTableEmpty_Seq(ST)) { return ERROR; }//if int low = 1, high = ST.length, tmp, j; while (low < high) { //正向冒泡,找到最大者 for (j = low; j < high; ++j) { if (ST.elem[j].key > ST.elem[j + 1].key){ tmp = ST.elem[j].key; ST.elem[j].key = ST.elem[j + 1].key; ST.elem[j + 1].key = tmp; }//if }//for //修改high值, 前移一位 --high; //反向冒泡,找到最小者 for (j = high; j > low; --j) { if (ST.elem[j].key < ST.elem[j - 1].key) { tmp = ST.elem[j].key; ST.elem[j].key = ST.elem[j - 1].key; ST.elem[j - 1].key = tmp; }//if }//for //修改low值,后移一位 ++low; }//while } //SortSSTable_Seq//7.----------------------有序表的折半查找算法------------------/* 函数:Search_Bin 参数:SSTable ST 静态查找表ST 返回值:若找到,则函数值为该元素在表中的位置,否则为0 作用:在有序表ST中折半查找其关键字等于key的数据元素*/int Search_Bin(SSTable ST, KeyType key){ //置区间初值 int low = 1, high = ST.length, mid; //当low > high时查找结束 while(low <= high){ //计算出mid mid = (low + high) / 2; //找到待查元素 if(EQ(key, ST.elem[mid].key)) { return mid; }//if //继续在前半区间进行查找 else if(LT(key,ST.elem[mid].key)) { high = mid - 1; }//else if //继续在后半区间进行查找 else { low = mid + 1; }//else }//while //顺序表中不存在待查元素 return 0; }//Search_Bin //8.-----------------------静态查找表的销毁操作--------------------/* 函数:DestorySSTable_Seq 参数:SSTable &ST 静态查找表引用 返回值:无 作用:销毁静态查找表ST*/void DestorySSTable_Seq(SSTable &ST){ //释放静态查找表内存空间 free(ST.elem); //指针置空 ST.elem = NULL; printf("内存空间释放成功!\n"); } //DestorySSTable_Seq//***************************************主函数******************************************** int main(int argc,char *argv[]){ //声明顺序查找表ST SSTable ST; //关键字 KeyType key; //状态标志 Status flag; printf("\n***************************顺序表及有序表查找算法测试***************************\n"); printf("->创建一个静态查找(顺序)表,请按要求进行操作\n"); InitSSTable_Seq(ST); SSTableInput_Seq(ST); printf("->您创建的静态查找表包含的所有元素如下:\n"); SSTableTraverse_Seq(ST, Print); printf("->请输入您想在顺序表中查找的元素:\n"); scanf("%d", &key); flag=Search_Seq(ST, key); if(!flag) { printf("查找失败!\n"); }//if else { printf("查找成功!该元素在表中的位置为%d,表中该位置元素值为%d。\n", flag, ST.elem[flag].key); }//else printf("对顺序表排序,准备进行有序表查找。\n"); SortSSTable_Seq(ST); printf("->排序后顺序表变为有序表,表中所有元素依次是:\n"); SSTableTraverse_Seq(ST, Print); printf("->请输入您想在有序表中查找的元素:\n"); scanf("%d", &key); flag=Search_Bin(ST, key); if(!flag) { printf("查找失败!\n"); }//if else { printf("查找成功!该元素在表中的位置为%d,表中该位置元素值为%d。\n", flag, ST.elem[flag].key); }//else printf("->销毁静态查找表ST:"); DestorySSTable_Seq(ST); return 0; }//main
输入数据来自书上P219页。
程序运行时输出:
->创建一个静态查找(顺序)表,请按要求进行操作->您想输入几个元素,请输入个数,最多不可以超过100 11请输入静态查找表ST的元素,中间用空格隔开,最多不可以超过100个元素05 13 19 21 37 56 64 75 80 88 92->您创建的静态查找表包含的所有元素如下: 5 13 19 21 37 56 64 75 80 88 92->请输入您想在顺序表中查找的元素:12查找失败!对顺序表排序,准备进行有序表查找。->排序后顺序表变为有序表,表中所有元素依次是: 5 13 19 21 37 56 64 75 80 88 92->请输入您想在有序表中查找的元素:88查找成功!该元素在表中的位置为10,表中该位置元素值为88。->销毁静态查找表ST:内存空间释放成功!--------------------------------Process exited with return value 0Press any key to continue . . .
总结:顺序表排序后变为有序表,查找效率有所提升。
下次的文章会介绍动态查找表也就是二叉排序树的实现。感谢大家一直以来的关注和支持。再见!
阅读全文
0 0
- 数据结构编程笔记二十四:第九章 查找 顺序表和有序表(静态查找表)查找算法的实现
- 数据结构编程笔记二十五:第九章 查找 二叉排序树(动态查找表)查找算法的实现
- 静态查找表(二)有序表的查找
- 静态表查找--顺序表的查找(有序)--折半查找
- 查找:链表顺序查找和有序数组二分查找
- 查找-顺序,有序表
- 查找(一)静态查找的顺序查找和 有序折半查找
- 数据结构--有序表查找
- 数据结构:静态查找表(顺序表)
- 【数据结构-查找】有序表的查找-折半查找
- 算法学习之查找算法:静态查找表(2)有序表查找
- 数据结构 查找 静态查找表
- 数据结构之查找(二)——顺序表查找
- 查找算法整理(一)---静态查找表:顺序表查找、折半(判定树)查找、静态查找树
- 算法-查找-线性表的查找(顺序查找,二分查找,分块查找)
- 数据结构编程笔记二十六:第九章 查找 平衡二叉树的实现
- 数据结构中的查找算法-静态查找表(1)
- 顺序表查找、有序表查找、索引顺序表查找
- 山峰和旗子
- ShaderForge笔记01—认识ShaderForge
- spring data jpa hibernate jpa 三者之间的关系
- Apache服务器安装
- maven手动添加 oracle 依赖
- 数据结构编程笔记二十四:第九章 查找 顺序表和有序表(静态查找表)查找算法的实现
- 将博客搬至CSDN
- partition table doesn't exist 该怎么恢复
- CTR预估中GBDT与LR融合方案
- 【Centos7.x】
- 【POJ】2975
- oracle12c安装详细图解
- codeforces 851C Five Dimensional Points 鸽巢定理
- 面向对象编程