静态链表
一、实验目的
巩固线性表的数据结构的存储方法和相关操作,学会针对具体应用,使用线性表的相关知识来解决具体问题。
二、实验内容
建立一个由n个学生成绩的顺序表,n的大小由自己确定,每一个学生的成绩信息由自己确定,实现数据的对表进行插入、删除、查找等操作。分别输出结果。
三、详细设计(C++)
1.算法设计
定义顺序表的数据类型——静态链表类,包括插入、删除、查找、遍历等基本操作。
静态链表是用数组来表示单链表,用数组元素的下标来模拟单链表的指针。静态链表的每个数组元素由两个域构成:data域存放数据元素,next域存放该元素的后继元素所在的数组下标。Avail是空闲链(所有空闲数组单元组成的单链表)头指针,first是静态链表头指针。
插入操作:首先从空闲链的最前端摘下一个结点,将该结点插入静态链表中。
1. 数组元素下标p初始化;
2. 查找第i-1个结点并使数组元素下标p指向该结点;
3. 若查找不成功,说明插入位置不合理,抛出参数非法;
否则,
3.1不用申请新结点,利用空闲链的第一个结点
3.2空闲链的头指针后移
3.3将x填入下标为s的结点
3.4将下标为s的结点插入到下标为p的结点后面
删除操作:
1 数组元素下标p初始化,累加器count初始化;
2 查找第i个结点并使用数组元素下标p指向该结点;
3 若p=-1,则抛出参数非法;
否则,数组元素下标p指向待删除结点
3.1 暂存被删结点的下标
3.2 摘链
3.3 将结点q插在空闲链avail的最前端
3.4 空闲链头指针avail指向结点q
2.源程序代码
#include<iostream>
using namespace std;
const int MaxSize=100;
struct SNode
{
int data;
int next;
}SList[MaxSize];
class StaticList
{
public:
StaticList();
StaticList(int a[],int n);
~StaticList();
int Length();
int Get(int i);
int Locate(int x);
void Insert(int i,int x);
int Delete(int i);
void PrintList();
private:
int first,avail;
};
StaticList::StaticList()
{
for(int i=0;i<MaxSize-1;++i)
{
SList[i].next=i+1;
}
SList[MaxSize-1].next=0;
}
StaticList::StaticList(int a[],int n)
{
if(n<0||n>MaxSize)
throw"参数非法";
for(int i=0;i<MaxSize;i++)
{
SList[i].next=i+1;
}
SList[MaxSize-1].next=-1;
first=0;
avail=1;
SList[first].next=-1;
for(int j=0;j<n;j++)
{
int s=avail;
avail=SList[avail].next;
SList[s].data=a[j];
SList[s].next=SList[first].next;
SList[first].next=s;
}
}
StaticList::~StaticList()
{
}
int StaticList::Length()
{
if(0==SList[1].next)
return 0;
int i=1;
int count=-1;
do
{
++count;
i=SList[i].next;
}while(0!=i);
return count;
}
int StaticList::Get(int n)
{
int i=1;
while(0!=i&&SList[SList[i].next].data!=n)
i=SList[i].next;
if(0==i)
{
cout<<"位置异常"<<endl;
return -1;
}
return i;
}
int StaticList::Locate(int x)
{
if(SList[first].next==-1)
throw"无成绩";
int p=first,count=0;
while(SList[p].next!=-1)
{
if(SList[p].data==x)
return count;
p=SList[p].next;
count++;
}
return 0;
}
void StaticList::Insert(int i,int x)
{
if(i<0||i>MaxSize)
throw"参数非法";
int s=avail;
int p=first;
if(p==-1)
throw"参数非法";
for(int count=0;count<i-1;count++)
{
p=SList[p].next;
}
avail=SList[avail].next;
SList[s].data=x;
SList[s].next=SList[p].next;
SList[p].next=s;
}
int StaticList::Delete(int i)
{
if(i<0||i>MaxSize)
throw"参数非法";
int p=first;
if(p==-1)
throw"参数非法";
for(int count=0;count<i-1;count++)
{
p=SList[p].next;
}
int q=SList[p].next;
SList[p].next=SList[q].next;
SList[q].next=avail;
avail=q;
return 0;
}
void StaticList::PrintList()
{
int p=SList[first].next;
while(p!=-1)
{
cout<<SList[p].data<<" ";
p=SList[p].next;
}
cout<<endl;
}
int main()
{
int score[10]={95,64,78,59,46,39,66,89,91,10};
StaticList List(score,10);
cout<<"查询分数前的数据为:"<<endl;
List.PrintList();
cout<<"值为66的元素位置为:";
cout<<List.Locate(66)<<endl;
cout<<"插入前的数据为:"<<endl;
List.PrintList();
try
{
List.Insert(2,77);
}
catch(char *s)
{
cout<<s<<endl;
}
cout<<"插入后的数据为:"<<endl;
List.PrintList();
cout<<"删除前的数据为a:"<<endl;
List.PrintList();
try
{
List.Delete(10);
}
catch(char *s)
{
cout<<s<<endl;
}
cout<<"删除第十个元素后的数据为:"<<endl;
List.PrintList();
system("pause");}
四、运行与测试结果