静态链表Test1

一.实验目的
     巩固线性表的数据结构的存储方法和相关操作,学会针对具体应用,使用线性表的相关知识来解决具体问题。
 
二..实验内容
  建立一个由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)才解决了错误;

除此之外,我还出现了不少细节上的小错误,在此就不一一列举了。

通过这次实验,发现了自己的不少问题,在解决了问题的同时也在提高着自己,相信自己以后能做到更好。



 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值