静态链表的抽象数据类型
ADT 线性表(List)
Data
线性表的数据对象集合为{a1,a2,…,an},每个元素的类型均为DataType。其中,除了第一个元素a1外,
每个元素有且只有一个直接的前驱,除了最后一个元素,每个元素有且只有一个直接后继元素。数据
元素之间的关系是一对一的关系。
Operator
InitList(*L):初始化操作,建立一个空的线性表L
ListEmpty(L):若线性表为空,返回true,否则返回false
ClearList(*L):将线性表清空
GetElem(L,I,*e):将线性表L中第i个位置元素值返回给e
LocateElem(L,e):在线性表L中查找与给定值e相等的元素;查找成功,返回该元素在表中序号表示成功,
否则返回0表示失败,
ListInsert(*L,i,e):在线性表中的第i个位置插入新元素e
ListDelet(*L,i,*e):删除线性表L中第i个位置元素,并用e返回其值
ListLength(L):返回线性表L的元素个数
(1)数组第一个元素的cur用来存储备用链表第一个结点的下标
(2)数组最后一个元素的cur用来存放第一个插入元素的下标,相当于头指针
.hpp
#ifndef TEST_H_
#define TEST_H_
#define MAXSIZE 1000
typedef int ElemType;
typedef struct
{
ElemType data;
int cur;//相当于单链表中的指针,存放该元素的后继在数组中的下标
}Component,StaticLinkList[MAXSIZE];
//InitList(*L):初始化操作,建立一个空的线性表L
bool initList(StaticLinkList L);
//ListEmpty(L):若线性表为空,返回true,否则返回false
bool listEmpty(const StaticLinkList L);
//ListLength(L):返回线性表L的元素个数
int listLength(const StaticLinkList L);
//GetElem(L,I,*e):将线性表L中第i个位置元素值返回给e
void getElem(const StaticLinkList L, const int i, ElemType * e);
//LocateElem(L,e):在线性表L中查找与给定值e相等的元素;查找成功,返回该元素在表中序号表示成功,否则返回0表示失败
bool locateElem(const StaticLinkList L, const ElemType e);
//若备用空间链表非空,则返回分配的结点下标,否则返回0
int Malloc_SLL(StaticLinkList L);
//ListInsert(*L,i,e):在线性表中的第i个位置插入新元素e
bool listInsert(StaticLinkList L, const int i, const ElemType e);
//将下标为k的空闲界定啊回收到备用链表
void Free_SSL(StaticLinkList L, const int k);
//ListDelet(*L,i,*e):删除线性表L中第i个位置元素,并用e返回其值
bool listDelete(StaticLinkList L, const int i);
#endif // !TEST_H_
#pragma once
.cpp
#include"test.h"
//InitList(*L):初始化操作,建立一个空的线性表L
bool initList(StaticLinkList L) {
for (int i = 0; i < MAXSIZE - 1; i++)
L[i].cur = i + 1;
L[MAXSIZE - 1].cur = 0;
return true;
}
//ListEmpty(L):若线性表为空,返回true,否则返回false
bool listEmpty(const StaticLinkList L) {
if (L[MAXSIZE - 1].cur == 0)
return true;
else
return false;
}
//ListLength(L):返回线性表L的元素个数
int listLength(const StaticLinkList L) {
int j = 0;
int i = L[MAXSIZE - 1].cur;//获取最后一个元素的cur:该下标存放第一个插入元素的下标
while (i)
{
i = L[i].cur;
j++;
}
return j;
}
//GetElem(L,I,*e):将线性表L中第i个位置元素值返回给e
void getElem(const StaticLinkList L, const int i, ElemType * e) {
int j = L[MAXSIZE - 1].cur;
int length = listLength(L);
while (length)
{
j = L[j].cur;
if (j == i)
{
*e = L[j].data;
break;
}
--length;
}
}
//LocateElem(L,e):在线性表L中查找与给定值e相等的元素;查找成功,返回该元素在表中序号表示成功,否则返回0表示失败
bool locateElem(const StaticLinkList L, const ElemType e) {
int j = L[MAXSIZE - 1].cur;
int length = listLength(L);
while (length)
{
j = L[j].cur;
if (L[j].data == e)
return true;
--length;
}
return false;
}
//ListInsert(*L,i,e):在线性表中的第i个位置插入新元素e
//为了辨明数组中那些分量未被使用,解决办法是:将所有未被使用的及已被删除的分量用游标链成
//一个备用链表,每当进行插入时,便可以从备用链表上取得第一个结点作为待插入的新结点
//若备用空间链表非空,则返回分配的结点下标,否则返回0
int Malloc_SLL(StaticLinkList L) {
int i = L[0].cur;//当前数组第一个元素的cur值,就是要返回的第一个备用空闲的下标
if (L[0].cur)
L[0].cur = L[i].cur;//由于要拿出一个分量来使用了,所以我们就得把它的下一个分量用来备用
return i;
}
bool listInsert(StaticLinkList L, const int i, const ElemType e) {
int k = MAXSIZE - 1;
if (i < 1 || i > listLength(L) + 1)
return false;
int j = Malloc_SLL(L);
if (j)
{
L[j].data = e;
for (int l = 1; l <= i - 1; l++)
k = L[k].cur;
L[j].cur = L[k].cur;
L[k].cur = j;
return true;
}
return false;
}
//将下标为k的空闲界定啊回收到备用链表
void Free_SSL(StaticLinkList L, const int k) {
//把第一个元素cur值赋给要删除分量cur
L[k].cur = L[0].cur;
//把要删除的分量下标赋值给第一个元素的cur
L[0].cur = k;
}
//ListDelet(*L,i,*e):删除线性表L中第i个位置元素,并用e返回其值
bool listDelete(StaticLinkList L, const int i) {
if (i < 1 || i > listLength(L) + 1)
return false;
int k = MAXSIZE - 1;
int j;
for (j = 0; j < i - 1; j++)
k = L[k].cur;
j = L[k].cur;
L[k].cur = L[j].cur;
Free_SSL(L, j);
return true;
}
main
#include<iostream>
#include"test.h"
void showList(const StaticLinkList & l);
int main()
{
StaticLinkList L{};
initList(L);
std::cout<<listEmpty(L)<<std::endl;
listInsert(L, 0, 1);
listInsert(L, 1, 2);
listInsert(L, 2, 3);
listInsert(L, 3, 4);
listInsert(L, 4, 5);
listInsert(L, 5, 6);
std::cout << listEmpty(L) << std::endl;
showList(L);
listDelete(L, 3);
showList(L);
return 0;
}
void showList(const StaticLinkList & L) {
int j = L[MAXSIZE - 1].cur;
int length = listLength(L);
while (length)
{
std::cout << L[j].data <<" ";
j = L[j].cur;
--length;
}
std::cout << std::endl;
}
运行结果