代码随想录第三天|203.移除链表元素、206.反转列表

  • 链表

链表为通过指针串联在一起的线性结构,每个节点由两部分构成:数据域、指针域。入口节点称为链表头结点(head),最后一个节点的指针域指向NULL。

代码随想录第三天|203.移除链表元素、206.反转列表_第1张图片

 链表类型

单链表:指针域只能指向节点的下一个节点。

代码随想录第三天|203.移除链表元素、206.反转列表_第2张图片

双链表:每个节点有两个指针域,一个指向下一个节点,一个指向上一个节点。

代码随想录第三天|203.移除链表元素、206.反转列表_第3张图片

 循环列表:链表首尾相连,用来解决约瑟夫环问题。

代码随想录第三天|203.移除链表元素、206.反转列表_第4张图片

 

链表存储方式

链表是通过指针域的指针连接在内存中各个节点。链表中节点在内存中不是连续分配,而是散落在内存中的某地址上,分配机制取决于操作系统的内存管理。

代码随想录第三天|203.移除链表元素、206.反转列表_第5张图片

 链表定义

// 单链表
struct ListNode {
     int val;
     ListNode *next;
     ListNode() : val(0), next(nullptr) {}
     ListNode(int x) : val(x), next(nullptr) {}
     ListNode(int x, ListNode *next) : val(x), next(next) {}
 };

链表操作

删除节点

代码随想录第三天|203.移除链表元素、206.反转列表_第6张图片

最后要手动删除D。 

添加节点

代码随想录第三天|203.移除链表元素、206.反转列表_第7张图片

  • 题目:

203.移除链表元素

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回新的头节点。

代码随想录第三天|203.移除链表元素、206.反转列表_第8张图片

正确版本:

        //设置虚节点
        ListNode* virtualnode=new ListNode(0);
        virtualnode->next=head;
        ListNode *cur=virtualnode;
        while(cur->next!=nullptr) {
            if(cur->next->val==val) {
                ListNode *tem=new ListNode(0);
                tem=cur->next;
                cur->next=cur->next->next;
                delete(tem);
            }
            else {
                cur=cur->next;                //忘记写else导致超时
            }
        }
        head=virtualnode->next;
        delete(virtualnode);
        return head;

在进行操作时,可设置一虚拟头结点,使原链表的所有节点可以按照统一方式进行移除。

在最后返回的是虚拟节点的下一个节点。

//不设置虚拟节点
while(head!=nullptr&&head->val==val) { //要注意与先后的顺序,反过来程序报错
            ListNode* temp=head;
            head=head->next;
            delete temp;
        }
            ListNode* cur=head;
            while(cur!=nullptr&&cur->next!=nullptr) {     //因为没有设置虚节点因此头结点也有可能为空
                if(cur->next->val==val) {
                    ListNode* temp=cur->next;
                    cur->next=cur->next->next;
                    delete temp;
                }
                else {
                    cur=cur->next;
                }
            }
        
        return head;

错误版本:

if(head!=nullptr&&head->val==val) {      //该程序答案错误,不能使用if else
            ListNode* temp=head;                 //因为若首节点和第二个节点都是val只能删一个数
            head=head->next;                     //删不全
            delete temp;
        }
        else {
            ListNode* cur=head;
            while(cur!=nullptr&&cur->next!=nullptr) {     //因为没有设置虚节点因此头结点也有可能为空
                if(cur->next->val==val) {
                    ListNode* temp=cur->next;
                    cur->next=cur->next->next;
                    delete temp;
                }
                else {
                    cur=cur->next;
                }
            }
        }
        return head;

运行结果:

代码随想录第三天|203.移除链表元素、206.反转列表_第9张图片

 206.反转链表

给你单链表的头节点head,请你反转链表,并返回反转后的链表.

代码随想录第三天|203.移除链表元素、206.反转列表_第10张图片

 

//双指针法
        if(head==nullptr) return head;
        ListNode* virtualnode=nullptr;
        ListNode* cur=head;
        while(cur->next!=nullptr) {
            ListNode* temp=cur->next;
            cur->next=virtualnode;
            virtualnode=cur;
            cur=temp;
        }
        cur->next=virtualnode;
        head=cur;
        return head;
        
   //精简版
        ListNode* temp;
        ListNode* cur=head;
        ListNode* pre=nullptr;
        while(cur) {
            temp=cur->next;
            cur->next=pre;
            pre=cur;
            cur=temp;
        }
        return pre;
class Solution {
public:
    ListNode* reverse(ListNode* pre,ListNode* cur) {
        if(cur==nullptr) return pre;
        ListNode* temp=nullptr;
        temp=cur->next;
        cur->next=pre;
        return reverse(cur,temp);
    }
    ListNode* reverseList(ListNode* head) {
        //递归法
        return reverse(NULL,head);
    }
};

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