【从零开始写博客】链表运用:链表的增删查改及反转(day3)

代码随想录刷题60天

【数组】day2

【数组】day1


目录


链表概述

链表是通过指针将一个个节点串起来的数据结构,其优点是增删方便,灵活性强。以下将结合leetcode上的一些例题介绍链表的一些功能和应用。


一、链表增删的初步理解

class Solution
 {
 public:
     ListNode* removeElements(ListNode* head, int val)
     {
         ListNode* temp;
         while (head && head->val == val)
         {
                 temp = head;
                 head = head->next;
         }
         //得到新的头节点
         temp = head;
         while (temp && temp->next)//不能交换顺序
         {
             ListNode* temp2;//需要有辅助节点来辅助删除节点
             while(temp->next && temp->next->val == val)
             {
                 temp2 = temp->next;
                 temp->next = temp->next->next;
             }
             temp = temp->next;
         }
         return head;
     }
 };

相比数组依靠覆盖来完成的删除操作,链表这种直接将需要移除节点的左右节点相连的方式要简单省事多了。而唯一需要注意的是——如果链表的节点是用堆储存的,必须将被移除节点释放,以此来避免内存泄漏。

二、链表常见六个操作

   class MyLinkedList 
 {
 public:
     class LinkedNode 
     {
     public:
         int val;
         LinkedNode* next;
     public:
         LinkedNode(int value) :val(value), next(nullptr){}
     };
     LinkedNode* head;
     int size;

 public:
     MyLinkedList()
     {
         head = new LinkedNode(0);
         size = 0;
     
     }

     int get(int index) 
     {
         LinkedNode* cur;
         if (index + 1 > size)
             return -1;
         cur = head->next;
         for (int i = 0; i < index; i++)
             cur = cur->next;
         return cur->val;
     }

     void addAtHead(int val) 
     {
         LinkedNode* temp = new LinkedNode(val);
         temp->next = head->next;
         head->next = temp;
         size++;
     }

     void addAtTail(int val)
     {
         LinkedNode* temp = new LinkedNode(val);
         LinkedNode* cur = head->next;
         while (cur && cur->next)
             cur = cur->next;
         if (cur)cur->next = temp;
         else head->next = temp;
         size++;
     }

     void addAtIndex(int index, int val) 
     {
         if (index > size)return;        
         if (index == 0){ addAtHead(val); return; }
         if (index == size){ addAtTail(val); return; }

         LinkedNode* temp = new LinkedNode(val);
         LinkedNode* cur = head->next;
         for (int i = 1; i < index; i++)
             cur = cur->next;
         temp->next = cur->next;
         cur->next = temp;  
         size++;
     }

     void deleteAtIndex(int index) 
     {
         LinkedNode* temp,*cur;
         if(index + 1 > size)return;
         size--;
         cur = head->next;
         if (index == 0) 
         {            
             head->next = head->next->next;
             delete(cur);
             return;
         }
         while (index > 1)
         {
             cur = cur->next;
             index--;
         }
         temp = cur->next;
         cur->next = cur->next->next;
         delete(temp);        
     }
 };


 int main(int argc, char* argv[])
 {
     MyLinkedList* myLinkedList = new MyLinkedList();
     //myLinkedList->addAtHead(7);
     //myLinkedList->addAtHead(2);
     //myLinkedList->addAtHead(1);

     myLinkedList->addAtTail(1);
     //myLinkedList->addAtIndex(3, 0);    // 链表变为 1->2->3
     cout<<myLinkedList->get(1)<<endl;              // 返回 2
     //myLinkedList->deleteAtIndex(2);    // 现在,链表变为 1->3
     cout<<myLinkedList->get(1)<<endl;              // 返回 3
     //myLinkedList->addAtHead(6);
     //myLinkedList->addAtTail(4);
     //myLinkedList->deleteAtIndex(0);
     cout << myLinkedList->get(0);
     return 0;
 }

在增删操作中有几点需要我们去注意:

1. 在链表创建中,建议保存的链表长度信息,以此来避免在查找某个节点信息或者在某个位置增删节点时,对节点或位置是否有效的额外判断操作。

2. 在链表中,头节点属于链表的其中一个节点。为了避免在对链表进行操作时不小心对头节点的进行修改,推荐使用不可修改的虚拟头节点。用该节点的next指针存储头节点信息。使用该虚拟头节点在一定程度上可以增加在操作链表时的容错率。

三,链表的转置

class Solution {
public:
  ListNode* reverseList(ListNode* head)
     {
         ListNode* pre, * cur,*temp;
         pre = nullptr;
         cur = head->next;//此时的head是虚拟头节点
         while (cur)
         {
             temp = cur->next;
             cur->next=pre;
             pre = cur;
             cur = temp;
         }
         return pre;
     }
};


总结

在链表中,理解好节点与节点的关系是掌握链表这一数据结构的关键所在。学会画图去模拟对链表节点的操作能够有效理解节点之间的关系以及操作链表时的逻辑错误。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值