链表理论基础

链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域,一个是指针域(存放指向下一节点的指针)。

链表的类型

单链表

每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。只能向后查询。

 双链表

每一个节点有两个指针域,一个指向下一节点,一个指向上一节点。既可以向前查询也可以向后查询。

循环列表 

就是首尾相连的单链表。

 链表的存储方式

数组在内存中是连续分布的,链表不是,链表是通过指针与的指针链接在内存中的各个节点,是散乱分布在内存中的,分配机制取决于操作系统的内存管理。

如图所示:

 链表的定义

C/C++的定义链表结点的方式:

// 单链表
struct ListNode {
    int val;  // 节点上存储的元素
    ListNode *next;  // 指向下一个节点的指针
    ListNode(int x) : val(x), next(NULL) {}  // 节点的构造函数
};

也可以不定义构造函数,C++默认生成一个构造函数,但是这个构造函数不会初始化任何成员变量,下面我来举两个例子:

通过自己定义构造函数初始化节点:

ListNode* head = new ListNode(5);

使用默认构造函数初始化节点:

ListNode* head = new ListNode();
head->val = 5;

所以如果不定义构造函数使用默认构造函数的话,在初始化的时候就不能直接给变量赋值!

链表的操作

删除节点

删除D节点,如图所示:

 只需要将C的next指针指向E就好了,在C++中可以手动释放D节点内存。

添加节点

 链表的增添和删除都是O(1),也不会影响其他节点,但是如果要删除第n个节点,需要从头查找到第n-1个节点,通过其next指针进行删除操作,查找的时间复杂度是O(N)。

数组和链表的对比

 数组在顶的的时候,长度就是固定的,如果想改动数组的长度,就需要定义一个新的数组。

链表的长度可以是不固定的,并且可以动态增删,适合数据量不固定,频繁增删,较少查询的场景。

下面具体说一下单链表实际的代码操作。还是没有彻底弄明白指针,可能有错误,请指出。本人后期也会根据持续的理解进行修正。

如下面代码,第一行就是定义了一个新的链表节点名为head,并且让这个head的节点等同于节点A,包括其节点值以及节点的指数域,也就是说此时head所代表的链表是和A代表的链表是一样的,但是在内存空间中head和A是不一样的,你可以删除A节点并不影响head节点和原来的列表,通常称列表中的第一个节点为头节点。head->val表示的是该节点所存储的数值,head->next表示的是该节点指针域的值,也就是图中C节点的指针。

ListNode* head = A;  
head->val;
head->next;

图1 单链表

上文中说到的节点A,这个A就是指向该节点的指针。

一般一个链表会用头节点的指针来表示,如下图 ,Head表示的就是该链表。

删除单链表节点:

ListNode* temp = D;  //释放D节点空间
D = D->next;
delete temp;

结合图1,上面代码就是将节点D删除,并且释放节点空间。在定义上C->next = D,并且都是指针,D改变C->next随之改变,所以进行D = D->next操作后,C->next=D->next,直接C指向E,并且delete temp,也就是删除掉了D。如果不进行D节点的删除,可以直接进行C->next=D->next操作。代码如下:

C->next=D->next   //不释放需要删除节点D的空间
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值