【数据结构基础】线性表的链式存储结构--单链表

n个结点链结成一个链表,即为线性表的链式存储结构,因为此链表的每个结点中只包含一个指针域,所以叫做单链表。

 

线性表的单链表存储结构:

typedef struct Node
{
    ElemType data;
    struct Node *next;
}Node;
typedef struct Node *LinkList;  /* 定义LinkList */


 

单链表的读取

/* 初始条件:顺序线性表L已存在,1<=i<=ListLength(L) */
/* 操作结果:用e返回L中第i个数据元素的值 */
Status GetElem( LinkList L, int i, ElemType *e )
{
    int j;
    LinkList p;      /* 申明一个指针p */
    p = L->next;     /* 让p指向链表L的第一个结点 */
    j = 1;        /* j为计数器 */
    while( p && j < i )  /* p不为空且计数器j还没有等于i时,循环继续 */
    {
        p = p->next;    /* 让p指向下个结点 */
        ++j;
    }
    if( !p || j > i )
        return ERROR;        /* 第i个结点不存在 */
    *e = p->data;         /* 取第i个结点的数据 */
    return OK;  
}


单链表的插入

/* 初始条件:顺序线性表L已存在,1<=i<=ListLength(L) */
/* 操作结果:在L中第i个结点位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert( LinkList *L, int i,ElemType e )
{
    int j;
    LinkList p, s;
    p = *L;
    j = 1;
    while( p && j < i )       /* 寻找第i-1个结点 */
    {
        p = p->next;
        ++j;
    }
    if( !p || j > i )
        return ERROR;     /* 第i个结点不存在 */
    s = ( LinkList )malloc( sizeof( Node ) ); /* 生成新节点(C标准函数) */
    s->data = e;
    s->next = p->next;    /* 将p的后继结点赋值给s的后继 */
    p->next = s;   /* 将s赋值给p的后继 */
    return OK;
}


 

单链表的删除

/* 初始条件:顺序线性表L已存在,1<=i<=ListLength */
/* 操作结果:删除L的第i个结点,并用e返回其值,L的长度减1 */
Status ListDelete( LinkList *L, int i, ElemType *e )
{
    int j;
    LinkList p, q;
    p = *L;
    j = 1;
    while( p->next && j < i )    /* 遍历寻找第i-1个结点 */
    {
        p = p->next;
        ++j;
    }
    if( !( p->next ) || j > i )
        return ERROR;     /* 第i个结点不存在 */
    q = p->next;
    p->next = q->next;    /* 将q的后继赋值给p的后继 */
    *e = q->data;       /* 将q结点中的数据给e */
    free( q );        /* 让系统回收此结点,释放内存 */
    return OK;
}


单链表的整表创建(头插法):

/* 随机产生n个元素的值,建立带表头结点的单链线性表L(头插法) */
void CreateListHead( LinkList *L, int n )
{
    LinkList p;
    int i;
    srand( time( 0 ) );     /* 初始化随机数种子 */
    *L = ( LinkList )malloc( sizeof( Node ) );
    ( *L )->next = NULL;    /* 先建立一个带头结点的单链表 */
    for( i = 0; i < n; i++ )
    {
        p = ( LinkList )malloc( sizeof( Node ) );    /* 生成新结点 */
        p->data = rand() % 100 + 1;   /* 随机生成100以内的数字 */
        p->next = ( *L )->next;
        ( *L )->next = p;        /* 插入到表头 */
    }
}


单链表的整表创建(尾插法):

/* 随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法) */
void CreateListTail( LinkList *L, int n )
{
    LinkList p, r;
    int i;
    srand( time( 0 ) );     /* 初始化随机数种子 */
    *L = ( LinkList )malloc( sizeof( Node ) );   /* 为整个线性表  */
    r = *L;            /* r为指向尾部的结点 */
    for( i = 0; i < n; i++ )
    {
        p = ( Node * )malloc( sizeof( Node ) );    /* 生成新结点 */
        p->data = rand() % 100 + 1;   /* 随机生成100以内的数字 */
        r->next = p;               /* 将表尾终端结点的指针指向新结点 */
        r = p;                   /* 将当前的新结点定义为表尾终端结点 */
    }
    r->next = NULL;            /* 表示当前链表结束 */
}


 

单链表的整表删除:

/* 初始条件:顺序线性表L已存在 */
/* 操作结果:将L重置为空表 */
Status ClearList( LinkList *L )
{
    LinkList p, q;
    p = ( *L )->next;   /* p指向第一个结点 */
    while( p )
    {
        q = p->next;
        free( p );
        p = q;
    }
    ( *L )->next = NULL;     /* 头结点指针域为空 */
    return OK;
}

 

适用范围

1,需要频繁插入和删除

2,线性表中的元素个数变化较大或不知道有多大时

 

对比与顺序存储结构,优缺点

1,存储分配方式

顺序存储结构用一段连续的存储单元依次存储线性表的数据元素;

单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素。

2,时间性能

在查找方面,顺序存储结构为O(1),单链表为O(n);

在插入和删除方面,顺序存储结构需要平均移动表长一半的元素,时间为O(n),而单链表仅为O(1)。

3,空间性能

顺序存储结构需要预分配存储空间,分大了,浪费,分小了易发生上溢;

单链表不需要预分配存储空间,只要有就可以分配,元素个数也不受限制。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值