一.实验目的
巩固静态链表的数据结构的存储方法和相关操作,学会针对具体应用,使用线性表的相关知识来解决具体问题。
二. 实验内容
建立一个由n个学生成绩的顺序表,n的大小由自己确定,每一个学生的成绩信息由自己确定,实现数据的对表进行插入、删除、查找等操作。用静态链表来实现,分别输出结果。
为了以后的对代码的修改、优化和复用,这里采用了C++中的模板来实现,下面是模板的实现。
StaticLinkList.h
#ifndef StaticLinkList_h
#define StaticLinkList_h
#include <iostream>
using namespace std;
const int MaxSize = 100;
template <class DataType>
struct SNode {
DataType data;
int next;
};
template <class DataType>
class StaticLink {
public:
// 构造函数
StaticLink(DataType a[],int n);
// 析构函数
~StaticLink() {};
//返回单链表的长度
int Length();
//按位查找
DataType Get(int i);
//按值查找
int Locate(DataType x);
//插入元素
bool Insert(int i, DataType x);
//删除节点
bool Delete(int i);
//遍历节点
void PrintList();
private:
int first;
int avail;
int length;
SNode<DataType> SList[MaxSize];
};
#endif /* StaticLinkList_h */
StaticLinkList.cpp
#include "StaticLinkList.h"
template<typename DataType>
StaticLink<DataType>::StaticLink(DataType a[],int n) {
for (int i = 0; i < MaxSize; i++) {
SList[i].next = i + 1;
}
length = 0;
SList[MaxSize - 1].next = -1;
avail = 2;
first = 1;
SList[first].next = -1;
//利用头插法插入元素
for (int j = 0; j < n;j++) {
//判断链中是否已满
if (avail == -1) {
break;
}
int s = avail;
avail = SList[avail].next;
SList[s].data = a[j];
SList[s].next = SList[first].next;
SList[first].next = s;
length++;
}
}
template<typename DataType>
int StaticLink<DataType>::Length() {
return length;
}
template<typename DataType>
DataType StaticLink<DataType>::Get(int i) {
if (i <= 0 || i > length) {
throw "位置错误";
}
int s = first;
for (int j = 0; j < i; j++) {
s = SList[s].next;
}
return SList[s].data;
}
template<typename DataType>
int StaticLink<DataType>::Locate(DataType x) {
int count = 0;
int s = first;
while (count<length && SList[s].next != -1)
{
if (SList[s].data == x) {
return count;
}
count++;
s = SList[s].next;
}
return -1;
}
template<typename DataType>
bool StaticLink<DataType>::Insert(int i, DataType x) {
if (SList[avail].next == -1) {
return false;
}
int s = first;
int temp = avail;
SList[temp].data = x;
avail = SList[avail].next;
for (int count=0; count < i-1 && count < length; count++) {
s = SList[s].next;
}
SList[temp].next = SList[s].next;
SList[s].next = temp;
length++;
return true;
}
template<typename DataType>
bool StaticLink<DataType>::Delete(int i) {
if (i <= 0 || i > length) {
return false;
}
int count = 0;
int s = first;
while (count < i-1&&count < length) {
s = SList[s].next;
count++;
}
int q = SList[s].next;
SList[s].next = SList[q].next;
SList[q].next = avail;
avail = q;
length--;
return true;
}
template<typename DataType>
void StaticLink<DataType>::PrintList() {
int s = SList[first].next;
for (int i = 1; i <= length; i++) {
cout << SList[s].data << " ";
s = SList[s].next;
}
cout << endl;
}
以上是静态链表模板,实现了基本的功能。写线性表的模板,重点在初始化时的构造函数,还有遍历的过程,只要会遍历了,适当加上逻辑判断就能实现基本的功能,当然了,这可不是最好的写法,还有比现在写的高效的算法。
接下来就是是用上面的模板去实现成绩表的操作。
main.cpp
#include <iostream>
#include "StaticLinkList.cpp"
int main(int argc, const char * argv[]) {
float score[5] = {80.5, 90, 85.5, 95, 100};
StaticLink<float> list(score, 5);
cout << "遍历学生分数" << endl;
list.PrintList();
cout << "读取第三个学生的分数" << endl;
cout << list.Get(3) << endl;
cout << "在第二个位置插入学生分数 95" << endl;
list.Insert(2, 95);
list.PrintList();
cout << "80分在分数表中的位置为: " << list.Locate(90) << endl;
cout << "该分数表长度为: " << list.Length() << endl;
cout << "删除第3个分数" << endl;
list.Delete(3);
list.PrintList();
return 0;
}
运行结果如下:
三. 总结和心得
静态表和单链表十分相似,所谓是静态就是它用了一个数组去模拟了一个链表,有了单链表在插入和删除不用移动元素的优点,但是也有顺序表不能扩展的缺点。静态链表的练习可以巩固对单链表的学习,说实话写一次并不能掌握到多少,如果能抛下书本写成功几次应该就能更好的掌握了。
静态链表中和了数组和链表,比较综合。我在学习时,对空闲链一下子也没有反应过来。在多敲代码的同时,要更加注重思维了。