一.实验目的
巩固线性表的数据结构的存储方法和相关操作,学会针对具体应用,使用线性表的相关知识来解决具体问题。
二..实验内容
建立一个由n个学生成绩的顺序表,n的大小由自己确定,每一个学生的成绩信息由自己确定,实现数据的对表进行插入、删除、查找等操作。分别输出结果。
(用双向链表来实现)。
三..源代码
//IndirectList.h文件
#include<iostream>
using namespace std;
const int MaxSzie = 100;
template<class T>
struct Node
{
T data;
Node *next;
};
template<class T>
class IndirectList
{
public:
IndirectList(); //无参构造函数
IndirectList(T b[], int n); //有参构造函数,插入长度为n的单链表
~IndirectList();
int Length(); //返回单链表的长度
T Get(int i); //按位查找,查找第i个节点的元素
int Locate(T x); //按值查找,查找链表中第一个值为x的元素,并返回序号
bool Insert(int i, T x); //插入元素,在第i个位置插入值x
bool Delete(int i); //删除节点,删除第i个节点
bool InsertHead(T x); //头插法插入节点
bool InsertTail(T x); //尾插法插入节点
void ListTraverse(); //正向遍历节点
bool changeList(int i, T x); //改变某一结点的值 i为节点的位置,x为替换的值
private:
Node<T> *first;
int m_Length;
Node<T> *a[MaxSzie];
};
template<class T>
IndirectList<T>::IndirectList()
{
for (int i = 0; i < MaxSzie; i++)
{
a[i] = null;
m_Length = 0;
}
}
template<class T>
IndirectList<T>::IndirectList(T b[], int n)
{
if (n > MaxSzie)
{
throw("溢出");
}
first = new Node<T>;
first->next = NULL;
for (int i = n-1; i>=0; i--)
{
Node<T> *s = new Node<T>;
s->data = b[i];
s->next = first->next;
first->next = s;
}
m_Length = n;
Node<T> *p = first; //临时指针
for (int i = 0; i < m_Length; i++)
{
p = p->next;
a[i] = p; //将指针地址存入数据
}
}
template<class T>
IndirectList<T>::~IndirectList()
{
while (first != NULL)
{
Node<T> *q = first;
first = first->next;
delete q;
}
m_Length = 0;
}
template<class T>
int IndirectList<T>::Length()
{
return m_Length;
}
template<class T>
T IndirectList<T>::Get(int i)
{
if (i > m_Length || i < 1)
{
throw("错误!");
}
Node<T> *p = a[i - 1];
return p->data;
}
template<class T>
int IndirectList<T>::Locate(T x)
{
Node<T> *p = first->next;
int count = 1;
while (p != NULL)
{
if (p->data == x)
{
return count;
}
p = p->next;
count++;
}
return -1;
}
template<class T>
bool IndirectList<T>::Insert(int i, T x)
{
if (i > m_Length || i < 1)
{
return false;
}
Node<T> *p = first;
int count = 0;
while (p != NULL&& count<i-1)
{
p = p->next;
count++;
}
if (p == NULL)
{
return false;
}
Node<T> *s = new Node<T>;
s->data = x;
s->next = p->next;
p->next = s;
m_Length++;
for (int j = m_Length - 1; j >= i; j--)
{
a[j] = a[j - 1];
}
a[i] = s; //新地址
return true;
}
template<class T>
bool IndirectList<T>::Delete(int i)
{
if (i > m_Length || i < 1)
{
return false;
}
Node<T> *p = first;
int count = 0;
while (p != NULL&& count<i - 1)
{
p = p->next;
count++;
}
if (p == NULL)
{
return false;
}
Node<T> *q;
q = p->next;
p->next = q->next;
delete q;
m_Length--;
for (int j = i; j <= m_Length; j++)
{
a[j - 1] = a[j];
}
return true;
}
template<class T>
bool IndirectList<T>::InsertHead(T x)
{
if (m_Length > MaxSzie)
return false;
Node<T> *s = new Node<T>;
if (s == NULL)
{
return false;
}
s->data = x;
s->next = first->next;
first->next = s;
m_Length++;
for (int i = m_Length - 1; i > 0; i--)
{
a[i] = a[i - 1];
}
a[0] = first->next;
return true;
}
template<class T>
bool IndirectList<T>::InsertTail(T x)
{
if (m_Length > MaxSzie)
return false;
Node<T> *p = first;
Node<T> *s = new Node<T>;
if (s == NULL)
{
return false;
}
while (p->next != NULL)
{
p = p->next;
}
s->data = x;
p->next = s;
s->next = NULL;
m_Length++;
a[m_Length - 1] = s;
return true;
}
template<class T>
void IndirectList<T>::ListTraverse()
{
Node<T> *p = first->next;
while (p != NULL)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
template<class T>
bool IndirectList<T>::changeList(int i, T x)
{
if (i > m_Length || i < 1)
return false;
Node<T> *p = a[i - 1];
p->data = x;
return true;
}
//源.cpp
#include"IndirectList.h"
#include<string>
#include<iostream>
using namespace std;
int main(void)
{
float score[5] = { 100,94.5,88.5,77.5,64 };
IndirectList<float> l1(score, 5);
l1.ListTraverse();
cout << "-----------------------------------------------" << endl;
cout << "第二个成绩为:" << l1.Get(2) << endl;
l1.Insert(3, 90);
l1.ListTraverse();
cout << "-----------------------------------------------" << endl;
cout << "成绩为77.5所在的位置为:" << l1.Locate(77.5) << endl;
l1.InsertHead(100);
l1.InsertTail(55.5);
l1.ListTraverse();
cout << "-----------------------------------------------" << endl;
cout << "成绩链长度为:" << l1.Length() << endl;
l1.changeList(2, 99);
l1.Delete(8);
l1.ListTraverse();
cout << "-----------------------------------------------" << endl;
system("pause");
return 0;
}
实验结果如下图:
一一验证,发现正确。
四、实验心得
间接寻址这次实验也是耗费了我许多的时间,主要是由于自己对间接寻址的原理不够了解,不能准确把握如何将数组和指针结合在一起,最终通过上网搜索才理解间接寻址的完整过程,在实验过程中,发现间接寻址的获取位置相应成绩的Get函数十分方便,同时在插入和删除操作的时间性能上也得到了改进。这次对间接寻址有了初步的了解及真正对其的实验操作,但以后还是要多加练习,毕竟这是之前困扰了自己很久的一个存储方式,而且课本讲解到的此方面也都是概念性的,可能是自己上课没能真正理解老师的思路,希望自己以后能做到更好。
本文通过建立学生成绩的顺序表和双向链表,介绍了如何利用间接寻址进行数据的插入、删除和查找操作。实验过程中,作者深入理解了间接寻址的原理,体验到了其在提高操作效率上的优势,并认识到需要进一步加强练习以巩固这一技能。
130





