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

来源:互联网 发布:淘宝运营师培训 怎么考 编辑:程序博客网 时间:2024/05/24 01:51

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