在c++的线性表中,如何用ListNode设置好结点呢?我们往往因为不熟悉指针和内存分配的原理,而在初学阶段不能正确的设置好结点,我总结了俩种不同情况设置结点的情况,这里引用LeetCode的几个题目为例
一、设置一个结点指向头结点head
如:ListNode * p = head;
在这里面我们设置了一个结点指向head,我们用它可以帮助我们遍历整个链表
在c++中如果我们需要求一个链表的长度时时候就可以这样设置
剑指 Offer 22. 链表中倒数第k个节点
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。
例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。
示例
给定一个链表: 1->2->3->4->5, 和 k = 2.
返回链表 4->5.
这一道题你在求解过程需要求链表长度 ,通过ListNode *pre = head;设置pre这个结点可以帮助遍历链表
class Solution { public: ListNode* getKthFromEnd(ListNode* head, int k) { ListNode *pre = head; ListNode *p = head; int j = 0; int len = 0; while(pre->next){ pre = pre->next; len++; } while(p && j < (len-k+1)){ p= p->next; j++; } return p; } };
二、单纯的设置结点
1
ListNode temp;
ListNode *ptr = &temp;
temp.next =head;
2
ListNode* temp = new ListNode (0,head); /*设置一个新结点,这个结点值为0,temp->next=head */
ListNode* ptr = temp; //设置一个指针指向temp
注意1和2俩种方法是等价的 ,但是你可以看到的第一种方法temp.next用到了“ . ”,而不是"->",是因为temp前用了&符号
同时我们设置了一个指针,指向temp这个结点,所以随着指针移动temp也会随之改变(&这个符号可以将ptr 与 temp进行捆绑操作,举个例子相当于三国杀里面的“铁索连环”)
我们用LeetCode里面的题目例子来看
203. 移除链表元素
方法1
class Solution { public: ListNode* removeElements(ListNode* head, int val) { ListNode temp; ListNode *pre = &temp; temp.next = head; while(pre->next){ //只有pre->next不为空才能进行操作 if(pre->next->val == val) //pre的下一个结点的值不为val的值 pre->next= pre->next->next; //是的话跳过这个结点 else{ pre = pre->next; //否则pre往前走 } } return temp.next; //因为temp这个结点后继才为head,所以返回temp.next; } };
方法2
class Solution { public: ListNode* removeElements(ListNode* head, int val) { ListNode *dummyHead = new ListNode(0, head); ListNode *temp = dummyHead; while (temp->next != NULL) { if (temp->next->val == val) { temp->next = temp->next->next; } else { temp = temp->next; } } return dummyHead->next; } };