数据结构【第三天】:线性表(二)

静态链表

用数组描述的链表

图转自网络

存储结构

#define MAXSIZE 1000    //即该链表最大长度为1000
typedef struct
{
    ElemType data;    //数据部分
    int cur;    //游标,为0时表示无指向
}Componet,StaticLinkList[MAXSIZE];    

初始化

Status InitList(StaticLinkList space)
{
    int i;
    for(i=0;i<MAXSIZE-1;i++);      //将游标序号从1开始依次排列到末尾-1处
        space[i].cur = i+1;
    space[MAXSIZE-1].cur = 0;     //将末尾游标置0,即当前链表为空
    return ok;
}

插入(插入到第i个节点前)

//获取备用链表在数组中的位置
int Malloc_SLL(StatixLinkList space)
{
    int i = space[0].cur;    //当前数组第一个节点的cur存的值
    if(space[0].cur)         //第一个值不为0
        space[0].cur = space[i].cur;    //更新备用链表的位置,即改变第一个节点的游标值
    return i;
}

//在L中第i个元素之前插入新的数据元素e
Status ListInsert(StaticLinkList L,int i,ElemType e)
{
    int i,k,l;
    k = MAXSIZE -1;    //获得数组最后一个节点的位置
    if(i<1 || i>ListLength(L)+1)
        return error;        //i小于1或者大于数组个数,则返回错误
    j = Malloc_SLL(L);       //获取备用节点在数组中的位置
    if(j)                    //若该位置不为0
    {
        L(j).data = e;       //备用节点数据部分赋值
        for(l=1 ; l<=i-1 ; l++)    //循环遍历前i-1个数据,找到第i-1个节点在数组中的位置
        {
            K = L(K).cur;    //将该位置赋值给k
        }
        L(j).cur = L(k).cur;    //把原本第i个节点在数组中的位置,现在给到新的节点的游标
        L(k).cur = j;           //第i-1个节点现在的游标值指向新节点在数组中的位置j
        return ok;
    }
    return error;
}

删除(删除L中第i个元素e)

//将在数组中位置为k的空闲节点回收到备用链表
void Free_SSL(StaticLinkList space,int k)
{
    space[k].cur = space[0].cur;    //将当前备用地址赋给即将删除的节点的游标
    space[0].cur = k;               //更新备用节点地址设置为k
}

//删除第i个元素
Status ListDelete(StaticLinkList L,int i)
{
    int j,k;
    if(i<1||i>ListLength(L))    //i小于1或者超过最大长度
        return error;
    k = MAXSIZE-1;              //最后节点
    for(j = 1;j <= i-1;j++)     //遍历找到第i-1个节点的位置赋给k
    {
         k = L[k].cur       
    }
    j = L[k].cur;    //获得第i个节点在数组中的位置
    L[k].cur = L[j].cur    //将原本第i+1个节点的位置给原本第i-1个节点的游标
    Free_SSL(L,j);        //释放位置为j的节点
    return ok;
}

返回链表长度

int ListLength(StaticLinkList L)
{
    int j = 0;
    int i = L[MAXSIZE-1].cur;    //从尾节点处获得第一个数据节点的位置
    while(i)            //为0即到达最后一个数据节点
    {    
        i = L[i].cur;    //依次遍历到下一个节点
        j++;            //计数+1
    }
    return j;
}

优点:在插入和删除时只需要修改游标不需要移动数据

缺点:表长仍为固定值;失去了顺序存储结构的随机存取特性

用处:用于没有指针的高级语言设计的一种实现方法,不需要malloc和free函数


循环链表

将单链表中终端节点的指针端由空指针改为指向头结点,使整个单链表成为一个环,称为单循环链表,简称循环链表

区别(与单链表):单链表判断p->next是否为空,单循环链表判断p->next是否为头节点

优化:为了操作更加方便,可以增加一个尾指针指向最后一个节点,于是第一个数据节点即为rear->next->next

合并两个循环链表

p = rearA -> next;       //记录A的头节点
rearA -> next = rearB -> next -> next;    //将A的尾节点指向改成B的第一个数据节点
q = rearB -> next;                //保存B的头节点
rearB -> next = p;                //将B的尾节点指向A的头节点
free(q);                         //释放B的头节点

双向链表

在每个节点中存在两个指针域,分别指向前一个和后一个节点

//线性表双向链表存储结构
typedef struct DulNode
{
    ElemType data;
    struct DulNode *prior;   //前驱指针
    struct DulNode *next;    //后继指针
}DulNode, *DuLinkList;

插入操作(s插入到p后)

思想:先修改需要插入节点的前后指针指向,再修改原链表中的节点的指针指向

s-> prior = p;
s -> next = p -> next;
p - next ->prior = s;
p ->next = s;

删除操作(删除s)

思想:将p的前后端节点的指针相互连接,然后释放p

p->prior->next = p->next;
p->next->prior = p->prior;
free(p);

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值