头文件
#define LIST_MAX_SIZE 5
#define LISTINCREMENT 2
#include<assert.h>
#include<string>
template<class type >//<>中是模板参数在用模板类的时候必须给出,可以不止一个且不能为空,class和typename的作用是一样的 其后的形参可以声明数据
class sqlist
{
protected:
type *s;//顺序表起始地址;
int listsize;//当前分配个数
int n;//当前元素个数
private:
/*
顺序数组重置(清空)
*/
void clear()
{
type* ns;
ns= new type[5];
assert(ns!=0);
for(int c=0;c<=n-1;++c)
ns[c]=s[c];
delete [] s;//释放旧的空间
s=ns;//把地址给原指针
listsize=LIST_MAX_SIZE;
n=0;
}
/*
顺序数组的输入
*/
void putin(int a)//a是用户要输入的元素个数
{
int i;
type *ns;
clear();
pd:
//*****判断分配个数是否足够不够就添加***
if(a>listsize-n)
{
ns= new type[listsize+LISTINCREMENT];
assert(ns!=0);
for(int c=0;c<=n;++c)
ns[c]=s[c];
delete [] s;//释放旧的空间
s=ns;//把地址给原指针
listsize=listsize+LISTINCREMENT;//分配个数增加
if(a>listsize-n)
goto pd;
}
//*****判断分配个数是否足够不够就添加***
cout<<"输入开始"<<endl;
for(i=0;i<a;i++)
{
cin>>s[i];
n++;//元素个数增加
}
}
/*
显示当前顺序表
*/
void out()
{
int i;
for(i=0;i<=n-1;i++)
{
cout<<s[i]<<' ';
}
}
/*
删除一个数据
*/
void del(int a)
{
int i;
a=a-1;
for(i=0;(a+i+1)<n;i++)//从删除后一位开始向前移动
s[a+i]=s[a+i+1];
n--;
}
/*
插入一个数据(未使用)
*/
void inset()
{
type* ns;
type a;
int i;
cout<<"请输入你要插入的数据"<<endl;
cin>>a;
t:
cout<<"请输入你要在第几位数后插入数据"<<endl;
cin>>b;
if(b<1||b>n)//判断b的有效性
{
cout<<"错误请重新输入"<<endl;
goto t;
}
if((listsize-n)>0)
;
else
{
//*****判断分配个数是否足够不够就添加***
ns= new type[listsize+LISTINCREMENT];
assert(ns!=0);
for(int c=0;c<=n;++c)
ns[c]=s[c];
delete [] s;
s=ns;//把地址给原指针
listsize=listsize+LISTINCREMENT;//分配个数增加
}
for(i=n-1;i!=b-1;i--)//从末位到添加位中间的数向后移动
s[i+1]=s[i];
s[b]=a;
n=n+1;
}
/*
插入一个数据(一个带参数的重载)
*/
void inset(int b,type a )
{
type* ns;
int i;
if((listsize-n)>0)
;
else
{
//*****判断分配个数是否足够不够就添加***
ns= new type[listsize+LISTINCREMENT];
assert(ns!=0);
for(int c=0;c<=n;++c)
ns[c]=s[c];
delete [] s;
s=ns;//把地址给原指针
listsize=listsize+LISTINCREMENT;//分配个数增加
}
for(i=n-1;i!=b-1;i--)//从末位到添加位中间的数向后移动
s[i+1]=s[i];
s[b]=a;
n=n+1;
}
/*
给顺序表排序
*/
void sort()
{
int a,i;
type min,change;
for(i=0;i<n;i++)
{
min=s[i];
for(a=i+1;a<n;a++)
if(s[a]<min)
{
change=s[a];
s[a]=min;
min=change;
}
s[i]=min;
}
}
/*
查找一个数据
*/
void find( type a)//折半查找
{
int low,mid,height,p=1;
sort();
low=0;
height=n-1;
while(low<=height)
{
mid=(int)(low+height)*0.5;
if(s[mid]==a)
{
cout<<a<<"是顺序表由小到大的第"<<mid+1<<"位元素"<<endl;
p=0;//用于判断是否找到元素
break;
}
else if(s[mid]<a)
low=mid+1;
else
height=mid-1;
}
if(p)
cout<<"没有找到该元素"<<endl;
}
/*
倒置
*/
void inversion()
{
int i=0,a=n-1;
type k;
for(;i!=a&&i<a;i++)
{
k=s[i];
s[i]=s[a];
s[a]=k;
}
}
/*
重载=运算符(未使用)
*/
sqlist<type> operator=(type *right)
{
int a;
if(this!= right)
{
for(int i=0;right[i]!=' ';i++)
;
a=i;
delete s[];
s= new type[a];
for(i=0;i<a;i++)
//s[i]=right[i];
return *s;
}
}
/*
顺序表的交集
*/
void intersection ()
{
char u='o';
int i;
int c;
type *p;
type x[50];//用于存放不同于类中顺序表的元素;
int g;//新顺序表的元素个数;
int y=0;//变化x数组下标
cout<<"请输入你要与这个顺序表求交集的顺序表"<<endl;
cout<<"请给出你要输入顺序表元素的个数";
cin>>g;
p= new type [g];
assert(p!=0);
for(i=0;i<g;i++)
cin>>p[i];
for(i=0;i<g;i++)
for(c=0;c<n;c++)
if(s[c]==p[i])
{
x[y]=s[c];
y++;
}
cout<<"交集为:";
for(i=0;i<y;i++)
cout<<x[i]<<' ';
cout<<"是否以交集替换当前顺序表?(n or y)"<<endl;
m:
cin>>u;
if(u!='n'&&u!='y')
{
cout<<"错误请重新输入u"<<endl;
goto m;
}
else if(u=='y')
{
clear();
listsize=y;
n=y;
s=new type[y];
for(i=0;i<y;i++)
s[i]=x[i];
// *s=*x;
}
else if(u=='n')
;
}
/*
顺序表的并集
*/
void sumj()
{
int g;//元素个数
int i;
int c;
int o=0;
bool r=true;
type *x;
cout<<"请输入要与当前顺序表合并的顺序表"<<endl;
cout<<"请输入你要输入多少个元素"<<endl;
cin>>g;
x = new type[g];
cout<<"输入开始"<<endl;
for(i=0;i<g;i++)
cin>>x[i];
for(c=0;c<g;c++)
{
for(i=0;i<n;i++)
if(s[i]==x[c])
r=false;
if(r==true)
inset(n,x[c]);
r=true;
}
cout<<"并集后的顺序表为"<<endl;
out();
r=true;
delete [] x;
}
/*
顺序表的差集
*/
void different()
{
int g;
int c;
int i;
char u;
bool r=true;
type *p;//存放求差元素
type x[50];//存放差集
int y=0;
cout<<"请输入要与当前顺序表求差集的顺序表B"<<endl;
cout<<"请输入你要输入多少个元素"<<endl;
cin>>g;
p= new type[g];
for(i=0;i<g;i++)
cin>>p[i];
for(c=0;c<g;c++)
{
for(i=0;i<n;i++)
if(p[c]==s[i])
r=false;
if(r==true)
{
x[y]=p[c];
y++;
}
r=true;
}
cout<<"B对当前顺序表的差集为"<<endl;
for(i=0;i<y;i++)
cout<<x[i]<<' ';
cout<<"是否以交集替换当前顺序表?(n or y)"<<endl;
mi:
cin>>u;
if(u!='n'&&u!='y')
{
cout<<"错误请重新输入u"<<endl;
goto mi;
}
else if(u=='y')
{
clear();
listsize=y;
n=y;
s=new type[y];
for(i=0;i<y;i++)
s[i]=x[i];
}
else if(u=='n')
;
}
/*
查找第一个与e满足compare关系的元素(未使用)
*/
void fcompare(type e)//status 可以用来代替数据类型的名称是代码更易理解
{
}
/*
结构体的输出
*/
void sout()
{
int i;
for(i=0;i<=n-1;i++)
{
cout<<"姓名"<<' '<<"学号"<<' '<<"性别"<<' '<<"健康状况"<<' '<<"身高"<<endl;
cout<<s[i].name<<' '<<s[i].id<<' '<<s[i].sex<<' '<<s[i].health<<' '<<' '<<s[i].height<<endl;
}
}
/*
结构体的输入
*/
void sputin(int a)//a是用户要输入的元素个数
{
int i;
type *ns;
pd:
//*****判断分配个数是否足够不够就添加***
if(a>listsize-n)
{
ns= new type[listsize+LISTINCREMENT];
assert(ns!=0);
for(int c=0;c<=n;++c)
ns[c]=s[c];
delete [] s;//释放旧的空间
s=ns;//把地址给原指针
listsize=listsize+LISTINCREMENT;//分配个数增加
if(a>listsize-n)
goto pd;
}
//*****判断分配个数是否足够不够就添加***
cout<<"输入开始"<<endl;
for(i=0;i<a;i++)
{
cout<<"学生的姓名:";
cin>>s[i].name;
cout<<endl;
cout<<"学生的学号:";
cin>>s[i].id;
cout<<endl;
cout<<"学生的性别:";
cin>>s[i].sex;
cout<<endl;
cout<<"学生的健康:";
cin>>s[i].health;
cout<<endl;
cout<<"学生的身高:";
cin>>s[i].height;
cout<<endl;
n++;//元素个数增加
}
}
/*
结构体插入一个数据(一个带参数的重载)
*/
void ssinset(int b,type a )
{
type* ns;
int i;
if((listsize-n)>0)
;
else
{
//*****判断分配个数是否足够不够就添加***
ns= new type[listsize+LISTINCREMENT];
assert(ns!=0);
for(int c=0;c<=n;++c)
ns[c]=s[c];
delete [] s;
s=ns;//把地址给原指针
listsize=listsize+LISTINCREMENT;//分配个数增加
}
for(i=n-1;i!=b-1;i--)//从末位到添加位中间的数向后移动
s[i+1]=s[i];
s[b]=a;
n=n+1;
}
/*
结构体查找一个数据
*/
void sfind(int a)
{
for(int i=0;;i++)
if(s[i].id==a)
{
cout<<"学号为"<<a<<"的同学的数据如下"<<endl;
cout<<"姓名"<<' '<<"学号"<<' '<<"性别"<<' '<<"健康状况"<<' '<<"身高"<<endl;
cout<<s[i].name<<' '<<s[i].id<<' '<<s[i].sex<<' '<<s[i].health<<' '<<s[i].height<<endl;
cout<<endl;
cout<<endl;
cout<<endl;
break;
}
else
continue;
}
/*
输入一个顺序表用=替换原表(未使用)
*/
void th()
{
int b,i;
sqlist a;
cout<<"请输入你要输入的顺序表的元素个数"<<endl;
cin>>b;
a.putin(b)
sq=b;//如何表示当前顺序表?
}
public:
/*
拷贝初始化构造函数(未使用)
*/
sqlist(const sqlist<type>&otherl)
{
s=new s[otherl.listsize];
assert(s!=0);
listsize=otherl.listsize;
n=otherl.n;
for(int i;i<=n;++i)
s[i-1]=otherl.s[i-1];
}
/*
构造函数
*/
sqlist()
{
s=new type[5];
listsize=LIST_MAX_SIZE;
n=0;
}
/*
总菜单
*/
void menu()
{
int a,b;
cout<<"*********************顺序表处理菜单*********************"<<endl;
cout<<"1.输入"<<endl;
cout<<"2.插入"<<endl;
cout<<"3.删除"<<endl;
cout<<"4.查找"<<endl;
cout<<"5.倒置顺序表"<<endl;
cout<<"6.由小到大排列顺序表"<<endl;
cout<<"7.清空顺序表"<<endl;
cout<<"8.求交集"<<endl;
cout<<"9.求并集"<<endl;
cout<<"10.求差集"<<endl;
cout<<"11.由小到大排序"<<endl;
//cout<<"12.输入一个顺序表替换原表"<<endl;
cout<<"当前数组"<<endl;
out();
cout<<endl;
cout<<"*********************顺序表处理菜单*********************"<<endl;
p:
cout<<"请选择:";
cin>>a;
switch(a)
{
case 1: {
cout<<"请输入你要输入几个数";
cin>>b;
putin(b);
}
;break;
case 2: {
type mn;
cout<<"请输入你要插入的数据"<<endl;
cin>>mn;
t:
cout<<"请输入你要在第几位数后插入数据"<<endl;
cin>>b;
if(b<1||b>n)//判断b的有效性
{
cout<<"错误请重新输入"<<endl;
goto t;
}
inset(b,mn);
};break;
case 3:
{ x:
cout<<"请输入你要删除顺序表的第几位数"<<endl;
cin>>a;
if(a<1||a>n)//判断a的有效性
{
cout<<"错误请重新输入"<<endl;
goto x;
}
del(a);
};break;
case 4: {
type kl;
cout<<"请输入你要查找的数据:"<<endl;
cin>>kl;
find(kl);
};break;
case 5: inversion();break;
case 6: sort();break;
case 7: clear();break;
case 8: intersection (); break;
case 9: sumj();break;
case 10: different();break;
case 11: sort();break;
//case 12: th();break;
default: cout<<"错误请重新选择"<<endl; goto p ;break;
}
cout<<endl;
}
/*
结构体菜单
*/
void smenu()
{
int a,b;
cout<<"*********************顺序表处理菜单*********************"<<endl;
cout<<"1.输入"<<endl;
cout<<"2.插入"<<endl;
cout<<"3.删除"<<endl;
cout<<"4.查找"<<endl;
cout<<"5.清空顺序表"<<endl;
cout<<"当前数组"<<endl;
sout();
cout<<endl;
cout<<"*********************顺序表处理菜单*********************"<<endl;
p:
cout<<"请选择:";
cin>>a;
switch(a)
{
case 1: {
cout<<"请输入你要输入几个数";
cin>>b;
sputin(b);
}
;break;
case 2: {
type mn;
cout<<"请输入你要插入的数据"<<endl;
cout<<"姓名:";
cin>>mn.name;
cout<<endl;
cout<<"学号:";
cin>>mn.id;
cout<<endl;
cout<<"性别:";
cin>>mn.sex;
cout<<endl;
cout<<"身高:";
cin>>mn.height;
cout<<endl;
cout<<"健康:";
cin>>mn.health;
cout<<endl;
t:
cout<<"请输入你要在第几位数后插入数据"<<endl;
cin>>b;
if(b<1||b>n)//判断b的有效性
{
cout<<"错误请重新输入"<<endl;
goto t;
}
inset(b,mn);
};break;
case 3:
{ x:
cout<<"请输入你要删除顺序表的第几位数"<<endl;
cin>>a;
if(a<1||a>n)//判断a的有效性
{
cout<<"错误请重新输入"<<endl;
goto x;
}
del(a);
};break;
case 4: {
type kl;
cout<<"请输入你要查找的学号:"<<endl;
cin>>kl.id;
sfind(kl.id);
};break;
case 5: clear();break;
default: cout<<"错误请重新选择"<<endl; goto p ;break;
}
}
};//在类中的成员函数应该多设立对应参数 返回对应值,这样才能使成员函数能在多个地方使用。
//某些功能结构体和普通数据类型不能通用
主函数
#include<iostream>
#include<string>
#include"head_sqlist.h"
#include<assert.h>
using namespace std;
int main()
{
struct student
{
int id;
string name;
string health;
int height;
string sex;
};
//sqlist<int> sq;
char p='y',u='y';
int a;//a用于switch语句 b用于表输入的输入次数控制
for(;u!='n';)
{
cout<<"请输入你要处理的数据类型(char(1) int(2) float(3) double(4) student(5))"<<endl;
cin>>a;
p='y';
s:
switch(a)//在case中定义变量或者新建对象必须用{}
{
case 1: {sqlist<char> sq;
for(;p!='n';)
{
sq.menu();
getchar();//接受回车键
cout<<"是否继续处理顺序表? 请输入 任意字符继续或n结束"<<endl;
p=getchar();
system("cls");
}
}break;
case 2: {sqlist<int> sq;
for(;p!='n';)
{
sq.menu();
getchar();//接受回车键
cout<<"是否继续处理顺序表? 请输入 任意字符继续或n结束"<<endl;
p=getchar();
system("cls");
}
}break;
case 3: {sqlist<float> sq;
for(;p!='n';)
{
sq.menu();
getchar();//接受回车键
cout<<"是否继续处理顺序表? 请输入 任意字符继续或n结束"<<endl;
p=getchar();
system("cls");
}
}break;
case 4: {sqlist<double> sq;
for(;p!='n';)
{
sq.menu();
getchar();//接受回车键
cout<<"是否继续处理顺序表? 请输入 任意字符继续或n结束"<<endl;
p=getchar();
system("cls");
}
}break;
case 5:{sqlist<struct student> sq;
for(;p!='n';)
{
sq.smenu();
getchar();//接受回车键
cout<<"是否继续处理顺序表? 请输入 任意字符继续或n结束"<<endl;
p=getchar();
system("cls");
}
}break;
default: cout<<"错误请重新输入"<<endl; goto s ;
}
cout<<"是否继续处理其他类型顺序表? 请输入 任意字符继续或n结束"<<endl;
getchar();
u=getchar();
}
system("pause");
}
//代码通用性不够,应注意函数的重复使用