C++数据结构之静态链表

声明:本文所有的字词如指针,指向,地址都不是真正意义上的指针与地址,只是为了方便理解与说明。

结点为结构体,与单链表相差无几,都有数据域和指针域,只不过单链表中的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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值