一、实验目的
巩固线性表的数据结构的存储方法和相关操作,学会针对具体应用,使用线性表的相关知识来解决具体问题。
二、实验内容
建立一个由n个学生成绩的顺序表,n的大小由自己确定,每一个学生的成绩信息由自己确定,实现数据的对表进行插入、删除、查找等操作。分别输出结果。用单链表实现。
三、实验步骤
1、依据实验内容分别说明实验程序中用到的数据类型的定义:
LinkList(); //建立只有头结点的空链表
LinkList(DataTypea[],int n); //建立有n个元素的单链表
~LinkList(); //析构函数
intLocate(DataType x); //在单链表中查找值为x的元素序号
voidInsert(int i,DataType x); //在第i个位置插入元素值为x的结点
DataTypeDelete(int i); //在单链表中删除第i个结点
voidPrintList(); //按序号依次输出各元素
2、相关操作的算法表达
定义单链表类LinkList,包括插入、删除、查找、输出等基本操作。
插入操作:
1.工作指针p初始化;
2.查找第i-1个结点并使工作指针p指向该节点;
3.若查找不成功,说明插入位置不合理,抛出插入位置非法;
(1)否则,生成一个元素值为x的新结点s;
(2)将新结点插入到结点p之后;
删除操作:
1.工作指针p初始化,累加器count初始化;
2.查找第i-1个结点并使工作指针p指向该节点;
3.若p不存在或p的后继结点不存在,抛出插入位置非法;
(1)否则,暂存被删结点和被删元素值;
(2)摘链,将结点p的后继结点从链表上摘下;
(3)释放被删结点
(4)返回被删元素值
查找操作:
(1) 按位查找
1.工作指针p初始化,累加器count初始化;
2.从头指针出发顺next域逐个结点往下搜索直到某个结点,判断是否为第i个结点。
3.若是,则查找成功;否则将工作指针p后移;
(2)按值查找
1.工作指针p初始化,累加器count初始化;
2.对单链表中各元素依次进行比较。查找成功则返回元素序号;否则,返回0表示查找失败;
输出操作:
1.工作指针p初始化;
2.重复执行下述操作,直到p为空:
(1) 输出结点p的数据域;
(2)工作结点p后移
源代码如下:
#ifndef LinkList_H
#define LinkList_H
template<class DataType>
struct Node
{
DataTypedata;
Node<DataType>*next;
};
template<class DataType>
class LinkList
{
public:
LinkList(); //建立只有头结点的空链表
LinkList(DataTypea[],int n); //建立有n个元素的单链表
~LinkList(); //析构函数
intLocate(DataType x); //在单链表中查找值为x的元素序号
voidInsert(int i,DataType x); //在第i个位置插入元素值为x的结点
DataTypeDelete(int i); //在单链表中删除第i个结点
voidPrintList(); //按序号依次输出各元素
private:
Node<DataType>*first; //单链表的头指针
};
#endif
#include<iostream>
using namespace std;
#include"LinkList.h"
template<class DataType>
LinkList<DataType>::LinkList()
{
first=newNode<DataType>; //生成头结点
first->next=NULL; //头结点的指针域置空
}
template<class DataType>
LinkList<DataType>::LinkList(DataTypea[],int n)
{
Node<DataType>*r,*s;
first=newNode<DataType>; //生成头结点
r=first; //尾指针初始化
for(inti=0;i<n;i++)
{
s=newNode<DataType>;
s->data=a[i]; //为每个数组元素建立一个结点
r->next=s;r=s; //将结点s插入到终端结点之后
}
r->next=NULL; //将终点指针域置空
}
template<class DataType>
LinkList<DataType>::~LinkList()
{
Node<DataType>*q=NULL;
while(first!=NULL) //释放单链表每一个结点的存储空间
{
q=first; //暂存被释放结点
first=first->next; //first指向被释放结点的下一个结点
deleteq;
}
}
template<class DataType>
void LinkList<DataType>::Insert(inti,DataType x)
{
Node<DataType>*p=first,*s=NULL; //工作指针p指向头结点
intcount=0;
while(p!=NULL&&count<i-1) //查找第i-1个结点
{
p=p->next; //工作指针p后移
count++;
}
if(p==NULL)throw"位置"; //没有找到第i-1个结点
else
{
s=newNode<DataType>;s->data=x; //结点s的数据域为x
s->next=p->next;p->next=s; //将结点s插入到结点p之后
}
}
template<class DataType>
DataTypeLinkList<DataType>::Delete(int i)
{
Node<DataType>*p=first,*q=NULL;
DataTypex;
intcount=0;
while(p!=NULL&&count<i-1)
{
p=p->next;
count++;
}
if(p==NULL||p->next==NULL)
throw"位置"; //结点p或p的后继结点不存在
else{
q=p->next;x=q->data; //暂存被摘结点
p->next=q->next; //摘链
deleteq;
returnx;
}
}
template<class DataType>
intLinkList<DataType>::Locate(DataType x)
{
Node<DataType>*p=first->next; //工作指针p初始化
intcount=1; //count初始化
while(p!=NULL)
{
if(p->data==x)return count; //查找成功,返回序号
p=p->next;
count++;
}
return0; //退出循环列表表明查找失败
}
template<class DataType>
void LinkList<DataType>::PrintList()
{
Node<DataType>*p=first->next; //工作指针p初始化
while(p!=NULL)
{
cout<<p->data<<"";
p=p->next; //工作指针p后移
}
cout<<endl;
}
#include<iostream>
using namespace std;
#include "LinkList.cpp"
void main()
{
intr[5]={90,88,75,68,73};
LinkList<int>L(r,5);
cout<<"执行插入操作前的学生成绩为:"<<endl;
L.PrintList(); //输出所有学生成绩
try
{
L.Insert(2,81);//在第2个位置插入值为81的元素
}
catch(char*s)
{
cout<<s<<endl;
}
cout<<"执行插入操作后的学生成绩为:"<<endl;
L.PrintList();//输出所有学生成绩
cout<<"成绩为90的元素位置为:";
cout<<L.Locate(90)<<endl;
cout<<"执行删除第3个成绩操作,删除前所有学生成绩为:"<<endl;
L.PrintList();//输出所有学生成绩
try
{
L.Delete(3);//删除第3个元素
}
catch(char*s)
{
cout<<s<<endl;
}
cout<<"删除后的学生成绩为:"<<endl;
L.PrintList();//输出所有学生成绩
}
运行结果如图.