第一课 链表

Posted zach0812

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第一课 链表相关的知识,希望对你有一定的参考价值。

技术图片

 

预备知识:链表基础:

基础(c语言版

 1 #include <stdio.h>
 2 struct ListNode 
 3     int val;
 4     struct ListNode* next;
 5 ;
 6 
 7 int main() 
 8     struct ListNode node1;
 9     struct ListNode node2;
10     struct ListNode node3;
11     struct ListNode node4;
12     struct ListNode node5;
13 
14     node1.val = 10;
15     node2.val = 20;
16     node3.val = 30;
17     node4.val = 40;
18     node5.val = 50;
19 
20     node1.next = &node2;
21     node2.next = &node3;
22     node3.next = &node4;
23     node4.next = &node5;
24     node5.next = NULL;
25 
26     struct ListNode *pCurrent = &node1;
27     while (pCurrent != NULL) 
28         printf("%d \\n", pCurrent->val);
29         pCurrent = pCurrent->next;
30     
31     return 0;
32 
33 /*
34 10
35 20
36 30
37 40
38 50
39 
40 
41 */

 

基础(c++版)

 1 #include <stdio.h>
 2 struct ListNode 
 3     int val;
 4     struct ListNode * next;
 5 ;
 6 
 7 int main()
 8     
 9     ListNode node1;
10     ListNode node2;
11     ListNode node3;
12     ListNode node4;
13     ListNode node5;
14     
15     node1.val = 10;
16     node2.val = 20;
17     node3.val = 30;
18     node4.val = 40;
19     node5.val = 50;
20     
21     node1.next = &node2;
22     node2.next = &node3;
23     node3.next = &node4;
24     node4.next = &node5;
25     node5.next = NULL;
26     
27     ListNode * pCurrent = &node1;
28     while(pCurrent != NULL)
29         printf("%d \\n",pCurrent->val);
30         pCurrent = pCurrent->next ;
31     
32     return 0;
33 

二者的主要区别是:c++ 可以没有 struct !

技术图片
 1 #include <iostream>
 2 using namespace std;
 3 
 4 //链表相关的基础
 5 struct ListNode 
 6     int val;
 7     struct ListNode * next;
 8 ;
 9 
10 struct ListNode * ListInit()
11     struct ListNode * head =(struct ListNode *)malloc(sizeof(struct ListNode));
12     head->val = 0;
13     head->next = NULL;
14 
15     return head;
16 
17 void printList(struct ListNode * head)
18     while(head != NULL)
19         printf("Val: %d\\n",head->val,head->next);
20         head = head->next;
21     
22 
23 void addOneNode(struct ListNode * head,int val)
24     struct ListNode * newNode  =(struct ListNode *)malloc(sizeof(struct ListNode));
25     newNode->val = val;
26     newNode->next = NULL;
27 
28     //遍历链表到 尾部
29     struct ListNode * temp = head;
30     while(temp->next !=NULL)
31         temp = temp->next;
32     
33     temp->next = newNode;
34 
35 
36 int main()
37 
38     struct ListNode * head = ListInit();  //head存数据(默认存的值为0)
39     head->val = 1; //这里将默认的head.val =0 变为1
40     for(int i =2;i<10;++i)
41         addOneNode(head,i);
42     
43     printList(head);
44     return 0;
45 
链表基础回顾!!!

 

例1-a:链表逆序-a  (leetcode 编号 206)

技术图片

 

 技术图片

 

注:不允许申请额外的空间。

自己的代码:(缺点是:当head 为空的时候不能通过, 而且最后一个还要在循环外另外写一下!!! 优点是:它没有在循环中重复声明pNext变量)

技术图片
 1 #include <iostream>
 2 using namespace std;
 3 
 4 //链表相关的基础
 5 struct ListNode 
 6     int val;
 7     struct ListNode * next;
 8 ;
 9 
10 struct ListNode * ListInit()
11     struct ListNode * head =(struct ListNode *)malloc(sizeof(struct ListNode));
12     head->val = 0;
13     head->next = NULL;
14 
15     return head;
16 
17 void printList(struct ListNode * head)
18     while(head != NULL)
19         printf("Val: %d ",head->val,head->next);
20         head = head->next;
21     
22 
23 void addOneNode(struct ListNode * head,int val)
24     struct ListNode * newNode  =(struct ListNode *)malloc(sizeof(struct ListNode));
25     newNode->val = val;
26     newNode->next = NULL;
27 
28     //遍历链表到 尾部
29     struct ListNode * temp = head;
30     while(temp->next !=NULL)
31         temp = temp->next;
32     
33     temp->next = newNode;
34 
35 
36 //链表逆序 (Leetcode 代码)
37 struct ListNode * reverseList(struct ListNode * head)
38     struct ListNode * pPre = NULL; //保存前一个地址
39     struct ListNode * pNext = head->next; //保存下一个地址
40     while(pNext != NULL)
41         head->next = pPre; //
42         pPre = head;
43 
44         head = pNext; //
45         pNext = head->next;
46     
47     head->next = pPre;  //这个是因为最后一个连不上,所以最后要自己连上!
48     return head;
49 
50 
51 
52 int main()
53 
54     struct ListNode * head = ListInit();  //head存数据(默认存的值为0)
55     head->val = 1; //这里将默认的head.val =0 变为1
56     for(int i =2;i<10;++i)
57         addOneNode(head,i);
58     
59     printList(head);
60     head = reverseList(head);
61     printList(head);
62 
63     return 0;
64 
19.10.3写

面是老师的代码:

 1 class Solution 
 2 public:
 3     ListNode* reverseList(ListNode* head) 
 4         ListNode * newHead =NULL;
 5         while(head)
 6             ListNode *temp = head->next;
 7             head->next =newHead;
 8             newHead = head;
 9             
10             head = temp;
11         
12         return newHead;
13         
14     
15 ;

例1-b:链表逆序-b  (leetcode 编号 92)

 

技术图片

 

重要的四个结点:

 技术图片

 

技术图片

 

技术图片

 

 

技术图片

 

技术图片

 

技术图片

 个人的思路:

技术图片

 

 

 

技术图片
 1 ListNode * reverseBetween(ListNode * head,int m,int n)
 2     if(head ==NULL || m==n) return head;
 3     int flag = 0;
 4     if(m==1)  flag = 1;
 5     ListNode* pCur = head;
 6     for(int i =0;i<m-2;++i)
 7         pCur = pCur->next;
 8     //将pCur 遍历到 m前一个节点
 9 
10     ListNode* pBackWard = pCur;  //记录
11     ListNode* pM = pCur->next; //记录
12     //开始逆序
13     pCur = pM;
14     if(flag) pCur = pBackWard; //特殊情景时修正下
15     ListNode * pPre = NULL;
16     for(int i =0;i<n-m;++i)
17         ListNode * pNext = pCur->next;//本次
18         pCur->next = pPre;//
19         pPre = pCur; //下次
20         pCur = pNext; //
21     
22     if(!flag)
23         pBackWard->next = pCur;
24         ListNode * temp = pCur->next;
25         pCur->next = pPre;
26         pM->next = temp;
27     else
28         head = pCur;
29         ListNode * temp = pCur->next;
30         pBackWard->next = temp;
31         head->next = pPre;
32     
33     return head;
34 
我自己的代码 只移动一个指针

下面是老师的代码:

 1 #include <stdio.h>
 2 struct ListNode
 3     int val;
 4     struct ListNode *next;
 5 ;
 6 
 7 class Solution 
 8 public:
 9     ListNode* reverseBetween(ListNode* head, int m, int n) 
10         ListNode * pre_head = NULL;
11         ListNode * result = head; //最终返回的头节点
12         // 向前移动m-1 个位置 ,pre_head  和 head 一起移动
13         for (int i = 0; i < m - 1; ++i) 
14             pre_head = head;
15             head = head->next;
16         
17 
18         ListNode * modified_list_tail =head;
19         ListNode * new_head  = NULL; //新的逆序链表的头
20         int change_node_num = n-m+1;
21         while(head &&change_node_num)
22             ListNode * temp = head->next;
23             head->next = new_head;
24             new_head = head;
25             head = temp;
26 
27             change_node_num--;
28         
29         modified_list_tail->next = head;
30 
31         if(pre_head)
32             pre_head->next = new_head;
33         
34         else  //如果是从第一个开始就逆序的话, 特殊情况!
35             result = new_head;
36         
37         return result;
38     
39 ;

 

以上是关于第一课 链表的主要内容,如果未能解决你的问题,请参考以下文章

数据结构-链表链表的基本操作

数据结构-链表链表的相关算法

[11道链表经典笔试题]优化的算法思想:反转链表链表相交快慢指针

reorder-list——链表快慢指针逆转链表链表合并

何为链表链表示例以及翻转链表

数据结构:链表链队列