数据结构(面向对象方法与C++语言描述)(第2版)静态链表内容整理
静态链表
如果为数组中每一个元素附加一个链接指针,就形成静态链表结构。它允许我们不改变各元素的物理位置,只要重新链接就能够改变这些元素的逻辑顺序。由于它是利用数组定义的,在整个运算过程中存储空间的大小不会变化,因此称之为静态链表。
静态链表的每个结点由两个数据成员构成:data域存储数据,link域存放链接指针。所有结点形成一个结点数组,它也可以附加头结点。
图示静态链表的存放数组为A,则链表的附加头结点在A[0],从A[1]起,后面都是链表结点的存放控件,链接指针用数组元素的下标(序号)表示。A[0].link给出链表第一个结点的位置,例如1,一次吧相应数组A[1]取出,通过A[1].link可以找到它的下一个结点位置。当找到某一结点A[k],A[k].link = -1,则链表终止。由于A[0]有效,所以空指针NULL用-1表示。
序号 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
data | 10 | 30 | 40 | 60 | 70 | 50 | 20 | |
link | 1 | 7 | 3 | 6 | 5 | -1 | 4 | 2 |
代码实现:
环境:vs2019
头文件:StaticList.h
源文件:main.cpp
StaticList.h代码:
#pragma once
#include <iostream>
using std::cout;
using std::endl;
const int maxSize = 100; //静态链表大小
template<typename T>
struct SLinkNode {
T data; //结点数据
int link; //结点链接指针
};
template<class T>
class StaticList {
private:
SLinkNode<T> elem[maxSize];
int avil; //当前可分配空间首地址
public:
void InitList();
int Length(); //计算静态链表的长度
int Search(T x); //在静态链表中查找具有给定值的结点
int Locate(int i); //在静态链表中查找第i个结点
bool Append(T x); //在静态链表的表尾追加一个新结点
bool Insert(int i, T x); //在静态链表第i个结点后插入新结点
bool Remove(int i); //在静态链表中释放第i个结点
bool IsEmpty(); //判链表空否?
void output();
};
template<class T>
inline void StaticList<T>::InitList()
{
//将链表空间初始化。
elem[0].link = -1;
avil = 1;
//当前可分配空间从 1 开始建立带头结点的空链表
for (int i = 1; i < maxSize - 1; i++)
{
elem[i].link = i + 1; //构成空闲链接表
}
elem[maxSize - 1].link = -1; //链表收尾
}
template<class T>
inline int StaticList<T>::Length()
{
//计算静态链表的长度
int p = elem[0].link;
int i = 0;
while (p != -1)
{
p = elem[p].link;
i++;
}
return i;
}
template<class T>
inline int StaticList<T>::Search(T x)
{
//在静态链表中查找具有给定值的结点。
int p = elem[0].link; //指针p指向链表第一个结点
while (p != -1)
if (elem[p].data == x) break;
else p = elem[p].link;
return p;
}
template<class T>
inline int StaticList<T>::Locate(int i)
{
//在静态链表中查找第i个结点
if (i < 0) return -1; //参数不合理
if (i == 0) return 0;
int j = 1, p = elem[0].link;
while (p != -1 && j < i) //循环查找第i号结点
{
p = elem[p].link;
j++;
}
return p;
}
template<class T>
inline bool StaticList<T>::Append(T x)
{
//在静态链表的表尾追加一个新结点
if (avil == -1) return false; //追加失败
int q = avil;
avil = elem[avil].link;
elem[q].data = x;
elem[q].link = -1;
int p = 0;
while (elem[p].link != -1)
p = elem[p].link;
elem[p].link = q; //追加
return true;
}
template<class T>
inline bool StaticList<T>::Insert(int i, T x)
{
//在静态链表第i个结点后面插入新结点。
int p = Locate(i);
if (p == -1) return false; //找不到结点
int q = avil;
avil = elem[avil].link;
elem[q].data = x;
elem[q].link = elem[p].link; //链入
elem[p].link = q;
return true;
}
template<class T>
inline bool StaticList<T>::Remove(int i)
{
//在静态链表中释放第i个结点。
int p = Locate(i - 1);
if (p == -1) return false; //找不到结点
int q = elem[p].link; //第i号节点
elem[p].link = elem[q].link;
elem[q].link = avil; //释放
avil = q;
return true;
}
template<class T>
inline bool StaticList<T>::IsEmpty()
{
//判链表空否?
if (elem[0].link == -1) return true;
else return true;
}
template<class T>
inline void StaticList<T>::output()
{
int p = elem[0].link;
while (p != -1)
{
cout << elem[p].data << " ";
p = elem[p].link;
}
cout << endl;
}
main.cpp代码:
#include "StaticList.h"
int main()
{
StaticList<int> L;
L.InitList();
for (int i = 0; i < 10; i++)
{
L.Append(10 * i);
}
cout << "新建的静态链表中元素为:" << endl;
L.output();
L.Remove(2);
cout << "静态链表释放第2个结点,当前元素为:" << endl;
L.output();
L.Insert(3, 33);
cout << "静态链表在第3个结点后插入新结点,当前元素为:" << endl;
L.output();
return 0;
}
控制台界面: