【编程2】单链表+单链表反转(LeetCode. 206)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012736685/article/details/84932638

一、链表

链表:不需要一块连续的内存空间,它通过“指针”将一组零散的内存块串联起来使用.
内存分布
在这里插入图片描述
最常用的链表结构:单链表、双向链表和循环链表

二、单链表

1、基本概念

(1)单链表

当一个序列中只含有指向它的后继结点的链接时,就称该链表为单链表。

  • 非空表(有头结点):
    在这里插入图片描述
  • 空表:
    在这里插入图片描述

(2)头指针——必有元素

链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针。头指针具有标识作用。

任何情况下,头指针都存在,无论链表是否为空

(3)头结点——非必需元素

为了操作的统一和方便(插入/删除首元结点)设立的,放在首元结点(第一元素结点)之前,其数据域一般无意义(也可以 存放链表的长度)。

(4)尾结点

最后一个结点指针为“空”(通常用NULL或“^”符号表示),是链表的结束标志,表示它没有后继结点。

2、查找操作

目标:随机访问第 k 个元素
==》依次遍历链表,查找第 k 个元素
==》时间复杂度:O(n)

3、插入操作

目标:插入 x 结点
==》时间复杂度:O(1)
x->next = a2->next
a2->next = x
在这里插入图片描述

4、删除操作

目标:删除 a2 结点
==》时间复杂度:O(1)
p = a1 -> next
a1->next = p->next
在这里插入图片描述

三、设计思想—— 时间 <-> 空间

  • 当内存足够时,若追求代码的执行速度 ==》选择空间复杂度高、时间复杂度相对较低的算法或者数据结构
  • 当内存比较紧张 ==》时间换空间

四、LeetCode206.反转链表

1、题目描述

反转一个单链表。

2、示例

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

3、分析

  • 要实现单链表反转,主要是修改结点的指针:将当前结点的指针指向其前驱结点。
  • 在反转的过程中为了防止断链,需要记录下一结点的信息。例如:假设 i 结点之前,我们把所有的结点的指针都已经反转了,那么自然 i 和以后的结点链接发生了断裂!
    在这里插入图片描述

==》利用三个指针,分别记录:当前结点、其前驱结点、其后继结点即可实现链表反转。

4、实现

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {        
        ListNode *pre = NULL;
        ListNode *pcur = head;
        ListNode *pnext = NULL;
        ListNode *tail = NULL;
        
        while(pcur != NULL){
            pnext = pcur->next;
            if(pnext == NULL)
                tail = pcur;
                
            pcur->next = pre;
            
            pre =pcur;
            pcur = pnext;
        }
        return tail;
    }
};

==》时间复杂度:O(n)

五、碎碎念

  • 很基本的题目,但是自己实现起来还是有困难,还得多多实践和思考;
  • 把链表的操作理解实现。
  • 后续加上leetcode92

猜你喜欢

转载自blog.csdn.net/u012736685/article/details/84932638
今日推荐