为什么这里是这样的呢else { tail->next = node; tail = node; }
时间: 2024-02-14 11:33:05 浏览: 17
这段代码是一个链表的插入操作。如果链表为空,即头节点`head`为NULL,那么新的节点就是头节点,所以将`head`指向新的节点即可。否则,就需要找到链表的尾节点,将其`next`指向新的节点,然后将`tail`指向新的节点,以便下一次插入操作可以直接在尾节点后插入新的节点。所以,`else`语句中的代码实现了将新节点插入到链表尾部的操作。
相关问题
解读这段代码// 在链表末尾添加节点 void addNode(List* list, int data) { // 创建新节点 Node* node = (Node*)malloc(sizeof(Node)); node->data = data; node->prev = list->tail; node->next = NULL; // 如果链表为空 if (list->head == NULL) { list->head = node; list->tail = node; } else { // 在尾部添加新节点 list->tail->next = node; list->tail = node; } }
这段代码是一个函数,实现了在链表末尾添加一个新节点的功能。具体来说,它接收两个参数:一个是指向链表的指针,一个是要添加的节点数据。函数内部的实现逻辑如下:
1. 创建一个新节点,并为其分配内存空间。
2. 将新节点的数据设置为传入的参数。
3. 将新节点的 prev 指针指向链表的尾部节点。
4. 将新节点的 next 指针设置为 NULL。
5. 判断链表是否为空,如果是,则将新节点同时设置为头节点和尾节点。
6. 如果链表不为空,则将链表尾部节点的 next 指针指向新节点,并将链表的尾部指针指向新节点。
这个函数的核心是将新节点添加到链表末尾。如果链表为空,则添加的节点既是头节点也是尾节点;如果链表不为空,则将新节点加入到尾部节点的 next 指针处,同时将尾节点指针指向新节点。这样就完成了在链表末尾添加节点的操作。
#include <iostream> using namespace std; struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(NULL) { }}; class LinkedList { public: static ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { ListNode dummy(0); ListNode* tail = &dummy; while (l1 && l2) { if (l1->val < l2->val) { tail->next = l1; l1 = l1->next; } else { tail->next = l2; l2 = l2->next; } tail = tail->next; } tail->next = l1 ? l1 : l2; return dummy.next; } }; int main() { ListNode* l1 = nullptr; ListNode* l2 = nullptr; int n1, n2; cin >> n1 >> n2; for (int i = 0; i < n1; i++) { int x; cin >> x; ListNode* node = new ListNode(x); if (l1 == nullptr) { l1 = node; } else { ListNode* cur = l1; while (cur->next) { cur = cur->next; } cur->next = node; } } for (int i = 0; i < n2; i++) { int x; cin >> x; ListNode* node = new ListNode(x); if (l2 == nullptr) { l2 = node; } else { ListNode* cur = l2; while (cur->next) { cur = cur->next; } cur->next = node; } } ListNode* mergedList = LinkedList::mergeTwoLists(l1, l2); while (mergedList) { cout << mergedList->val << " "; mergedList = mergedList->next; } cout << endl; return 0; }详细解释每一句代码
下面是每行代码的详细解释:
```
#include <iostream>
using namespace std;
```
包含iostream头文件,并使用命名空间std。
```
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) { }
};
```
定义链表节点结构体ListNode,每个节点包含一个整型数值val和一个指向下一个节点的指针next。构造函数初始化节点的val值为传入的参数x,next指针初始化为NULL。
```
class LinkedList {
public:
static ListNode* mergeTwoLists(ListNode* l1, ListNode* l2)
{
ListNode dummy(0);
ListNode* tail = &dummy;
while (l1 && l2)
{
if (l1->val < l2->val)
{
tail->next = l1;
l1 = l1->next;
}
else
{
tail->next = l2;
l2 = l2->next;
}
tail = tail->next;
}
tail->next = l1 ? l1 : l2;
return dummy.next;
}
};
```
定义一个LinkedList类,其中包含一个静态方法mergeTwoLists用于合并两个有序链表。参数l1和l2分别为要合并的两个链表的头节点指针。函数中创建一个虚拟头节点dummy,用于方便后续的链表合并操作。通过tail指针来表示合并后的链表的最后一个节点,根据l1和l2当前节点值的大小关系来更新tail指向的节点。最后将剩余未合并的链表接到tail后面,返回合并后链表的头节点指针。
```
int main() {
ListNode* l1 = nullptr;
ListNode* l2 = nullptr;
int n1, n2;
cin >> n1 >> n2;
for (int i = 0; i < n1; i++)
{
int x;
cin >> x;
ListNode* node = new ListNode(x);
if (l1 == nullptr)
{
l1 = node;
}
else
{
ListNode* cur = l1;
while (cur->next)
{
cur = cur->next;
}
cur->next = node;
}
}
for (int i = 0; i < n2; i++)
{
int x;
cin >> x;
ListNode* node = new ListNode(x);
if (l2 == nullptr)
{
l2 = node;
}
else
{
ListNode* cur = l2;
while (cur->next)
{
cur = cur->next;
}
cur->next = node;
}
}
ListNode* mergedList = LinkedList::mergeTwoLists(l1, l2);
while (mergedList)
{
cout << mergedList->val << " ";
mergedList = mergedList->next;
}
cout << endl;
return 0;
}
```
主函数中首先定义了两个链表的头节点指针l1和l2以及两个整型变量n1和n2,分别表示两个链表的节点个数。通过输入流cin读取参数n1和n2以及链表节点的值,并创建相应的节点。对于第一个链表l1,在链表为空的情况下将第一个节点赋值为头节点,否则遍历链表直到找到最后一个节点将新节点插入。对于第二个链表l2同理。接着调用LinkedList::mergeTwoLists方法将两个链表合并,并遍历输出合并后链表的每个节点的值。最后输出一个换行符并返回0表示程序运行正常结束。
阅读全文