数据结构——反转单链表

最近看了《剑指offer》这本书,遇到了一个问题:反转链表

题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后的链表的头结点。

链表结点定义如下:

struct ListNode
{
    int _data;
    ListNode * _pNext;
};

解决方案如下:

ListNode * ReverseList(ListNode * pHead)
{

    ListNode * pRevesedHead = nullptr;//反转后的头结点
    ListNode * pNode = pHead;//当前结点
    ListNode * pPrev = nullptr;//前一结点
    while (pNode != nullptr)//判断非空
    {
        ListNode * pNext = pNode->_pNext;//下一结点(用pNext保存,避免链表断裂)
        if (pNext == nullptr)//如果只有一个结点
        {
            pRevesedHead = pNode;//则直接返回当前结点
        }
        pNode->_pNext = pPrev;//反转操作
        pPrev = pNode;//将前一结点指针后移到当前结点位置
        pNode = pNext;//将当前结点指针后移到下一结点位置
    }
    return pRevesedHead;//返回 反转后的头结点
}

如果不画图,我是怎么都想不出来的。脑子都晕了~~~

后面看别人的博客,再结合自己画的图,勉强了解了反转链表的算法思想。

话不多说,下面看我的图解:

这个题目还有要注意的是:

  • 判断输入的链表是否为空
  • 注意防止反转后链表出现断裂
  • 返回的反转之后的头结点不是原始链表的尾结点

下面是我的测试代码:

//创建一个新链表
void CreateList(ListNode * L,int n)
{
    cin>>L->_data;//输入第一个结点的数据值
    n--;
    for (int i = 0; i < n; i++)
    {
        ListNode * p = new ListNode;
        cin>>p->_data;
        p->_pNext = nullptr;
        L->_pNext = p;
        L = p;
    }
}

//显示链表
void showList(ListNode * L)
{
    ListNode * p = L;
    while (p)
    {
        cout<<p->_data<<‘ ‘;
        p = p->_pNext;
    }
    cout<<endl;
}

//主函数
int main()
{
    ListNode * L = new ListNode;
    L->_pNext = nullptr;
    CreateList(L,5);
    showList(L);
    ListNode * p;
    p = ReverseList(L);
    showList(p);
    return 0;
}

测试结果如下:

就说这么多,如有不足之处,还请不吝赐教。

时间: 2024-10-10 21:19:06

数据结构——反转单链表的相关文章

递归、非递归 反转单链表

定义链表结构 struct ListNode { int val; ListNode *next; ListNode(int v) : val(v), next(NULL) {} }; 非递归反转单链表 ListNode* reverse(ListNode *root) { if (root == NULL || root->next == NULL) return root; ListNode *cur = root->next; root->next = NULL; while (c

C#数据结构-单链表

理论基础: 链表是用一组任意的存储单元来存储线性表中的数据元素. 如果结点的引用域只存储该结点直接后继结点的存储地址,则该链表叫单链表(Singly Linked List). 单链表由头引用H唯一确定.头引用指向单链表的第一个结点,也就是把单链表第一个结点的地址放在H中. C#实现: 1接口 引用线性表的接口IListDS<T> 2实现 首先,必须定义一个单链表的节点类.  1 public class Node<T> 2    { 3        private T data

C语言:【单链表】逆置反转单链表

#include<stdio.h> #include<assert.h> #include<stdlib.h> typedef int DataType; typedef struct SListNode {     DataType data;     struct SListNode* next; }SListNode; SListNode* BuyNode(DataType x) {     SListNode* next = (SListNode*)malloc

【LeetCode-面试算法经典-Java实现】【092-Reverse Linked List II(反转单链表II)】

[092-Reverse Linked List II(反转单链表II)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Reverse a linked list from position m to n. Do it in-place and in one-pass. For example: Given 1->2->3->4->5->NULL, m = 2 and n = 4, return 1->4->3->2->

算法题:反转单链表

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 题目:存在一个单链表,头指针为head,实现单链表的反转Node *Reverse(Node *head).  该算法的求解办法有很多,如: 方法1:先顺序变量单链表,将结点保存到栈中,在从栈中弹出结点,重新建立一个新的单链表: 方法2:用<剑指offer>里面给出的算法,用三个指针来实现: 方法3:采用递归实现,是方法2的递归实现形式. 本文主要给出方法2和方法3,在给出具体的代码之前,先要注意几个问题:          (1)如果hea

反转单链表并验证(详解)

单链表优点: 可以动态增加和删除. 不需要定义初始大小. 点链表缺点: 不能随机访问.需要逐个遍历直到找到目标项. 用到动态内存分配和指针,代码复杂度提升,内存泄漏和内存段错误风险提升. 开销大较大,因为是动态分配内存.而且每项需要存储一个额外的指针. 定义单链表: ------------------------------ ------------------------------ | | | \ | | | | val | next |--------------| val | next

反转单链表

ListNode是单链表节点的数据结构,实现见如下代码:package List; /** * Created by Administrator on 2015/10/10. */public class ListNode { //节点的值 private char data; //节点的后续节点 private ListNode next; public ListNode(char data, ListNode next) { this.data = data; this.next = nex

数据结构(一) 单链表的实现-JAVA

数据结构还是很重要的,就算不是那种很牛逼的,但起码得知道基础的东西,这一系列就算是复习一下以前学过的数据结构和填补自己在这一块的知识的空缺.加油.珍惜校园中自由学习的时光.按照链表.栈.队列.排序.数组.树这种顺序来学习数据结构这门课程把. -WH 一.单链表的概念 链表是最基本的数据结构,其存储的你原理图如下图所示 上面展示的是一个单链表的存储原理图,简单易懂,head为头节点,他不存放任何的数据,只是充当一个指向链表中真正存放数据的第一个节点的作用,而每个节点中都有一个next引用,指向下一

java数据结构:单链表常见操作代码实现

一.概述: 本文主要总结单链表常见操作的实现,包括链表结点添加.删除:链表正向遍历和反向遍历.链表排序.判断链表是否有环.是否相交.获取某一结点等. 二.概念: 链表: 一种重要的数据结构,HashMap等集合的底层结构都是链表结构.链表以结点作为存储单元,这些存储单元可以是不连续的.每个结点由两部分组成:存储的数值+前序结点和后序结点的指针.即有前序结点的指针又有后序结点的指针的链表称为双向链表,只包含后续指针的链表为单链表,本文总结的均为单链表的操作. 单链表结构: Java中单链表采用No