声明:本文所有的字词如指针,指向,地址都不是真正意义上的指针与地址,只是为了方便理解与说明。
结点为结构体,与单链表相差无几,都有数据域和指针域,只不过单链表中的next是真的指针,指向内存地址,而静态链表中的next则指向下一个元素在数组中的下标
struct Node{
int date;
int next;
};
class SList{
private:
int head;//非空表的第一个下标
int avail;//空链表的首下标
int length;
Node *SA;//链表的首地址
public:
SList(int N);
~SList();
int Insert(int L,int Elem);
int Delete(int L);
void Display();
int GetElem(int L);
bool IsEmpty();
void Locate(int Elem);
int Length();
};
1.构造函数
new一个很大的数组,输入N个元素,并把next赋值为下一个元素的下标(数组中的所有next都要初始化),在非空表的最后设置结束标志,next不指向任何下标,赋值为-1,初始化非空表和空闲表的头指针
SList::SList(int N)
{
SA=new Node[MaxSize];
cout<<"请输入"<<N<<"个数据:"<<endl;
for (int i=0;i<N;i++)
{
cin>>SA[i].date;
if (i!=N-1)
SA[i].next=i+1;
else
SA[i].next=-1;//非空表最后一个元素设置结束标志
}
for (int i=N;i<MaxSize;i++)
{
if (i!=MaxSize-1)
SA[i].next=i+1;
else
SA[i].next=-1;
}
length=N;
head=0;
avail=N;
}
2.插入结点
①判断插入位置是否合法
②获取插入地址,赋值,然后把空闲表的头指针移到下一位
③把新结点加入到链表中,即修改next的值。
如果插到链表第一位,则新结点的next指向原来的头结点(即head),然后head再修改为新结点的下标
如果插入到链表中间或结尾,找到原位的上一位,新结点的next指向上一位的next,上一位的next修改为新结点的下标。假设插入到L位上,则找到L-1的下标,也就是(L-2)->next,然后新结点的next=((L-2)->next)->next,((L-2)->next)->next=新结点的下标
④长度加一
int SList::Insert(int L,int Elem)
{
if (L<1||L>length+1)//length+1是最后一个元素的下一位
{
cout<<"位置不合法"<<endl;
return -1;
}
int i=head,j=1;
int m=avail;//获取新元素的地址
avail=SA[avail].next;//空链表移到下一位
SA[m].date=Elem;//存放数据
//如果插入到第一位,则插入元素的next指向原来的head,原来的head改为新元素的下标
if (L==1)
{
SA[m].next=head;
head=m;
}
else
{
for (;j<L-1;j++)
i=SA[i].next;//找到插入位置的上一位
SA[m].next=SA[i].next;//新元素的next指向上一位的next
SA[i].next=m;//上一位的next指向新元素
}
length++;
return 0;
}
3.删除结点
①判断位置的合法性
②如果删掉第一位,取值,把第一位加到空闲表中,head指向原来的head的下一位。
③如果删掉其它结点,找到被删除结点的上一位,获取被删除结点的下标(即上一位的next),取值,上一位的next改为被删除结点的next,把被删除结点加到空闲表中
④长度减一,返回该结点的值
int SList::Delete(int L)
{
int temp;
if (L<1||L>length)
{
cout<<"位置不合法"<<endl;
return -1;
}
int i=head;
int j,m;
if (L==1)
{
temp=SA[head].date;//取值
int t=head;
head=SA[head].next;//链表头指向下一位的下标
SA[t].next=avail;//被删除结点的next指向加到空链上
avail=t;//先取出被删除结点的下标
}
else
{
for (j=1;j<L-1;j++)
i=SA[i].next;//找到被删除元素的上一位
m=SA[i].next;//获取被删除元素在数组中的下标
temp=SA[m].date;//取值
SA[i].next=SA[m].next;//上一位的next改为被删除元素的next
SA[m].next=avail;//把被删除元素的位置加到空链表中
avail=m;//空链表的首地址改为被删除元素的下标
}
length--;
return temp;
}
析构函数
SList::~SList()
{
delete SA;
}
定位
void SList::Locate(int Elem)
{
int i=head;
int j=1;
while (i!=-1&&SA[i].date!=Elem)//不是表尾且不等于Elem时
{
i=SA[i].next;
j++;
}
if (i!=-1)
cout<<"在数组中的下标是"<<i<<",在链表中的位置是"<<j<<endl;
else
cout<<"不存在此数据"<<endl;
}
取值
int SList::GetElem(int L)
{
int i=head;
for(int j=0;j<L-1;j++)
i=SA[i].next;
return SA[i].date;
}