【二】线性表的链式存储结构

1、链式存储定义

为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外 ,还需要存储指示其直接后继的信息。

这里写图片描述

2、链式存储逻辑结构
n个结点链接成一个链式线性表的结构叫做链表,
当每个结点中只包含一个指针域时,叫做单链表。

这里写图片描述

3、链表的基本概念
表头结点
链表中的第一个结点,包含指向第一个数据元素的指针以及
链表自身的一些信息;
数据结点
链表中代表数据元素的结点,包含指向下一个数据元素的指
针和数据元素的信息;
尾结点
链表中的最后一个数据结点,其下一元素指针为空,表示无
后继元素;

4、单链表示例图
这里写图片描述

5、表头结点、数据结点 在C中的实现

表头结点:

/*
LinklistNode 为一个结构体,里面只包含一个指针,用于指向下一个元素
*/
typedef struct _struct_linklist
{
  LinklistNode header;
  int length;
}TLinklist;
/*LinklistNode 定义*/
typedef struct _struct_linklistnode LinklistNode;
struct _struct_linklistnode
{
  LinklistNode *next;
};

数据结点:

typedef struct _struct_value
{
/*LinklistNode 结点用于保存下一个元素地址信息*/
  LinklistNode node;
  int value;
}Value;

6、插入元素操作

/*
该方法用于向一个线性表list的pos位置处插入新元素node
返回值为1表示插入成功,0表示插入失败
pos表示插入的位置,从0开始计数
*/
int List_Insert(Linklist* list, LinklistNode* node, int pos)
{
  int iret = 1;
  TLinklist *tlist = (TLinklist*)list;
  iret = iret && (list != NULL) && (node != NULL) && (pos >= 0);
  if(iret)
  {
  /*
  判断插入的位置是否已经大于了当前链表长度,如果是,则修正插入位置为链表最后
  可用本代码替换:pos = pos > tlist->length ? tlist->length:pos;
  */
    if(pos > tlist->length)
    {
      pos = tlist->length;
    }
    /*current 指向了头结点的LinklistNode 成员*/
    LinklistNode *current = (LinklistNode*)tlist;
    for(int i = 0; (i<pos) && (current->next != NULL); i++)
    {
      current = current->next;
    }
    //插入元素
    node->next = current->next;
    current->next = node;
    //改变链表长度
    tlist->length++;
  }
  return iret;
}

7、删除元素操作

/*
该方法用于删除一个线性表list的pos位置处的元素
返回值为被删除的元素,NULL表示删除失败
*/
LinklistNode* List_Delete(Linklist* list, int pos)
{
  LinklistNode *node = NULL;
  TLinklist *tlist = (TLinklist*)list;
  if(tlist != NULL)
  {
  /*确保要删除的位置合法*/
    if((pos>=0)&&(pos < tlist->length))
    {
    /*current指向了头结点的LinklistNode成员*/
      LinklistNode *current = (LinklistNode*)tlist;
      for(int i = 0; (i<pos)&&(current->next != NULL);i++)
      {
        current = current->next;
      }
      /*删除元素*/
      node = current->next;
      current->next = node->next;
      /*改变被删除元素的next指针值*/
      node->next = NULL;
      //改变元素个数
      tlist->length--;
    }
  }
  return node;
}

8、获取元素操作

/*
该方法用于获取一个线性表list的pos位置处的元素
返回值为pos位置处的元素,NULL表示获取失败
*/
LinklistNode* List_Get(Linklist* list, int pos)
{
  LinklistNode *node = NULL;
  TLinklist *tlist = (TLinklist*)list;
  if(tlist != NULL)
  {
    /*判断位置是否合法*/
    if((pos>=0) && (pos < tlist->length))
    {
    /*node指向了头结点的LinklistNode成员*/
       node = (LinklistNode*)tlist;
    /*当移动pos-1次后,node指向了要获取结点的前一个结点,而实际要获取的结点是当前结点的next,所以这里循环条件设置为i<=pos
    */
      for(int i = 0; (i <= pos) &&(node->next != NULL);i++)
      {
        node = node->next;
      }
    }
  }
  return node;
}

9、完整源码下载

文件名:linklist-1.0.tar.gz
链接: http://pan.baidu.com/s/1hqjFjJu 密码: xhn8

文件名:linklist-1.1.tar.gz
链接: http://pan.baidu.com/s/1c0q92Bu 密码: stag
说明:次版本修复List_Get()函数,在链表为空是返回了链表头地址,新的实现如上所示!

编译步骤:
0.1 解压缩:tar -zxvf linklist-1.1.tar.gz
0.2 进入目录:./configure
0.3 生成Seqlist:make
0.4 运行程序:./Linklist

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值