单链表的逆置是一个非常经典的问题,这里利用两个思想进行解决。

      首先,我们需要看下原理图,其实两个思想都是一样的,都是使后一个的节点的 next 指针指向前一个节点,依次递推,直到第二个节点指向第一个节点,第一个节点的 next 指针指向 NULL。


      第一种方法:

      在链表往前走的过程中,记录前一个节点,当前节点和后一个节点,并使当前节点的 next 指针指向前一个节点,直到最后一个节点指向倒数第二个节点

      算法实现如下:

void reverse_list(LinkList list)
{
LinkedNode *pre = list;
LinkedNode *cur = list->next;
LinkedNode *next = NULL; if(list == NULL || list->next == NULL)
return; /*在这里实现翻转*/
while(cur != NULL)
{
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
list->next = NULL;
list = pre;
print(list);
return;
}

第二种方法

      这里利用递归的思想,首先完成最后一个节点指向倒数第二个,再使倒数第二个指向倒数第三个,。。。直到第二个指向第一个节点,第一个节点指向 NULL,思想和第一种方法正好是相反的

      算法实现如下:

void reverse_the_list(LinkedNode *cur, LinkList *list)
{
LinkedNode *next = NULL;
if(cur == NULL || cur->next == NULL)
{
*list = cur;
}
else
{
next = cur->next;
reverse_the_list(next, list);
next->next = cur;
cur->next = NULL;
}
return;
}

下面给出完整的实现和实验结果:

#include <stdio.h>
#include <malloc.h> typedef int DataType;
typedef struct node
{
DataType data;
struct node *next;
}LinkedNode, *LinkList; LinkList create_list()
{
DataType value[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int len = sizeof(value) / sizeof(DataType);
int i = 0;
LinkedNode *list_head = NULL;
LinkedNode *temp = NULL;
LinkedNode *p = NULL; list_head = (LinkedNode*)malloc(sizeof(LinkedNode));
list_head->data = value[0];
list_head->next = NULL; temp = list_head;
for(i = 1; i < len; i++)
{
while (temp->next != NULL)
{
temp = temp->next;
}
p = (LinkedNode*)malloc(sizeof(LinkedNode));
p->data = value[i];
p->next = NULL;
temp->next = p;
}
return list_head;
} /*打印链表中的各个节点*/
void print(LinkList list)
{
LinkedNode *temp = NULL;
if(list == NULL)
return; temp = list;
while(temp != NULL)
{
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
return;
} void reverse_list(LinkList list)
{
LinkedNode *pre = list;
LinkedNode *cur = list->next;
LinkedNode *next = NULL; if(list == NULL || list->next == NULL)
return; /*在这里实现翻转*/
while(cur != NULL)
{
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
list->next = NULL;
list = pre;
print(list);
return;
} void reverse_the_list(LinkedNode *cur, LinkList *list)
{
LinkedNode *next = NULL;
if(cur == NULL || cur->next == NULL)
{
*list = cur;
}
else
{
next = cur->next;
reverse_the_list(next, list);
next->next = cur;
cur->next = NULL;
}
return;
} int main()
{
LinkList list = NULL;
LinkedNode *temp = NULL;
LinkList list2 = NULL; list = create_list();
print(list);
reverse_list(list); list2 = create_list();
temp = list2;
reverse_the_list(temp, &list2);
print(list2);
return 0;
}

运行结果如下所示:


C语言实现单链表的逆置的更多相关文章

  1. C语言实现单链表,并完成链表常用API函数

    C语言实现单链表,并完成链表常用API函数: 1.链表增.删.改.查. 2.打印链表.反转打印.打印环形链表. 3.链表排序.链表冒泡排序.链表快速排序. 4.求链表节点个数(普通方法.递归方法). ...

  2. YTU 2991: 链表节点逆置(线性表)

    2991: 链表节点逆置(线性表) 时间限制: 1 Sec  内存限制: 128 MB 提交: 14  解决: 6 题目描述 设计一个算法,将一个带头节点的数据域依次为a1,a2,-,an(n> ...

  3. SDUT OJ 数据结构实验之链表三:链表的逆置

    数据结构实验之链表三:链表的逆置 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descri ...

  4. C/C++语言实现单链表(带头结点)

    彻底理解链表中为何使用二级指针或者一级指针的引用 数据结构之链表-链表实现及常用操作(C++篇) C语言实现单链表,主要功能为空链表创建,链表初始化(头插法),链表元素读取,按位置插入,(有序链表)按 ...

  5. SDUT-2118_数据结构实验之链表三:链表的逆置

    数据结构实验之链表三:链表的逆置 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 输入多个整数,以-1作为结束标志,顺序 ...

  6. C语言实现单链表-03版

    在C语言实现单链表-02版中我们只是简单的更新一下链表的组织方式: 它没有更多的更新功能,因此我们这个版本将要完成如下功能: Problem 1,搜索相关节点: 2,前插节点: 3,后追加节点: 4, ...

  7. C语言实现单链表-02版

    我们在C语言实现单链表-01版中实现的链表非常简单: 但是它对于理解单链表是非常有帮助的,至少我就是这样认为的: 简单的不能再简单的东西没那么实用,所以我们接下来要大规模的修改啦: Problem 1 ...

  8. 如何在时间复杂度为O(n)空间复杂度为O(1)的情况下完成链表的逆置

    问题如题目,首先分析,链表的反转的空间复杂度如果为常数级,那么不可能完成从堆中申请数据来完成链表的反转工作,所以问题就转化为了如何将原链表修改/拆解为逆置的链表: 函数形式假定如下  void Inv ...

  9. C语言实现单链表节点的删除(带头结点)

    我在之前一篇博客<C语言实现单链表节点的删除(不带头结点)>中具体实现了怎样在一个不带头结点的单链表的删除一个节点,在这一篇博客中我改成了带头结点的单链表.代码演示样例上传至 https: ...

随机推荐

  1. Spring Cache使用详解

    Spring Cache Spring Cache使用方法与Spring对事务管理的配置相似.Spring Cache的核心就是对某个方法进行缓存,其实质就是缓存该方法的返回结果,并把方法参数和结果用 ...

  2. perl5 第一章 概述

    第一章 概述 by flamephoenix 一.Perl是什么?二.Perl在哪里?三.运行四.注释 一.Perl是什么?      Perl是Practical Extraction and Re ...

  3. Linux 内核的编译系统

    Linux  的编译使用 GNU make 工具来检查整个系统的文件和调用 gcc 工具以及脚本完毕编译源码生成 image 等操作.要了解整个编译系统,我们首先要了解 Linux 内核的 Makef ...

  4. poj2342 Anniversary party【树形dp】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4316097.html   ---by 墨染之樱花 [题目链接]http://poj.org/p ...

  5. 2.4.5 用NPOI操作EXCEL--插入图片

    我们知道,在Excel中是可以插入图片的.操作菜单是“插入->图片”,然后选择要插入图片,可以很容易地在Excel插入图片.同样,在NPOI中,利用代码也可以实现同样的效果.在NPOI中插入图片 ...

  6. SSIS: 使用最大ID和最大日期来增量更新表

    简单三步: 1.  新增变量 MaxID和MaxCreateDate以及Variable 2.  放置一个 Execute SQL  Task ,用SQL 来获取 MaxID和MaxCreateDat ...

  7. Oracle递归sql笔记

    查询一个机构下所辖机构: select * from t00_organ t start with t.organkey=#uporgankey# connect by prior t.organke ...

  8. 猪猪的机器学习笔记(十四)EM算法

    EM算法 作者:樱花猪   摘要: 本文为七月算法(julyedu.com)12月机器学习第十次次课在线笔记.EM算法全称为Expectation Maximization Algorithm,既最大 ...

  9. C++日期和时间

    C++ 日期 & 时间 C++ 标准库没有提供所谓的日期类型.C++ 继承了 C 语言用于日期和时间操作的结构和函数.为了使用日期和时间相关的函数和结构,需要在 C++ 程序中引用 <c ...

  10. jQuery扩展extend一

    把这个扩展写在这里,以后要是忘了可以回头查看. (function(j) {// 这里的j是一个形参,表示传入的jQuery对象,j可以任意填写 j.extend({// 相当于给jQuery对象加上 ...