蓝蓝计算机考研算法-day05反转输出链表

238 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 28 天,点击查看活动详情

Day05 2023/03/03

难度:简单

题目

输入一个链表的头节点,按链表从尾到头的顺序返回每个节点的值(用数组返回)。 如输入L,2,3的链表如下图:

image.png

返回一个数组为(3,2,1) 0<=链表长度<=10000

示例1

输入: 1 2 3 4 5 6
输出: 6 5 4 3 2 1

运行实例

image.png

思路


本题的意思就是让我们翻转链表,那我们采用带虚拟头节点的头插法创建链表,众所周知头插法创建的链表中数据和我们输入的数据是相反的。天然的就翻转了链表,代码也比较简单,当然这算是曲线救国的方式,大概不是本题的初衷,这里我也给出直接翻转链表的题解:206.反转链表

关键点


  • 本题也没啥关键点,可能用虚拟头节点的方式统一插入操作,需要注意一下。
  • 包括后面释放虚拟头节点内存的小细节。

算法实现


c++代码实现-头插法翻转

#include <iostream>
using namespace std;

//定义链表节点
typedef struct LNode {
    int data;                                     // 数据域  
    LNode *next;                                  // 指针域  
    LNode(int val) : data(val), next(nullptr){};  // 构造函数 
} LNode, *ListLink; 


// 采用带虚拟头节点的头插法创建链表,用空格隔开各个节点数据,回车结束链表创建
ListLink ListHeadInsert() {
    LNode *dummyHead = new LNode(-1), *s, *tmp;  // 虚拟头节点(统一插入操作) 待插入新节点指针 临时节点指针
    int val;
    char ch;                                     // 待插入节点的数据
    while (cin >> val) {
        s = new LNode(val);                      // 创建待插入的新节点
        s->next = dummyHead->next;               // 插入节点
        dummyHead->next = s; 
        if ((ch = cin.get()) == '\n') break;     // 结束条件   
    };
    tmp = dummyHead->next;  // 真正的头节点
    delete dummyHead;       // 释放虚拟头节点
    return tmp;             // 返回真正的头节点
}


// 测试一下
int main() {
    ListLink L =  ListHeadInsert();  // 创建链表
    LNode *cur = L;                  // 遍历指针
    while (cur) {                    // 遍历打印节点
        cout << cur->data << ' ';
        cur = cur->next;
    }
    return 0;
}
  • 时间复杂度 O(n)O(n)--- 创建链表的时间复杂度为O(n)O(n)
  • 空间复杂度 O(1)O(1)--- 链表属于必要空间,除此无额外的辅助空间

总结

  • 对数据结构中的一些基本操作,一定要熟悉,不要 "眼高手低"