题目要求:
构建一个单向链表,链表中包含一组整数数据。输出链表中的所有元素。
1. 使用自定义的链表数据结构
2. 提供一个 linkedList 类来管理链表,包含构建链表和输出链表元素的方法
3. 在 main 函数中,创建一个包含一组整数数据的链表,然后调用链表的输出方法将所有元素打印出来
输入包含多组测试数据,输入直到文件尾结束。 每组的第一行包含一个整数 n,表示需要构建的链表的长度。 输出每组数据占一行 每个元素之间一个空格
学习定义了一个名为
ListNode
的结构体,用于表示链表中的一个节点,包含存储节点数据的数据域和存储下一个节点地址的指针域。// 链表节点结构体 struct ListNode { int val; // 存储节点的数据 ListNode *next; // 指向下一个节点的指针 // 构造函数,用于初始化节点, x接收数据作为数据域,next(nullptr)表示next指针为空 ListNode(int x) : val(x), next(nullptr) {} };
new运算符:作用就是在堆内存中动态分配内存空间,并返回分配内存的地址,使用方式一般为
指针变量 = new 数据类型
,后面有需要输入的值 前面需要给出定义 在main函数开头定义
#include<iostream>
using namespace std;
//定义一个链表节点
struct ListNode{
int val;
ListNode *next;
ListNode(int x): val(x), next(nullptr){}
};
int main(){
int n, val;
ListNode *dummyHead = new ListNode(0); //定义一个虚拟头结点
while(cin >> n){ //根据输入的链表长度值构建链表
ListNode *cur = dummyHead; //定义一个指向当前头结点的指针cur,指向虚拟头结点
while(n--){
cin >> val; // 输入链表的val值
ListNode *newNode = new ListNode(val); //根据val 的值构建一个新的节点 next为nullptr
cur -> next = newNode; //新节点接入链表 尾接
cur = cur -> next; // cur指向新接入的节点 链表的最后一个节点
}//链表构建完 从头开始遍历链表并输出
cur = dummyHead;
// cur -> next != Null的话 就是还没有遍历完 以此为循环临界点
//遍历并逐个输出
while(cur->next != nullptr){
cout << cur->next->val << " ";
cur = cur -> next;
}
cout << endl;
}
}
这样子在实际操作中还存在结构问题
1.在每次循环中,
dummyHead->next
会指向新的链表,但之前的链表没有被释放,会导致内存泄漏。应该在每次循环结束时,释放之前的链表,并将dummyHead->next
重置为nullptr
2.dummyHead
是在堆上动态分配的内存,但程序结束时没有释放它,会导致内存泄漏。应该在程序结束前,释放dummyHead
。
完整的代码应该为
#include<iostream>
using namespace std;
//定义一个链表节点
struct ListNode{
int val;
ListNode *next;
ListNode(int x): val(x), next(nullptr){}
};
// 释放链表内存
//从链表的头节点开始,逐个删除节点,直到链表为空。
void freeList(ListNode* head) {
while (head != nullptr) {
ListNode* temp = head;
head = head->next;
delete temp; //释放 temp 指向的当前节点的内存
}
}
int main(){
int n, val;
ListNode *dummyHead = new ListNode(0); //定义一个虚拟头结点
while(cin >> n){ //根据输入的链表长度值构建链表
ListNode *cur = dummyHead; //定义一个指向当前头结点的指针cur,指向虚拟头结点
while(n--){
cin >> val; // 输入链表的val值
ListNode *newNode = new ListNode(val); //根据val 的值构建一个新的节点 next为nullptr
cur -> next = newNode; //新节点接入链表 尾接
cur = cur -> next; // cur指向新接入的节点 链表的最后一个节点
}//链表构建完 从头开始遍历链表并输出
cur = dummyHead;
// cur -> next != Null的话 就是还没有遍历完 以此为循环临界点
//遍历并逐个输出
while(cur->next != nullptr){
cout << cur->next->val << " ";
cur = cur -> next;
}
cout << endl;
// 释放当前链表的节点(保留 dummyHead)
freeList(dummyHead->next);
dummyHead->next = nullptr; // 重置 dummyHead 的 next 指针
}
// 程序结束 释放虚拟头结点
delete dummyHead;
return 0;
}