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

代码随想录刷题60天

【数组】day2

【数组】day1


目录

链表概述

一、链表增删地初次理解

二、链表常见六个操作

三,链表的转置

总结


链表概述

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


一、链表增删的初步理解

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

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;
     }
 };

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

二、链表常见六个操作

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

   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<get(1)<deleteAtIndex(2);    // 现在,链表变为 1->3
     cout<get(1)<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;
     }
};


总结

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

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