数据结构——单链表存储结构

  • 单链表的链式存储结构

所谓链式存储结构,相较于顺序存储结构的顺序表,顾名思义其存储方式不再是物理地址开辟一块连续空间存储所有结点的方式,见图1,而是通过指针将结点连接起来的存储方式。因此,单链表的每一个结点在物理空间可以不相邻,而在逻辑空间上连续存在;且每个结点除了存储了本身的数据Data,而且有且仅有一个指针Pointer指向下一个结点的位置(地址),是单向存储。

图1所示是典型的单链表结构,这里Head是头结点,头结点用来标记单链表的开始,其数据为NULL,指针指向单链表第一个结点,头结点的存在让单链表的操作更加方便。单链表最后一个结点的指针一般指向NULL,如果让其指向开头,则这个链表就成了循环单链表。

这里写图片描述

  • 链式存储的优缺点

因为引入了指针索引的特点,链式结构的线性表的插入和删除特定结点的过程比顺序存储的单链表方便很多,无需移动大量元素,而是通过更改指针指向即可实现。但是与此同时,链式存储线性表查找定位特定元素则需要遍历整个链表直至寻找到所需元素,而顺序表可以直接通过数组下标获得第i个元素。


关于单链表的基础操作:插入、删除、初始化等在本文中将通过c++描述,这里的一个理解难点在于函数调用过程中的指针的使用。理解了指针的调用过程以及增删结点的方法,对于单链表的基础操作就可以掌握了。

  1. 指针调用
    在单链表的初始化销毁等需要涉及到对头结点的处理,需要用到二级指针。如下所示:

首先定义单链表的结点结构,数据data和结构指针next:

typedef int ElemType;
typedef int Status;

typedef struct LNode
{
    Elemtype data;
    struct LNode* next;
}LNode;
typedef LNode* LinkList; 

在主函数中定义了单链表头结点的结构指针L, L用来对头结点操作。主函数调用了InitList(&L)对链表进行初始化,传递了L的地址到子函数中:

/*mainTEST*/
int main()
{
        LinkList L;
        Printf("Test on function IninList:");
        InitList(&L);
        ....
}
  • 函数传递的两种方式:
  • 地址传递:LinkList *L是指向头结点指针的指针(二级指针),主函数将头指针的地址传递到L中,从而用*L指向头指针,再修改*L的值,即头结点的地址,完成对头结点的内存动态分配,删除头结点等操作。
  • 值传递:主函数传递指针的值,即头结点的地址到子函数中,在子函数中通过引用(LinkList &L)直接修改头指针L的值。
    本文采用了第一种方法:
Status InitList(LinkList *L)
{
    //malloc动态分配了一块大小为LNode结构体大小的内存作为头结点,并将其首地址存入头指针,若分配失败,返回NULL。
    (*L) = (LinkList)malloc(sizeof(LNode));
    if((*L)==NULL) 
        exit(OVERFLOW);
    (*L)->next =NULL;
    return OK;
}

/*c语言中规定:结构体变量中成员的引用方式有两种:
- 变量名.成员名;LNode p; p.data = 3;
- 结构指针->成员名;LNode *p; p->data = 3;*/

2. 单链表的插入算法
如下图所示,在第i个元素之前插入一个元素值为e,将第i-1个元素的next指针指向新元素,并让新元素指向原本的第i个元素。
数据结构——单链表存储结构_第1张图片
程序如下:

Status ListInsert(LinkList L, int i, ElemType e)
{
    LinkList new, cur;
    int j;
    cur = L;

    for(j = 0;j1;j++)
    {
        if(cur) 
            cur = cur->next;
        else 
            break;
    }
    if(!cur) return ERROR;
    new = (LinkList)malloc(sizeof(LNode));
    if(!new) exit(OVERFLOW);
    new->next = cur->next;
    new->data = e;
    cur->next = new;
    return OK;
}

删除算法与插入类似见下图:
数据结构——单链表存储结构_第2张图片
程序如下:

Status ListDelete(LinkList L, int i,ElemType *e)
{
    LinkList pre, p;
    int j=1;
    pre = L;
    while(pre->next && jnext;
        ++j;
    }

    if(!pre->next || j>i) return ERROR;
    p = pre->next;
    *e = p->data;
    pre->next = p->next;
    free(p);
    return OK; 
}

你可能感兴趣的:(数据结构)