链表练习题目:反转链表

NC78 反转链表

给出一个长度为n链表,反转链表中的所有节点。

比如,输入一个长度为 n n n 链表:
N 1 → N 2 → . . . → N n − 1 → N n N_1→ N_2 → ... → N_{n-1}→ N_n N1N2...Nn1Nn

翻转后为:
N n → N n − 1 → . . . → N 2 → N 1 N_n→ N_{n-1} → ... → N_2→ N_1 NnNn1...N2N1

链表的反转不同于数组:数组反转只需交换数据,链表反转一般要求交换指针域。

比如,一个长度为 4 的链表,如下所示:
在这里插入图片描述
反转之后变为:

不难发现,数据在内存中的位置没有改变,只是指针域的值发生了变化。

头插法

头插法,常用的链表构造方法之一。顾名思义,就是把元素插在链表最前边的位置。

首先,我们先声明一个空指针作为头结点,表示此时链表中没有节点:

struct Node {
	int data = 0;
	Node *next = nullptr;
};
Node *head = nullptr;

接下来,从数据源读取数据,假设我们从标准输入读取:

for (int x; cin >> x;) {
	// do something
}

每读入一份数据 x x x,就将其存入一个新节点 t m p tmp tmp

for (int x; cin >> x;) {
	Node *tmp = new Node();
	tmp->data = x;
	// do something
}

现在我们有了两个指针 t m p tmp tmp h e a d head head

  • t m p tmp tmp 指向一个孤立的节点。
  • h e a d head head 指向一个链表的头结点。

现在要将 t m p tmp tmp 插入至链表中,头插法的流程是:

  • t m p tmp tmp 的指针域指向链表的头结点:
    tmp->next = head;
    
  • h e a d head head 指向 t m p tmp tmp 指向的节点,即将该节点当做新的头结点:
    head = tmp;
    

至此,一次头插法的操作完成啦。可以结合下面的图,更容易理解一点。

按照上述步骤,继续插入第二个节点:

不难发现,按照头插法构造链表,后插入的节点在前面,先插入的节点后面。

因此,我们只要从头至尾遍历输入的链表,然后将每个节点依次按照头插法插入新链表。

最后,新链表就是反转之后的样子啦。

完整代码如下:

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        ListNode *head = nullptr;
        while (pHead != nullptr) {
            auto tmp = pHead->next;
            pHead->next = head;
            head = pHead;
            pHead = tmp;
        }
        return head;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值