DAY3 链表part01

 
 

今日任务

●  链表理论基础

●  203.移除链表元素

●  707.设计链表

●  206.反转链表

链表理论基础

文章链接:https://programmercarl.com/%E9%93%BE%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html

 1、循环链表用于解决约瑟夫环的问题

2、自定义链表结点的结构体

1 struct LinkNode
2 {
3     int val;
4     LinkNode* next;
5     LinkNode():val(0),next(NULL) {}//初始化函数1;
6     LinkNode(int x):val(x),next(NULL) {}//初始化函数2;
7     LinkNode(int x,LinkNode *next):val(0),next(next) {}//初始化函数3;
8 }//自定义结构体时自选

LinkNode *head= new Linknode(x);

3、若使用C++默认的初始化函数,则初始化不能赋值

LinkNode *head= new Linknode();//即初始化函数1

203.移除链表元素

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode() : val(0), next(nullptr) {}
 7  *     ListNode(int x) : val(x), next(nullptr) {}
 8  *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 9  * };
10  */
11 class Solution {
12 public:
13     ListNode* removeElements(ListNode* head, int val) {
14             ListNode* dummy=new ListNode(0);
15             dummy->next=head;
16             ListNode*p=dummy;
17             while(p->next!=NULL)
18             {
19                 if(p->next->val==val) 
20                 {
21                     ListNode* q=p->next;
22                     p->next=p->next->next;
23                     delete(q);//注意释放
24                 }
25                 else p=p->next;
26             }
27             head=dummy->next;
28             return head;
29     }
30 };

重点掌握虚拟头节点dummy的用法

题目链接/文章讲解/视频讲解::https://programmercarl.com/0203.%E7%A7%BB%E9%99%A4%E9%93%BE%E8%A1%A8%E5%85%83%E7%B4%A0.html

 

707.设计链表

 1 class MyLinkedList {
 2 public:
 3     struct LinkNode
 4     {
 5         int val;
 6         LinkNode* next;
 7         LinkNode(int x):val(x),next(NULL){};
 8     };
 9     MyLinkedList() {
10         dummy=new LinkNode(0);
11         cnt=0;
12     }//掌握类的语法
13     
14     int get(int index) {
15         if(index<0||index>=cnt) return -1;
16         else
17         {
18             LinkNode*p=dummy->next;
19             while(index--)
20             {
21                 p=p->next;
22             }//p定位到下标为index的位置
23             return p->val;
24         }
25     }
26     
27     void addAtHead(int val) {
28         LinkNode*newNode=new LinkNode(val);
29         newNode->next=dummy->next;
30         dummy->next=newNode;
31         cnt++;
32     }
33     
34     void addAtTail(int val) {
35         LinkNode*newNode=new LinkNode(val);
36         LinkNode*p=dummy;
37         while(p->next!=NULL) p=p->next;
38         p->next=newNode;
39         cnt++;
40     }
41     
42     void addAtIndex(int index, int val) {
43         if(index<0||index>cnt) return;
44         else if(index==cnt) 
45         {
46             addAtTail(val);
47         }
48         else if(index==0) addAtHead(val);
49         else 
50         {
51             //定位到下标为index的结点前一个结点52             LinkNode*p=dummy;
53             while(index--)
54             {
55                 p=p->next;
56             }
57             LinkNode* newNode=new LinkNode(val);
58             newNode->next=p->next;
59             p->next=newNode;
60             cnt++;
61         }
62     }
63     
64     void deleteAtIndex(int index) {
65         if(index<0||index>=cnt) return ;
66         else{
67             LinkNode*p=dummy;
68             while(index--)
69             p=p->next;//p指向下标为index的结点前一个结点
70 
71             LinkNode*q=p->next;
72             p->next=p->next->next;
73             delete(q);
74             cnt--;
75         }
76     }
77     private:
78     LinkNode*dummy=new LinkNode(0);
79     int cnt;//定义全局变量
80 };
81 
82 /**
83  * Your MyLinkedList object will be instantiated and called as such:
84  * MyLinkedList* obj = new MyLinkedList();
85  * int param_1 = obj->get(index);
86  * obj->addAtHead(val);
87  * obj->addAtTail(val);
88  * obj->addAtIndex(index,val);
89  * obj->deleteAtIndex(index);
90  */

 

题目链接/文章讲解/视频讲解:https://programmercarl.com/0707.%E8%AE%BE%E8%AE%A1%E9%93%BE%E8%A1%A8.html

 

206.反转链表

思路:

 

解法一:双指针法

 1 class Solution {
 2 public:
 3     ListNode* reverseList(ListNode* head) {
 4         ListNode* temp; // 保存cur的下一个节点
 5         ListNode* cur = head;
 6         ListNode* pre = NULL;
 7         while(cur) {
 8             temp = cur->next;  // 保存一下 cur的下一个节点,因为接下来要改变cur->next
 9             cur->next = pre; // 翻转操作
10             // 更新pre 和 cur指针
11             pre = cur;
12             cur = temp;
13         }
14         return pre;
15     }
16 };

 

解法二:递归 还是一如既往的难以理解

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode() : val(0), next(nullptr) {}
 7  *     ListNode(int x) : val(x), next(nullptr) {}
 8  *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 9  * };
10  */
11 class Solution {
12 public:
13     ListNode* reverse(ListNode* pre,ListNode*cur) {
14       if(cur==NULL) return pre;
15       ListNode*p=cur->next;
16       cur->next=pre;
17       return reverse(cur,p);
18     }//递归函数,注意返回值
19 
20     ListNode* reverseList(ListNode*head)
21     {
22         return reverse(NULL,head);
23     }//调用递归的函数
24 };

题目链接/文章讲解/视频讲解:https://programmercarl.com/0206.%E7%BF%BB%E8%BD%AC%E9%93%BE%E8%A1%A8.html

 

总结:

链表的定义;链表的基本操作;链表反转的两种方法

posted @ 2024-07-19 16:34  xzdmzrc  阅读(11)  评论(0编辑  收藏  举报