数据结构与算法-链表反转

1.输入一个链表的头结点,从尾到头反过来输出每个结点的值。
链表结点定义如下:
struct ListNode
{
      int       m_nKey;
      ListNode* m_pNext;
};
分析:这是一道很有意思的面试题。该题以及它的变体经常出现在各大公司的面试、笔试题中。
看到这道题后,第一反应是从头到尾输出比较简单。于是很自然地想到把链表中链接结点的指针反转过来,改变链表的方向。然后就可以从头到尾输出了。

接下来的想法是从头到尾遍历链表,每经过一个结点的时候,把该结点放到一个栈中。当遍历完整个链表后,再从栈顶开始输出结点的值,此时输出的结点的顺序已经反转过来了。该方法需要维护一个额外的栈,实现起来比较麻烦。

既然想到了栈来实现这个函数,而递归本质上就是一个栈结构。于是很自然的又想到了用递归来实现。要实现反过来输出链表,我们每访问到一个结点的时候,先递归输出它后面的结点,再输出该结点自身,这样链表的输出结果就反过来了。

//递归方法逆序输出
void PrintListReversely(ListNode* pListHead)
{
      if(pListHead != NULL)
      {
            if (pListHead->m_pNext != NULL)
            {
                  PrintListReversely(pListHead->m_pNext);
            }
            // Print this node
            printf("%d", pListHead->m_nKey);
      }
}

//栈方法逆序输出
void PrintListUsingStack(ListNode *pListHead)
{
    Stack s;
    s.top=0;
    ListNode *p;
    p=pListHead;
   do{
       push(&s,p->m_nKey);
       p=p->m_pNext;
   }while(p!=NULL);

   while(!IsEmpty(&s))
   {
       printf("%d/n",pop(&s));
   }
}
时间: 2024-08-26 00:05:42

数据结构与算法-链表反转的相关文章

数据结构与算法-链表反转带头节点

1.输入一个链表的头结点,反转该链表,并返回反转后链表的头结点.链表结点定义如下:    struct ListNode{      int       m_nKey;      ListNode* m_pNext;};分析:这是一道广为流传的微软面试题.由于这道题能够很好的反应出程序员思维是否严密,在微软之后已经有很多公司在面试时采用了这道题. 为了正确地反转一个链表,需要调整指针的指向.与指针操作相关代码总是容易出错的,因此最好在动手写程序之前作全面的分析.在面试的时候不急于动手而是一开始做

数据结构与算法-链表的基本操作---ShinPans

//链表操作:建立.插入.删除.查找.倒置.删除等基本操作 #include<stdio.h> #include<stdlib.h> typedef  struct LNode {       int data;       structLNode *next; }LNode,*Llist; LNode *creat_head();//创建一个空表 void creat_list(LNode *,int);//创建一个长度为n的线性链表 void insert_list(LNode

数据结构与算法(c++)——反转链表

算法概述:要求实现将一条单向链表反转并考虑时间复杂度. 算法分析: 数组法(略): 将列表元素逐个保存进数组,之后再逆向重建列表 点评:实现逻辑最简单,需要额外的内存开销. 移动指针: 通过三个指针逐个从链表头开始逐一反转链表元素的指针 点评:不需要额外的内存开销,会改变原始链表. 递归: 以递归的方式首先找到链表尾部,再逐一反转指针 点评:不需要额外的内存开销,不会改变原始链表. 算法实现: 构建链表结构 /* 节点结构 */ struct NODE { int data; struct NO

数据结构和算法-链表

链表分类 单向链表 双向链表 优势: 删除某个节点更加高效, 可以快速找到前驱节点 可以方便的在某个节点前插入元素 循环链表 当要处理的数据具有环形结构的时候, 适合循环链表. 如约瑟夫环问题 双向循环链表 数组的缺点是大小固定, 一旦声明长度就要占用连续的内存空间, 当空间不够用时更换更大的空间, 此时就需要将原数组的所有数据迁移过去, 比较费时. 链表则可以动态扩容. 数组在查询上可以更快, 链表在插入和删除上更快, 为了结合数组和链表的优点, 有同时使用的情况, 比如一个网站的用户注册,

数据结构——线性表——链表反转

链表反转有两种常见方式.下面从图中详细解释.其中带有部分核心代码,最后上完整代码. 迭代法 //首先定义三个变量    PNODE pre = NULL;    PNODE now = pHead->pNext;    PNODE next = NULL; next = now->pNext;//先保存下一个节点 now->pNext = pre;//当前节点的next指针指向前一个节点 pre = now;//前一个节点赋值为当前节点 now = next;//当前节点赋值为下一个节点

python数据结构与算法——链表

具体的数据结构可以参考下面的这两篇博客: python 数据结构之单链表的实现: http://www.cnblogs.com/yupeng/p/3413763.html python 数据结构之双向链表的实现: http://www.cnblogs.com/yupeng/p/3413800.html 我这里只实现了单链表的类型,代码也相对精简一点: 先构造关于节点的类: 1 class Node: 2 def __init__(self,data=None,next=None): 3 self

数据结构和算法--链表一之单向链表的简单实现

链表在我们java中也是一种基础的数据结构,可以理解成是一种和数组同级的数组结构,正如我们所知,在我们使用这集合ArrayList和LinkedList的时候,总会学习底层数组实现的ArrayList和双向链表实现的LinkedList的区别.在这里,我们将要讲说的是单向链表的简单实现,让我们体会一下链表在实现增删改查的时候是怎么样的一个操作,在和前边涉及到的数组的增删改查进行对比,得到我们学习的结论,数组的增删效率低于链表结构,查改效率高于链表结构! 什么叫做单向链表,我们可以理解为一个一个节

数据结构与算法 - 链表

链表 题型1:数组和链表的区别是什么? 数组和链表的区别主要表现在以下几个方面: 1)逻辑结构.数组必须事先定义固定的长度,不能适应数据动态地增减.当数组中插入.删除数据项时,需要移动其他数据项.而链表采用动态分配内存的形式实现,可以适应数据动态第增减的情况,需要时可以用new/malloc分配内存空间,不需要时使用delete/free将已分配的空间释放,插入和删除元素不需要移动数据项. 2)内存结构.数组从栈中分配空间,链表从堆中分配空间. 3)数组中的数据在内存中是顺序存储的,而链表是随机

数据结构与算法 —— 链表linked list(02)

我们继续来看链表的第二道题,来自于leetcode: 两数相加 给定两个非空链表来代表两个非负整数,位数按照逆序方式存储,它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例: 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807 分析: 因为是位数按照逆序方式存储,所以链表的前置节点是地位,直接循环链表相加,生成新的