静态链表

静态链表即使用一维数组描述的线性表,这种描述方式便于在不设“指针”类型的高级程序设计语言中使用链表结构。
其存储形式为
/*线性表的静态单链表存储结构*/
typedef struct _STATICLIST_
{
    ElemType data;//数据
    int cursor;//游标
}Component,StaticList[MAX_SIZE];
其中data表示节点的数据域,而cursor则是游标,用来指示下一个节点的地址。一般第一个节点的数据域为空,游标指向首节点。


跟单链表的区别是,我们需要自己实现malloc和free函数。为了辨别数组中哪些分量未被使用,解决的办法是将所有未被使用过以及被删除的分量用游标链接成一个 备用链表,每当进行插入时便可从备用链表中取得第一个节点作为待插入的新节点。反之,在删除时将从链表中删除下来的节点链接到备用链表上。
备用链表初始化:
void InitSpace_SL(StaticList &space)
{
    for(int i = 0; i < MAX_SIZE - 1; i++)
    {
        space[i].cursor = i+1;
    }
    space[MAX_SIZE - 1].cursor = 0;
}
Malloc函数实现:
int Malloc_SL(StaticList &space)
{
    int i = space[0].cursor;
    if(i)//备用链表非空
    {
        space[0].cursor = space[i].cursor;
    }
    return i;
}
free函数实现:
void Free_SL(StaticList &space,int i)
{
    //将下标为i的节点回收,放回备用链表
    space[i].cursor = space[0].cursor;
    space[0].cursor = i;
}
在内存中的存储形态如图所示:
标准实现源代码:
/***********************************************
    静态链表的实现
    by Rowandjj
    date 2014/3/28
***********************************************/
#include<iostream>
using namespace std;

#define MAX_SIZE 1000//静态链表最大长度

typedef int ElemType;
#define OK 1;
#define ERROR 0;
/*线性表的静态单链表存储结构*/
typedef struct _STATICLIST_
{
    ElemType data;//数据
    int cursor;//游标
}Component,StaticList[MAX_SIZE];

/*操作声明*/
void InitSpace_SL(StaticList&);//初始化备用链表
int Malloc_SL(StaticList&);//从备用链表上申请一个节点,成功则返会节点位置,否则返回0
void Free_SL(StaticList&,int);//释放指定位置的节点,并放回备用链表中
/
int InitList_SL(StaticList&);//初始化静态链表,
int ListLength_SL(StaticList&,int);//获取链表长度
int ListInsert_SL(StaticList&,int,int,ElemType);//插入节点
int ListDelete_SL(StaticList&,int,int,ElemType&);//删除节点
int ClearList_SL(StaticList&,int);//将静态链表重置,全部放回到备用链表上
int ListEmpty_SL(StaticList&,int);// 判断L中表头位序为n的链表是否空,若是空则是空表返回1;否则返回0  
int GetElem_SL(StaticList&,int,int,ElemType&);//获取特定位置上的节点的值
int LocateElem_SL(StaticList&,int,ElemType);//在静态链表中查找给定元素位置

int ListTraverse_SL(StaticList &L,int n,void(*vi)(ElemType));//遍历静态链表
void visit(ElemType);

/*具体实现*/
void InitSpace_SL(StaticList &space)
{
    for(int i = 0; i < MAX_SIZE - 1; i++)
    {
        space[i].cursor = i+1;
    }
    space[MAX_SIZE - 1].cursor = 0;
}
int Malloc_SL(StaticList &space)
{
    int i = space[0].cursor;
    if(i)//备用链表非空
    {
        space[0].cursor = space[i].cursor;
    }
    return i;
}
void Free_SL(StaticList &space,int i)
{
    //将下标为i的节点回收,放回备用链表
    space[i].cursor = space[0].cursor;
    space[0].cursor = i;
}

int InitList_SL(StaticList &L)
{
    // 构造一个空链表,返回值为空表在数组中的位序   
    int i = Malloc_SL(L);//从备用链表中获取一个节点
    L[i].cursor = 0;//指针域为0
    return OK;
}
int ListLength_SL(StaticList &L,int i)
{
    int j = L[i].cursor;
    int num = 0;
    while(j)
    {
        j = L[j].cursor;
        num++;
    }
    return num;
}
int ListInsert_SL(StaticList &L,int n,int i,ElemType e)
{
    // 在L中表头位序为n的链表的第i个元素之前插入新的数据元素e 
    //L代表备用链表,n代表当前链表的表头下标,i代表待插入的位置,e代表插入元素值
    int j,p = n;
    if(i<1 || i>ListLength_SL(L,n)+1)
    {
        return ERROR;
    }
    j = Malloc_SL(L);
    if(j)//节点申请成功
    {
        L[j].data = e;
        for(int m = 1; m < i;m++)//移到待插入位置的前一个位置
        {
            p = L[p].cursor;
        }
        //插入节点
        L[j].cursor = L[p].cursor;
        L[p].cursor = j;
        return OK;
    }
    return ERROR;
}
int ListDelete_SL(StaticList &L,int n,int i,ElemType &e)
{
    // 删除在L中表头位序为n的链表的第i个数据元素e,并返回其值
    if(i < 1 || i > ListLength_SL(L,n))
    {
        return ERROR;
    }
    int p = n;
    for(int m = 1; m < i;m++)//移到待删节点的前一个节点
    {
        p = L[p].cursor;
    }
    int q = L[p].cursor;
    e = L[q].data;
    L[p].cursor = L[q].cursor;
    Free_SL(L,q);
    
    return OK;
}
int ClearList_SL(StaticList &L,int n)//重置链表
{
    // 将此表重置为空表,即将这个链表转化为备用表的一部分  
    int p = L[n].cursor;//p指向当前链表的首节点
    L[n].cursor = 0;//将链表置空
    int k = L[0].cursor;//k指向备用链表首节点
    L[0].cursor = p;//将当前链表首节点备用链表头节点后
    while(L[p].cursor)
    {
        p = L[p].cursor;
    }
    L[p].cursor = k;//将备用链表首节点接到当前链表尾巴上
    return OK;
}
int ListEmpty_SL(StaticList &L,int n)// 判断L中表头位序为n的链表是否空,若是空则是空表返回1;否则返回0 
{
    return !L[n].cursor;//==0,true
}
int GetElem_SL(StaticList &L,int n,int i,ElemType &e)//用e返回L中表头位序为n的链表的第i个元素的值  
{
    int j,p = n;
    if(i < 1 || i > ListLength_SL(L,n))
    {
        return ERROR;
    }
    for(j = 1; j <= i;j++)
    {
        p = L[p].cursor;
    }
    e = L[p].data;
    return OK;
}
int LocateElem_SL(StaticList &L,int n,ElemType e)
{
    // 在L中表头位序为n的静态单链表中查找第1个值为e的元素。   
    // 若找到,则返回它在静态链表中的位序(而不是L的位序) 
    int p = L[n].cursor;
    int i = 1;
    while(p && L[p].data!=e)
    {
        p = L[p].cursor;
        i++;
    }
    return i;
}
int ListTraverse_SL(StaticList &L,int n,void(*vi)(ElemType))//遍历
{
    int p = L[n].cursor;
    while(p)
    {
        vi(L[p].data);
        p = L[p].cursor;
    }
    cout<<endl;
    return OK;
}
void visit(ElemType e)
{
    cout<<e<<" ";
}
部分测试代码:
int main(void)
{
    StaticList L;
    InitSpace_SL(L);//初始化备用链表
    int la = InitList_SL(L);//初始化静态链表,返回头节点位序
    int i,m = 0;
    int index;
    ElemType e;
    cin>>i;
    for(int j = 0; j < i;j++)
    {
        cin>>e;
        cin>>index;
        ListInsert_SL(L,la,index,e);
    }
    cout<<"traverse:";
    ListTraverse_SL(L,la,visit);
    cout<<"len:"<<ListLength_SL(L,la)<<endl;
    cout<<ListEmpty_SL(L,la)<<endl;
    while(m != -1)
    {    
        cin>>m;
        ListDelete_SL(L,la,m,e);
        cout<<"*****************"<<endl;
        cout<<"del :"<<e<<endl;
        ListTraverse_SL(L,la,visit);
        cout<<"len:"<<ListLength_SL(L,la)<<endl;
        cout<<"*****************"<<endl;
        cout<<ListEmpty_SL(L,la)<<endl;
    }
/*    while(m != -2)
    {
        cin>>m;
        GetElem_SL(L,la,m,e);
        cout<<"get elem :"<<e<<endl;
    }*/
    while(m != -3)
    {
        cin>>m;
        e = LocateElem_SL(L,la,m);
        cout<<"get elem :"<<e<<endl;
    }
/*    cout<<"已经清除链表..."<<endl;
    ClearList_SL(L,la);
    ListTraverse_SL(L,la,visit);
    cout<<"len:"<<ListLength_SL(L,la)<<endl;

        cin>>i;
    for( j = 0; j < i;j++)
    {
        cin>>e;
        cin>>index;
        ListInsert_SL(L,la,index,e);
    }
    cout<<"traverse:";
    ListTraverse_SL(L,la,visit);
    cout<<"len:"<<ListLength_SL(L,la)<<endl;

    while(m != -2)
    {    
        cin>>m;
        ListDelete_SL(L,la,m,e);
        cout<<"*****************"<<endl;
        cout<<"del :"<<e<<endl;
        ListTraverse_SL(L,la,visit);
        cout<<"len:"<<ListLength_SL(L,la)<<endl;
        cout<<"*****************"<<endl;
    }
    */
    return 0;
}





  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
静态链表是一种使用数组实现的链表结构,它通过数组中的元素来模拟链表中的节点,并使用一个特殊的指针(游标)来表示节点之间的逻辑关系。静态链表的优点是实现简单,不需要频繁地申请和释放内存空间,但缺点是插入和删除操作比较麻烦,需要手动维护游标指针。 以下是一个简单的Python静态链表的实现示例[^1]: ```python class StaticLinkedList: def __init__(self, size): self.data = [None] * size # 存储数据的数组 self.next = [i + 1 for i in range(size)] # 游标数组,用于维护节点之间的逻辑关系 self.next[-1] = -1 # 最后一个元素的游标为-1,表示链表的末尾 self.head = -1 # 头指针,指向链表的第一个节点 def is_empty(self): return self.head == -1 def is_full(self): return self.next == -1 def insert(self, value): if self.is_full(): print("StaticLinkedList is full") return new_node = self.next # 获取一个空闲节点 self.next = self.next[new_node] # 更新空闲节点的游标 self.data[new_node] = value # 在空闲节点中存储数据 if self.is_empty(): self.head = new_node self.next[new_node] = -1 else: current = self.head while self.next[current] != -1: current = self.next[current] self.next[current] = new_node self.next[new_node] = -1 def delete(self, value): if self.is_empty(): print("StaticLinkedList is empty") return prev = -1 current = self.head while current != -1: if self.data[current] == value: break prev = current current = self.next[current] if current == -1: print("Value not found") return if prev == -1: self.head = self.next[current] else: self.next[prev] = self.next[current] self.next[current] = self.next # 将删除的节点加入空闲节点链表 self.next = current def display(self): if self.is_empty(): print("StaticLinkedList is empty") return current = self.head while current != -1: print(self.data[current], end=" ") current = self.next[current] print() # 创建一个容量为5的静态链表 static_list = StaticLinkedList(5) # 插入数据 static_list.insert(1) static_list.insert(2) static_list.insert(3) # 删除数据 static_list.delete(2) # 显示链表中的数据 static_list.display() ``` 输出结果为: ``` 1 3 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值