数据结构实验三

《数据结构》实验三:                 线性表综合实验 

一.实验目的:

巩固线性表的数据结构的存储方法和相关操作,学会针对具体应用,使用线性表的相 关知识来解决具体问题。

二、实验内容:

1.建立一个由 n 个学生成绩的顺序表,n 的大小由自己确定,每一个学生的成绩信息由自己 确定,实现数据的对表进行插入、删除、查找等操作。分别输出结果。 要求如下: 1)用顺序表来实现。 2)用单链表来实现。 3)用双链表实现。 4)用静态链表实现。 5)用间接寻址实现。

1、用顺序表实现

#include<iostream>
using namespace std;
const int MaxSize=100;
class Seqlist
{
double score[MaxSize];
int length;
public:
Seqlist(){length=0;}        //无参的构造函数,建立一个空的顺序表
Seqlist(double a[],int n)        //有参的构造函数,建立一个长度为n的顺序表
{
if(n>MaxSize) throw"超过最大学生人数!";
for(int i=0;i<n;i++)
score[i]=a[i];
length=n;
}
~Seqlist(){}        //析构函数
int Getlength(){return length;}        //求线性表的长度
double Getnum(int i)              //按位查找学生的成绩
{
if(i<1&&i>length) throw"不存在该学生!";
return score[i-1];
}
double Locate(double x)      //按值查找学生的位置
{
if(x<0&&x>100) throw"分数非法!";
for(int i=0;i<length;i++)
if(score[i-1]==x) 
return i;
return 0;
}
void Insert(int i,double x)          //插入操作,在线性表的第i个位置插入值为x的学生会学生成绩
{
if(length>=MaxSize) throw"上溢";
if(i<1||i>length+1) throw"位置异常";
for(int j=length;j>=i;j--)
score[j]=score[j-1];
score[i-1]=x;
length++;
}
int Delete(int i)               //删除操作,删除顺序表中的第i个位置的学生成绩
{
if(length==0) throw"下溢";
if(i<1||i>length) throw"位置异常";
double x;
x=score[i-1];
for(int j=i;j<length;j++)
score[j-1]=score[j];
length--;
return x;
}
void Print()
{
for(int i=0;i<length;i++)
cout<<"第"<<i+1<<"个学生的成绩为: "<<score[i]<<endl;
}
};
void main()
{
cout<<"***顺序表的代码与实现***"<<endl;
double a[5]={80,76,91.5,75,68.5};
Seqlist A(a,5);
cout<<"执行插入操作前的数据: "<<endl;
A.Print();
cout<<"执行插入操作,在第二个位置插入学生成绩85"<<endl;
A.Insert(2,85);
cout<<"执行插入操作后的数据: "<<endl;
A.Print();
cout<<"查询到第四个的位置上学生的成绩为: "<<A.Getnum(4)<<endl;
cout<<"查询学生成绩为75的位置为: "<<A.Locate(75)<<endl;
cout<<"执行删除操作,删除第二个的位置上学生的成绩"<<endl;
A.Delete(2);
cout<<"执行删除操作后的数据: "<<endl;
A.Print();

}


2、用单链表实现

#include<iostream>
using namespace std;
const int MaxSize=100;
template<class D>       //定义模板类D
struct Node             //定义结构体,用于结点的申请
{
D date;
Node<D> *next;
};
template<class D>
class Linklist
{
Node<D> *first;       //单链表的头指针
public:
Linklist()        //无参的构造函数,建立一个空的顺序表
{
first=new Node;        //生成头结点
first->next=NULL;       //头结点的指针域置为空
}
Linklist(D a[],int n)        //有参的构造函数,建立一个长度为n的顺序表
{
Node<D> *r,*s;
first=new Node<D>;        //生成头结点
r=first;                 //尾指针初始化
for(int i=0;i<n;i++)
{
s=new Node<D>;s->date=a[i];        //为每一个数组元素建立一个结点
r->next=s;r=s;     //将结点s插入到头结点之后
}
r->next=NULL;             //将终端结点的指针置为空
}
~Linklist()        //析构函数
{
Node<D> *q=NULL;
while(first!=NULL)       //释放单链表的每一个结点的存储空间
{
q=first;               //暂存被释放结点
first=first->next;       //first指向被释放结点的下一个结点
delete q;
}
}
int Length()        //求线性表的长度
{
Node<D> *p=NULL;
p=first->next;count=0;      //工作指针p和累加器count初始化
while(p!=NULL)
{
p=->next;
count++;
}
return count;
}
double Getnum(int i)              //按位查找学生的成绩
{
Node<D> *p=NULL;
p=first->next;int count=1;         //工作指针p和累加器count初始化
while(p!=NULL&&count<i)
{
p=p->next;              //工作指针p后移
count++;
}
if(p==NULL) throw"位置异常";
return p->date;
}
double Locate(double x)      //按值查找学生的位置
{
Node<D> *p=NULL;
p=first->next;int count=1;         //工作指针p和累加器count初始化
while(p!=NULL)
{
if(p->date==x) return count;       //查找成功,结束函数并返回序号
p=p->next;
count++;
}
cout<<"查找失败"<<endl;
return 0;             //退出循环表明查找失败
}
void Insert(int i,double x)          //插入操作,在线性表的第i个位置插入值为x的学生会学生成绩
{
Node<D> *p=NULL,*s;
p=first;int count=0;       //工作区间p应指向头结点
while(p!=NULL&&count<i-1)        //查找第i-1个结点
{
p=p->next;          //工作指针后移
count++;
}
if(p==NULL) throw"位置异常,找不到结点";
else
{
s=new Node<D>;s->date=x;     //申请一个结点s,其数据域为x
s->next=p->next;p->next=s;   //将结点s插入到结点p之后
}
}
int Delete(int i)               //删除操作,删除顺序表中的第i个位置的学生成绩
{
Node<D> *p=NULL,*q=NULL;
int x;
p=first;int count=0;       //工作区间p应指向头结点
while(p!=NULL&&count<i-1)        //查找第i-1个结点
{
p=p->next;          //工作指针后移
count++;
}
if(p==NULL||p->next==NULL) throw"位置异常";   //结点p不存在或者p的后继结点不存在
else
{
q=p->next;x=q->date;   //暂存被删结点
p->next=q->next;     //摘链
delete q;
return x;
}
}
void Print()
{
Node<D> *p=NULL;
p=first->next;        //工作指针初始化
while(p!=NULL)
{
cout<<p->date<<" ";
p=p->next;       //工作指针后移
}
cout<<endl;
}
};
void main()
{
cout<<"***单链表的代码与实现***"<<endl;
int a[5]={80,76,91,75,68.5};
Linklist <int>A(a,5);
cout<<"执行插入操作前的数据: "<<endl;
A.Print();
cout<<"执行插入操作,在第二个位置插入学生成绩85"<<endl;
A.Insert(2,85);
cout<<"执行插入操作后的数据: "<<endl;
A.Print();
cout<<"查询到第四个的位置上学生的成绩为: "<<A.Getnum(4)<<endl;
cout<<"查询学生成绩为75的位置为: "<<A.Locate(75)<<endl;
cout<<"执行删除操作,删除第二个的位置上学生的成绩"<<endl;
A.Delete(2);
cout<<"执行删除操作后的数据: "<<endl;
A.Print();

}


3、用双链表实现

#include<iostream>
using namespace std;
const int MaxSize=100;
template<class D>       //定义模板类D
struct Node             //定义结构体,用于结点的申请
{
D date;
Node<D> *prior,*next;
};
template<class D>
class Linklist
{
Node<D> *first;       //单链表的头指针
public:
Linklist()        //无参的构造函数,建立一个空的顺序表
{
first=new Node;        //生成头结点
first->next=NULL;       //头结点的指针域置为空
}
Linklist(D a[],int n)        //有参的构造函数,建立一个长度为n的顺序表
{
Node<D> *r,*s;
first=new Node<D>;        //生成头结点
r=first;                 //尾指针初始化
for(int i=0;i<n;i++)
{
s=new Node<D>;s->date=a[i];        //为每一个数组元素建立一个结点
r->next=s;r=s;     //将结点s插入到头结点之后
}
r->next=NULL;             //将终端结点的指针置为空
}
~Linklist()        //析构函数
{
Node<D> *q=NULL;
while(first!=NULL)       //释放单链表的每一个结点的存储空间
{
q=first;               //暂存被释放结点
first=first->next;       //first指向被释放结点的下一个结点
delete q;
}
}
int Length()        //求线性表的长度
{
Node<D> *p=NULL;
p=first->next;count=0;      //工作指针p和累加器count初始化
while(p!=NULL)
{
p=->next;
count++;
}
return count;
}
double Getnum(int i)              //按位查找学生的成绩
{
Node<D> *p=NULL;
p=first->next;int count=1;         //工作指针p和累加器count初始化
while(p!=NULL&&count<i)
{
p=p->next;              //工作指针p后移
count++;
}
if(p==NULL) throw"位置异常";
return p->date;
}
double Locate(double x)      //按值查找学生的位置
{
Node<D> *p=NULL;
p=first->next;int count=1;         //工作指针p和累加器count初始化
while(p!=NULL)
{
if(p->date==x) return count;       //查找成功,结束函数并返回序号
p=p->next;
count++;
}
cout<<"查找失败"<<endl;
return 0;             //退出循环表明查找失败
}
void Insert(int i,D x)          //插入操作,在线性表的第i个位置插入值为x的学生会学生成绩
{
Node<D> *p,*s;
p=first;int count=0;       //工作区间p应指向头结点
while(p!=NULL&&count<i-1)        //查找第i-1个结点
{
p=p->next;          //工作指针后移
count++;
}
if(p==NULL) throw"位置异常,找不到结点";
else
{
s=new Node<D>;
s->date=x;            //申请一个结点s,其数据域为x
s->prior=p;
s->next=p->next;
p->next->prior=s;
p->next=s;   //将结点s插入到结点p之后
}
}
int Delete(int i)               //删除操作,删除顺序表中的第i个位置的学生成绩
{
Node<D> *p=NULL,*q=NULL;
int x;
p=first;int count=0;       //工作区间p应指向头结点
while(p!=NULL&&count<i-1)        //查找第i-1个结点
{
p=p->next;          //工作指针后移
count++;
}
if(p==NULL||p->next==NULL) throw"位置异常";   //结点p不存在或者p的后继结点不存在
else
{
q=p->next;x=q->date;   //暂存被删结点
p->next=q->next;     //摘链
(q->next)->prior=p->prior;
delete q;
return x;
}
}
void Print()
{
Node<D> *p=NULL;
p=first->next;        //工作指针初始化
while(p!=NULL)
{
cout<<p->date<<" ";
p=p->next;       //工作指针后移
}
cout<<endl;
}
};
void main()
{
cout<<"***双链表的代码与实现***"<<endl;
int a[5]={80,76,91,75,68.5};
Linklist <int>A(a,5);
cout<<"执行插入操作前的数据: "<<endl;
A.Print();
cout<<"执行插入操作,在第二个位置插入学生成绩85"<<endl;
A.Insert(2,85);
cout<<"执行插入操作后的数据: "<<endl;
A.Print();
cout<<"查询到第四个的位置上学生的成绩为: "<<A.Getnum(4)<<endl;
cout<<"查询学生成绩为75的位置为: "<<A.Locate(75)<<endl;
cout<<"执行删除操作,删除第二个的位置上学生的成绩"<<endl;
A.Delete(2);
cout<<"执行删除操作后的数据: "<<endl;
A.Print();

}


4、用静态链表实现

#include<iostream>
using namespace std;
const int MaxSize=100; 
template<class D>
struct Node
{
D data;
int next;
};
template<class D>
class SL                //定义静态链表的类
{
private:
int first;
int avail;
int length;
Node<D> list[MaxSize];
public:
SL();                //无参构造
SL(D a[],int n);     //有参构造
~SL(){}              //析构函数
int Length();        //静态链表的长度
D Get(int i);        //按位查找
int Locate(D x);     //按值查找
void Insert(int i,D x);      //插入操作
D Delete(int i);             //删除操作
void Print();        //遍历操作 
};


template<class D>
SL<D>::SL()
{
first=0;
list[0].next=avail=1;
for(int i=1;i<MaxSize-1;i++)
list[i].next=i+1;       //初始化空闲链    
list[MaxSize-1].next=-1;      //置空闲链结束的标志 
}
template<class D>
SL<D>::SL(D a[],int n)
{
length=0;
int s;
if(n<=0||n>MaxSize) throw"error";
first=0;
list[0].next=avail=1;
for(int i=1;i<MaxSize-1;i++)
list[i].next=i+1;       //初始化空闲链    
list[MaxSize-1].next=-1;      //置空闲链结束的标志 
for(int j=0;j<n;j++)
{
s=avail;
list[s].data=a[j];
avail=list[avail].next;
length++;
}
list[s].next=-1;
}
template<class D>
int SL<D>::Length()
{
int p=list[first].next;count=0;
while(p!=-1)
{
p=list[p].next;
count++;
}
return count;
}
template<class D>
D SL<D>::Get(int i)
{
if(i<=0||i>length) throw"位置非法";
int p=list[first].next,count=1;     //工作指针p和累加器count初始化
while(p!=-1&&count<i)
{
p=list[p].next;         //工作指针后移
count++;
}
if(p==-1) throw"位置";
return list[p].data;
}
template<class D>
int SL<D>::Locate(D x)
{
int p=list[first].next,count=1;
while(p!=-1)
{
if(list[p].data==x) return count;        //查找成功,结束函数并返回序号
p=list[p].next;
count++;
}
return 0;        //退出循环表明查找失败
}
template<class D>
void SL<D>::Insert(int i,D x)
{
int p=list[first].next,count=0;
while(p!=-1&&count<i-1)       //查找第i-1个结点
{
p=list[p].next;
count++;
}
if(p==-1) throw"位置";
int s=avail;                  //不用申请新结点,利用空闲链的第一个结点
avail=list[avail].next;       //空闲链的头指针后移
list[s].data=x;               //将x填入下标为s的结点
list[s].next=list[p].next;    //将下标为s的结点插入到下标为p的结点后面
list[p].next=s;  
}
template<class D>
D SL<D>::Delete(int i)
{
int p=list[first].next,count=0;
while(p!=-1&&count<i-1)         //查找第i-1个结点
{
p=list[p].next;
count++;
}
if(p==-1||list[p].next==-1) throw"位置";    //结点p不存在或者p的后继结点不存在
int q=list[p].next;    //暂存被删结点
list[p].next=list[q].next;      //摘链
list[q].next=avail;          //将结点q插入空闲链avail的最前端
avail=q;            //空闲链头指针avail指向结点q
return list[p].data;
}
template<class D>
void SL<D>::Print()
{
int p=list[first].next, count=1;     //工作指针p初始化
while(p!=-1)
{
cout<<"第"<<count<<"学生的成绩为: "<<list[p].data<<endl;
p=list[p].next;              //工作指针p后移
count++;
}
}
void main()
{
cout<<"***静态链表的代码与实现。***"<<endl;
float a[5]={80,76,91.5,75,68.5};
SL<float> A(a,5);
cout<<"执行插入操作前的数据: "<<endl;
A.Print();
cout<<"执行插入操作,在第二个位置插入学生成绩85"<<endl;
A.Insert(2,85);
cout<<"执行插入操作后的数据: "<<endl;
A.Print();
cout<<"查询到第四个的位置上学生的成绩为: "<<A.Get(4)<<endl;
cout<<"查询学生成绩为75的位置为: "<<A.Locate(75)<<endl;
cout<<"执行删除操作,删除第二个的位置上学生的成绩"<<endl;
A.Delete(2);
cout<<"执行删除操作后的数据: "<<endl;
A.Print();

}

5、用间接寻址实现

#include<iostream>
using namespace std;
const int MaxSize=100;
template<class D>       //定义模板类
struct Node
{
D data;
};
template<class D>
class Inadd            //定义间接寻址类
{
public:
Inadd(){length=0;}        //无参的构造函数
Inadd(D a[],int n);      //带参的构造函数
~Inadd(){}             //析构函数
int Length(){return length;}         //求表的长度
D Get(int i);       //按位查找
int Locate(D x);     //按值查找
void Insert(D x,int i);     //插入操作
D Delete(int i);         //删除操作,按位删除
    void Print();           //遍历操作
private:
Node<D> *add[MaxSize];        //创建存储指向该元素的指针的数组
int length;            //表的长度 
};


template<class D>
Inadd<D>::Inadd(D a[],int n)
{

if(n>MaxSize) throw"超过最大学生人数!";
for(int i=0;i<n;i++)
{
add[i]=new Node<D>;
add[i]->data=a[i];

}
length=n;
}
template<class D>
D Inadd<D>::Get(int i)
{
if(i<1||i>length) throw"参数非法";
return add[i-1]->data;
}
template<class D>
int Inadd<D>::Locate(D x)
{
for(int i=0;i<length;i++)
if(add[i]->data==x) return i+1;
return 0;
}
template<class D>
void Inadd<D>::Insert(D x,int i)
{
if(length>MaxSize) throw"上溢";
if(i<1||i>length+1) throw"参数非法";
for(int j=length;j>=i;j--)
add[j]=add[j-1];
add[i-1]->data=x;
length++;
}
template<class D>
D Inadd<D>::Delete(int i)
{
if(length==0) throw"下溢";
if(i<1||i>length) throw"参数非法";
int x=add[i-1]->data;
for(int j=i;j<length;j++)
add[j-1]->data=add[j]->data;
length--;
return x;
}
template<class D>
void Inadd<D>::Print()
{
for(int i=0;i<length;i++)
cout<<"第"<<i+1<<"个学生的成绩是: "<<add[i]->data<<endl;
}
void main()
{
cout<<"***间接寻址的代码与实现***"<<endl;
float a[5]={80,76,91.5,75,68.5};
Inadd<float> A(a,5);
cout<<"执行插入操作前的数据: "<<endl;
A.Print();
cout<<"执行插入操作,在第二个位置插入学生成绩85"<<endl;
A.Insert(85,2);
cout<<"执行插入操作后的数据: "<<endl;
A.Print();
cout<<"查询到第四个的位置上学生的成绩为: "<<A.Get(4)<<endl;
cout<<"查询学生成绩为75的位置为: "<<A.Locate(75)<<endl;
cout<<"执行删除操作,删除第二个的位置上学生的成绩"<<endl;
A.Delete(2);
cout<<"执行删除操作后的数据: "<<endl;
A.Print();

}


猜你喜欢

转载自blog.csdn.net/panlxg/article/details/80261337