Bootstrap

卡码网语言基础课|链表的基础操作Ⅰ

题目要求:

构建一个单向链表,链表中包含一组整数数据。输出链表中的所有元素。
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;
}

;