首先,按照惯例,欢迎大家边听歌边看本博客!!!
这里是神奇的赛尔号_张杰 (kugou.com)
一.背景:由于是上机实验,直接引用数据结构教程第6版73页的实验题1
修改第6,7,8,10题改为由用户输入而非直接求!
二.代码
同上期,由于比较简单和有较多注释的原因,笔者在这里不再赘述!
值得注意的是一定要先搞清楚用户输入的逻辑序号(就是我认为A是第一位),但是在数组中即在物理序号中(A在a【0】的位置),这里多次决定了循环需不需要等号,代码很长且每部分关联性较强,所以一个等号的失误可能会促成全局的错误,建议大家写完一部分后编译运行一下!!!!
#include<iostream>
using namespace std;
#define Max 100000
typedef char ch;//将数据类型改成ch,方便代码修改
typedef struct //创建一个自己想要的关键字,这是结构体
{//这里补充:由于我们创建的是一个顺序表,定义了关键字后,结构体的内容就应该为顺序表中我们想实现的功能
ch data[Max];//存储字母
int lth;//length长度
}Sqlist;//关键字的名称叫做Sqlist,因为我们要做一个顺序表
//初始化顺序表
void Initsqlist(Sqlist *&L)//内容包括开辟空间,定义长度
{
L=new Sqlist;
L->lth=0;
}
//释放顺序表
void destroysqlist(Sqlist *&L)
{
delete L;
}
//插入元素
bool Insertsqlist(Sqlist *&L,int i,ch e)//感想:为什么要用bool,因为要两种不同的回答
{
if(i<1||i>L->lth+1)//逻辑,逻辑序号判断
return false;
i--;//更改为物理序号
for(int j=L->lth;j>i;j--)
{
L->data[j]=L->data[j-1];
}
L->data[i]=e;
L->lth++;
return true;
}
//删除元素
bool delem(Sqlist *&L,int i,ch &o)
{
if(i<1||i>=L->lth+1)
return false;
i--;
o=L->data[i];
for(int j=i;j<L->lth-1;j++)
{
L->data[j]=L->data[j+1];
}
L->lth--;
return true;
}
//输出顺序表
void displaysqlist(Sqlist *L)
{
for(int i=0;i<L->lth;i++)
cout<<L->data[i]<<" ";
}
//输出顺序表的长度
int displaylength(Sqlist *L)
{
return L->lth;
}
//判断顺序表是否为空
bool listempty(Sqlist *L)
{
return (0==L->lth);
}
//输出某个元素(判断可不可取)
bool getlist(Sqlist *L,int i,ch &tmp)//感想:这种三个参数的好处就在于既可以判断,还可以直接锁定输出
{
if(i<1||i>=L->lth+1)
return false;
i--;
tmp=L->data[i];
return true;
}
//输出元素的位置(判断存不存在)
int locelem(Sqlist *L,ch tmp)
{
int k=0;//物理序号从0开始
while(k<=L->lth-1&&L->data[k]!=tmp){
k++;
}
if(k>=L->lth)
return 0;
else
return k+1;//返回逻辑序号
}
int main()
{
Sqlist *L1;Initsqlist(L1);
cout<<"1.初始化顺序表成功!!!"<<endl<<endl;
int h=1;
ch a[10]={'A','B','C','D','E'};
cout<<"2.依次插入ABCDE."<<" ";
for(int i=0;i<5;i++)
{
if(!Insertsqlist(L1,i+1,a[i]))//这里注意我们所输入的参数是逻辑序号,在第一位插入
{
cout<<"Warning:插入失败!!!请重试"<<endl;
h=0;
}
}
if(h)
cout<<"插入成功!!!"<<endl<<endl;
//输出顺序表
cout<<"3.当前顺序表的元素有:";displaysqlist(L1);cout<<endl<<endl;
//输出长度
cout<<"4.当前顺序表的长度为:"<<displaylength(L1)<<endl<<endl;
//空表
cout<<"5.当前顺序表";
if(listempty(L1))
cout<<"为空表"<<endl<<endl;
else
cout<<"不为空表"<<endl<<endl;
//取值(输出元素)
cout<<"6.取值操作:";
ch temp;int p;
cout<<"请输入您要取哪个位置的值:";cin>>p;
if(getlist(L1,p,temp))
cout<<"取值成功! "<<"顺序表第"<<p<<"位的元素是:"<<temp<<endl<<endl;
else
cout<<"取值失败,您输入的位置"<<p<<"越界!!!"<<endl<<endl;
cout<<"7.查找操作:";
ch find;
cout<<"请输入您要查找的元素: ";cin>>find;
if(locelem(L1,find)==0)
cout<<"对不起,当前顺序表中没有您查找的元素!!"<<endl<<endl;
else
cout<<"查找成功,您所查找的元素"<<find<<"在当前顺序表的第"<<locelem(L1,find)<<"位"<<endl<<endl;
cout<<"8.插入操作:";
int k;ch q;
cout<<"请您输入一个数字和一个字符,代表在第几位插入一个字符:";cin>>k>>q;
; if(!Insertsqlist(L1,k,q))
cout<<"Warning:输入序号越界,插入失败!!!"<<endl;
else
cout<<"插入成功!!!"<<endl<<endl;
cout<<"9.当前顺序表的元素有:";displaysqlist(L1);cout<<endl<<endl;
//删除元素
cout<<"10.删除操作:";
int y;ch o;
cout<<"请您输入要删除的元素的序号:";cin>>y;
if(!delem(L1,y,o))
cout<<"对不起,您的输入的序号有误(越界),删除失败!"<<endl<<endl;
else
cout<<"删除成功!成功删除第"<<y<<"个元素"<<o<<endl<<endl;
cout<<"11.当前顺序表的元素有:";displaysqlist(L1);cout<<endl<<endl;
//释放顺序表
cout<<"12.销毁顺序表:";
destroysqlist(L1);
cout<<"销毁成功!!!";
return 0;
}
//值得注意
//1.顺序表的长度是逻辑序号
//我们查找插入所输入的序号也是逻辑序号
全部输入正确的例子
全部错误的例子
这里给大家推荐几组试错样例
第六部分输入:6或者-1
第七:A,a或者凌乱的程序猿
第八:6 o
第10:6
反复试试边缘数字对修改代码也是有用处的!!!
其实在编写代码的时候笔者也考虑到了,因为提前看过书本,思维比较定式,以上代码多个部分可以优化重改,
bool和return int 其实两者代码是可以互换的,而且个人觉得return int会比较通顺,输入bool也不难,但是一旦错了,在bool这里会比较犹豫,然后就是什么时候三个参数,什么时候几个参数,什么时候使用&,什么时候使用*了
做了这么久不难发现struct *l其实就是一个指向结构题体的指针(具体在上期的复数已经注释过了,不赘述)
需要改变传进来的数时使用&(引用)
多少参数主要看函数的作用,比如我们的插入函数的作用是判断和传值,所以我们把结构体放进来,需要序号,需要字符,所以三个,再写的时候可以先想想这个函数的功能是什么,然后再写!!