一.实验目的
巩固线性表的数据结构的存储方法和相关操作,学会针对具体应用,使用线性表的相关知识来解决具体问题。
二..实验内容
建立一个由n个学生成绩的顺序表,n的大小由自己确定,每一个学生的成绩信息由自己确定,实现数据的对表进行插入、删除、查找等操作。分别输出结果。
(用单链表来实现)。
三..源代码
//StaticList.h文件
#pragma once
#include<iostream>
#include<string>
using namespace std;
const int MaxSize = 100;
template<class T>
struct Student
{
string name;
T S_score;
};
template<class T>
class Node
{
public:
T data;
int next;
};
template<class T>
class StaticList
{
public:
StaticList(T a[], int n);
~StaticList();
int GetLength();
T Get(int i);
int Locate(T x);
bool Insert(T e, int index);
bool Delete(T &e, int index);
void PrintList();
private:
int first;
int avail;
int i_Length;
Node<T> Slist[MaxSize];
};
template<typename T>
StaticList<T>::StaticList(T a[], int n) {
i_Length = 0;
for (int i = 0; i < MaxSize; i++)
{
Slist[i].next = i + 1;
}
Slist[MaxSize - 1].next = -1;
avail = 2;
first = 1;
Slist[first].next = -1;
for (int j = n-1; j >=0; j--)
{
if (avail == -1)
{
break;
}
int s = avail;
avail = Slist[avail].next;//空闲链的头指针后移
Slist[s].data = a[j];//将a[j]填入下标为S的节点
Slist[s].next = Slist[first].next;//将a[j]插到first后面
Slist[first].next = s;
i_Length++;
}
}
template<class T>
StaticList<T>::~StaticList()
{
}
template<class T>
int StaticList<T>::GetLength()
{
return i_Length;
}
template<typename T>
T StaticList<T>::Get(int i) {
if (i <= 0 || i > i_Length) {
throw"";
}
int s = first;
for (int j = 0; j < i; j++) {
s = Slist[s].next;
}
return Slist[s].data;
}
template<class T>
int StaticList<T>::Locate(T x)
{
int count =0;
int s = first;
while (Slist[s].data.S_score!= x.S_score)
{
count++;
s = Slist[s].next;
if (count > i_Length)
{
return -1;
}
}
return count;
}
template<class T>
bool StaticList<T>::Insert(T e, int index)
{
if (index<0 || index>i_Length+1)
{
return false;
}
int s = first;
for (int i = 1; i < index; i++)
{
s = Slist[s].next;
}
int k = Slist[s].next;
Slist[s].next = avail;
Slist[avail].data.name = e.name;
Slist[avail].data.S_score = e.S_score;
Slist[avail].next = k;
avail = Slist[avail].next;
i_Length++;
return true;
}
template<class T>
bool StaticList<T>::Delete(T &e, int index)
{
if (index<0 || index>i_Length + 1)
{
return false;
}
int s = first;
for (int i = 0; i < index; i++)
{
s=Slist[s].next;
}
int q = Slist[s].next;
e = Slist[s].data;
Slist[s].next = Slist[q].next;
Slist[q].next = avail;
avail = q;
i_Length--;
return true;
}
template<class T>
void StaticList<T>::PrintList()
{
int s = first;
for (int i = 0; i < i_Length; i++)
{
s = Slist[s].next;
cout << Slist[s].data.name << ":"<<Slist[s].data.S_score;
cout << endl;
}
}
//源.cpp文件
#include"StaticList.h"
#include<iostream>
using namespace std;
int main(void)
{
Student<float> student[4] = { {"小明",100 }, {"小红",90},{"小刚",80.5},{"小强",60.5} };
StaticList<Student<float>> S1(student, 4);
S1.PrintList(); //遍历学生成绩
cout << "-------------------------------" << endl;
cout << "成绩链长度为:"<<S1.GetLength() << endl; //获取成绩链的长度
cout <<"第三个学生:"<<endl<<S1.Get(3).name <<":"<<S1.Get(3).S_score<< endl; //取第三个成绩
cout <<"小红的位置:"<< S1.Locate({ "小红",90 }) << endl; //获取名为“小红”,成绩为90的位置
cout << "-------------------------------" << endl;
S1.Insert({"小李",85.5}, 3);//在第三个位置插入
S1.PrintList(); //遍历学生成绩
cout << "-------------------------------" << endl;
Student<float> temp;
S1.Delete(temp, 2); //提取并删除第二个成绩
cout << temp.name <<":"<<temp.S_score<< endl; //输出被删除的成绩
cout << "-------------------------------" << endl;
S1.PrintList(); //遍历学生成绩
system("pause");
return 0;
}
实验结果如下:
一一验证正确。
四、实验心得
静态链表是花费我时间和精力敲最多的一个线性表,其中主要原因是自己对静态链表的掌握度不够,对于avail和first指针的运用并不熟悉,在插入和删除操作时对静态链
和空闲链的位置移动也不是很清晰,所以出现了不少问题,在仔细研究课本之后才真正完全理解了其原理;在对student s1的定义时,一开始我输入了
StaticList<Student> S1(student, 4),发现提示错误“缺少类模板Student的参数列表”,才发现少了模板的参数,改为StaticList<Student<float>> S1(student, 4)才解决了错误;
除此之外,我还出现了不少细节上的小错误,在此就不一一列举了。
通过这次实验,发现了自己的不少问题,在解决了问题的同时也在提高着自己,相信自己以后能做到更好。