上机实验报告实验课题:实现对有序数据集合的顺序查找和二分查找,并展示出查找过程设计思路:我们可以采用数组有序的保存所有数据,这样便于将数据的有序性和其索引的有序性统一起来,同时也便于查找数据。
需要声明的是,我们不使用零下标的项,这样做是为了在顺序查找中优化传统顺序查找算法,具体原因后面会有详细介绍。
为此,我们可以设计一个类,私有变量声明为该数组和数组的长度。
由于集合中的数据类型未知,所以该类为模板类。
对于公有成员,我们创建六个成员函数,除了构造函数和析构函数,其他四个函数分别用来获取外界传入的数组长度、获取外界传入的数组数据、对数据实现顺序查找、对数据实现二分查找。
这里,我们只重点介绍顺序查找函数和二分查找函数。
对于顺序查找,我们对传统的顺序查找方法进行优化,避开每次对数据索引是否越界进行判断这一步骤。
具体做法是:将所查找的元素保存在零下标的项中(这也是零下标闲置的原因),然后按照下标顺序从后向前依次遍历匹配所查找元素与数组元素。
若两者相等,展示出该数组元素,并将其下标值反馈给客户;若两者不相等,展示出该元素,进行下一轮匹配。
若最终标记下标达到零下标处,说明未查找到所要查找的元素,则客户反馈该信息。
优化后的顺序查找算法比传统的顺序查找算法减少一半的步骤,原因在于每次无须判断标记下标是否越界,这是该算法优化后的优点。
它的缺点是没有利用到数据集合有序这一性质,且查找效率低。
对于二分查找,我们声明三个整型变量low、high和mid 依次标记查找域的上界下标、下界下标和中值下标,其中mid=(low+high)/2。
我们在开始的时候将low初始化为1(上文中提到过,我们是从下表为1的位置开始存储数据),将high初始化为len(数组长度),并由此初始化mid的值。
对于任意一次查找,将索引为mid的值与所查找的值进行比较。
若两者相等,则将该元素的索引值反馈给客户;若所查找的值比索引为mid的值小,则将high的值变为mid-1,进行下一轮的查找;若所查找的值比索引为mid的值大,则将low 的值变为mid+1,进行下一轮查找。
若最终low>high,则表明未查找到所要查找的值,将此信息反馈给客户。
该算法是一种效率很高的算法,因为它充分利用到数据集合的有序性,这一优点在数据规模较大时体现的更明显。
实验过程分析:1.在编码过程中,出现了诸如语句末尾逗号遗漏等低级错误。
2.在对WL类的成员函数编码时,出现了函数声明错误,原因是对模板类的语法不熟,编码较少,对类面向对象这一思想理解不透彻。
3.在编码用户选择菜单等地方时,考虑到了程序的健壮性,添加了异常处理,比以前进步。
源代码:#include <iostream>#include "WL.h"#define MAX 10000 //定义数组的最大长度using namespace std;int main(){WL<int> p; //以整形数据为例,将模板类实例化int num,i,x; //num用来存储数组长度,x存储所查找的值int a[MAX];char s;cout<<"Please input the length of the array:"; //提示用户输入数组长度cin>>num;p.getlen(num);cout<<"Please input each data in order:"; //提示用户依次输入数据,并将其保存在数组中for(i=1;i<=num;i++)cin>>a[i];p.getdata(a,num);cout<<endl;cout<<"Please input the data searched:"; //提示用户输入所查找的值cin>>x;cout<<endl;loop:cout<<"Please choose the way for search:"<<endl; //提示用户选择查找方式,并进行查找cout<<"1. Order_search"<<endl;cout<<"2. Binary_search"<<endl<<endl;cout<<"Please input the figure notation:";cin>>s;cout<<endl;if(s=='1')p.find(x);else if(s=='2')p.binary_search(x);else{cout<<"Operator error!"<<endl<<endl; //若用户输入值不为‘1’或‘2’,对用户进行提示重新操作goto loop;}return 0;}***********************************************#ifndef WL_H_INCLUDED#define WL_H_INCLUDED#include <iostream>#define MAX 10000using namespace std;template <class T> //由于数据类型未知,采用模板类声明class WL{private:T s[MAX]; //对存储数据的数组进行声明int len; //对数组长度进行声明public:WL() {};~WL() {}void getlen(int num); //从外界获取数组长度值,并将其传给lenvoid getdata(T a[],int num); //从外界获取数组数据,并将其传给s[MAX] void find(const T x); //顺序查找函数声明void binary_search(const T x); //二分查找函数声明};template <class T>void WL<T>::getlen(int num){len=num;}template <class T>void WL<T>::getdata(T a[],int num){int i;for(i=1;i<=num;i++)s[i]=a[i];}template <class T>void WL<T>::find(const T x){int i=len; //将标记下标初始化为lens[0]=x; //将所查找元素赋给s[0]cout<<"The process of the search:";while(s[i]!=x) //若未查找到x,展示出该数据值{cout<<s[i]<<' ';i--;}if(i)cout<<s[i];cout<<endl;if(!i) //若i=0,说明查找失败,将该信息反馈给客户cout<<"Sorry,no result!"<<endl;else //若i!=0,将索引值反馈给客户cout<<"The index of the data is "<<i<<endl;}template <class T>void WL<T>::binary_search(const T x){int low=1,high=len; //声明并初始化low、highint mid;cout<<"The process of the search:";while(low<=high) //low<=high 说明还未找到所查找的值{mid=(low+high)/2;if(x==s[mid]) //若找到所查找的元素,将该值展示出来,并将索引值反馈给客户{cout<<s[mid]<<endl;cout<<"The index of the data is "<<mid<<endl;return;}else if(x<s[mid]) //若x比s[mid]小,将查找域上界变为mid-1{cout<<s[mid]<<' ';high=mid-1;}else //若x比s[mid]大,将查找域下界变为mid+1{cout<<s[mid]<<' ';low=mid+1;}}cout<<endl;cout<<"Sorry,no result!"<<endl; //若low>high,说明查找失败,将信息反馈给客户}#endif // WL_H_INCLUDED测试结果:顺序查找:二分查找:。