数据结构—链表详解

浅谈数据结构——链表

本篇随笔就数据结构——链表进行讲解。链表是一种特别实用的数据结构,我把它理解为数组的升级版,也就是在数组的基础上,它能作到在任意位置添加或者删除元素,而不影响其余元素。链表仍是咱们进行图论学习时,图的经常使用存储方式——邻接表(链式前向星)的实现基础。学习链表须要读者具备必定的语法基础,最好会一点点指针。(不会也不要紧,咱们主要讲解数组模拟链表)数组

什么是链表

链表,顾名思义,就是带链的表。我已经说过,链表属于数组的增强版。那咱们能够借助数组来理解链表:若是说数组是一长排连在一块儿的“方块”的话,那么链表就是把这些方块“拉开“,每一个方块还有两个箭头,分别指向这个方块前面的方块和后面的方块。数据结构

这样咱们就能够理解,为何链表能够支持随机插入和删除了。从某种意义上来讲,这里的每个方块都是离散的,咱们在某两点插入的时候,只须要把要插入的元素,这个元素目标位置前面的元素、后面的元素的箭头改一下,就作到了插入的操做。删除同理。学习

链表的实现原理

根据刚才的理解,咱们能够发现,咱们能够用一个结构体来模拟每个方块,结构体中存一个元素和两个指针,指针分别指向上一个元素的位置和下一个元素的位置。可是蒟蒻不会指针指针的实现比较麻烦,并且在调试的时候也不是很理想。因此咱们来想指针的本质就是告诉你一个位置,那么针对于”增强数组“链表来说,这个位置能够用什么来表示呢?指针

对,数组下标。调试

因此咱们刚才的结构体就能够简化,变成存一个元素和两个int变量(存储数组下标)。这样,咱们就能够用结构体数组模拟链表的实现。code

链表基本操做的代码实现

链表实现的精髓就是更改指针,改掉了三个元素(前,中,后)的指针使链表合法,就完成了咱们须要作的操做,本部分再也不就每段代码进行过多讲解,请你们自行理解代码含义,最好借助纸笔推演,看的会更明白一些。rem

(1)初始化

咱们初始化链表的时候,要根据题目意思处理开头的第一个元素,这很重要!而且,咱们把全部的指针都清成-1,这样保证了链表初始绝对合法。it

void init()
{
    for(int i=1;i<=n;i++)
        a[i].pre=a[i].nxt=-1;
    a[1].nxt=-1;
    a[1].pre=0;
    a[0].nxt=1;
}

(2)插入操做

void insert_left(int pos,int k)//把元素k插入到pos元素以前
{
    a[a[pos].pre].nxt=k;
    a[k].pre=a[pos].pre;
    a[pos].pre=k;
    a[k].nxt=pos;
}
void insert_right(int pos,int k)//把元素k插入到pos元素以后
{
    a[a[pos].nxt].pre=k;
    a[k].nxt=a[pos].nxt;
    a[pos].nxt=k;
    a[k].pre=pos;
}

(3)删除操做

void remove(int x)
{
    if(a[x].pre==-1)
        return;
    a[a[x].pre].nxt=a[x].nxt;
    a[a[x].nxt].pre=a[x].pre;
    a[x].pre=-1;
    a[x].nxt=-1;
}

(4)遍历

void print()
{
    int start=a[0].nxt;
    while(1)
    {
        printf("%d ",start);
        if(a[start].nxt==-1)
            break;
        start=a[start].nxt;
    }
}
相关文章
相关标签/搜索