C语言实现单链表反转

 更新时间:2020年07月24日 16:29:44   作者:一码&当先  
这篇文章主要介绍了C语言实现单链表反转,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、理解指针

看懂链表的结构并不是很难,但是一旦把它和指针混在一起,就很容易让人摸不着头脑。所以,要想写对链表代码,首先就要理解好指针。

  有些语言有“指针”的概念,比如 C 语言;有些语言没有指针,取而代之的是“引用”,比如 Java、Python。不管是“指针”还是“引用”,实际上,它们的意思都是一样的,都是存储所指对象的内存地址。

  将某个变量赋值给指针,实际上就是将这个变量的地址赋值给指针,或者反过来说,指针中存储了这个变量的内存地址,指向了这个变量,通过指针就能找到这个变量。

  p->next=q。这行代码是说,p 结点中的 next 指针存储了 q 结点的内存地址。p->next=p->next->next。这行代码表示,p 结点的 next 指针存储了 p 结点的下下一个结点的内存地址。

C语言标准规定,对于一个符号的定义,编译器总是从它的名字开始读取,然后按照优先级顺序依次解析。对,从名字开始,不是从开头也不是从末尾,这是理解复杂指针的关键! 

 对于初学者,有几种运算符的优先级非常容易混淆,它们的优先级从高到低依次是:

定义中被括号( )括起来的那部分。后缀操作符:括号( )表示这是一个函数,方括号[ ]表示这是一个数组。前缀操作符:星号*表示“指向xxx的指针”。

  在本章中我们最多只用到二级指针因此将对二级指针做下说明。比如int **p,是什么意思?

首先看 *p 。 “*”表示P是一个指针。但是是指向什么的指针呢?

在看前面的int* ,int是一个整型类型后面加一个“*”表示整型类型的指针。

  *p就是指向整型类型指针的指针。p保存的是整型类型指针的地址。

二、警惕指针丢失和内存泄漏

  不知道你有没有这样的感觉,写链表代码的时候,指针指来指去,一会儿就不知道指到哪里了。所以,我们在写的时候,一定注意不要弄丢了指针。指针往往都是怎么弄丢的呢?我拿单链表的插入操作为例来给你分析一下。

  指针往往都是怎么弄丢的呢?我拿单链表的插入操作为例来给你分析一下。

  如图所示,我们希望在结点 a 和相邻的结点 b 之间插入结点 x,假设当前指针 p 指向结点 a。如果我们将代码实现变成下面这个样子,就会发生指针丢失和内存泄露。

p->next = x; // 将p的next指针指向x结点;
x->next = p->next; // 将x的结点的next指针指向b结点;

  初学者经常会在这儿犯错。p->next 指针在完成第一步操作之后,已经不再指向结点 b 了,而是指向结点 x。第 2 行代码相当于将 x 赋值给 x->next,自己指向自己。因此,整个链表也就断成了两半,从结点 b 往后的所有结点都无法访问到了。

  对于有些语言来说,比如 C 语言,内存管理是由程序员负责的,如果没有手动释放结点对应的内存空间,就会产生内存泄露。所以,我们插入结点时,一定要注意操作的顺序,要先将结点 x 的 next 指针指向结点 b,再把结点 a 的 next 指针指向结点 x,这样才不会丢失指针,导致内存泄漏。所以,对于刚刚的插入代码,我们只需要把第 1 行和第 2 行代码的顺序颠倒一下就可以了。同理,删除链表结点时,也一定要记得手动释放内存空间,否则,也会出现内存泄漏的问题。当然,对于像 Java 这种虚拟机自动管理内存的编程语言来说,就不需要考虑这么多了。

三、单链表反转的C语言实现

  使用p指向第一个结点,cur指向当前结点,每次把cur->next结点摘掉放在p节点前面。然后更新p结点指向头结点。具体实现代码如下所示

 void revers_list(list1 **l)
 {
   if(!(*l)||!l)
   {
     exit(-1);
   }
 
   list1 *start=*l;
   list1 *start_next=NULL;
 
   while (start->next)
   {
     // 获取当前节点的后继节点 
     start_next = start->next; 
     // 将后继节点摘链 72   
      start->next = start_next->next; 
     // 将后继节点提到最前面 
     start_next->next = *l; 
     // 更新头节点 
     *l = start_next;
   }
 }

到此这篇关于C语言实现单链表反转的文章就介绍到这了,更多相关C语言 单链表反转内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C/C++编程语言中的指针(pointer)你了解吗

    C/C++编程语言中的指针(pointer)你了解吗

    这篇文章主要为大家详细介绍了C/C++编程语言中的指针,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • C语言中改变目录的相关操作函数详解

    C语言中改变目录的相关操作函数详解

    这篇文章主要介绍了C语言中改变目录的相关操作函数详解,分别是fchdir()函数和rewinddir()函数的使用方法,需要的朋友可以参考下
    2015-09-09
  • C++中based for循环的实现

    C++中based for循环的实现

    C++中的范围for循环是一种简洁的遍历容器的方法,本文主要介绍了C++中based for循环的实现,具有一定的参考价值,感兴趣的可以了解一下
    2025-02-02
  • C++类的定义和对象的创建详解

    C++类的定义和对象的创建详解

    本篇文章重点讲解了两种创建对象的方式:一种是在栈上创建,形式和定义普通变量类似;另外一种是在堆上使用 new 关键字创建,必须要用一个指针指向它,下面和小编一起来学习下面为文章的内容
    2021-09-09
  • C语言中动态内存管理图文详解

    C语言中动态内存管理图文详解

    在编写程序时,通常并不知道需要处理的数据量,或者难以评估所需处理数据量的变动程度,下面这篇文章主要给大家介绍了关于C语言中动态内存管理的相关资料,需要的朋友可以参考下
    2022-06-06
  • 对一个数组进行zig-zag重新排列

    对一个数组进行zig-zag重新排列

    本文介绍了“对一个数组进行zig-zag重新排列”,需要的朋友可以参考一下
    2013-03-03
  • C语言二叉树与堆的概念与实现

    C语言二叉树与堆的概念与实现

    这篇文章主要给大家介绍了关于C语言二叉树与堆的相关资料,文章详细记录了他们的相关概念以及如何实现的,通过图文介绍的非常详细,需要的朋友可以参考下
    2021-06-06
  • c++实现reactor高并发服务器的详细教程

    c++实现reactor高并发服务器的详细教程

    这篇文章主要介绍了c++从零实现reactor高并发服务器,包括环境准备和基础知识介绍,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-03-03
  • C++索引越界的解决方法

    C++索引越界的解决方法

    本文主要介绍了C++索引越界的解决方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • C语言宏定义使用分析

    C语言宏定义使用分析

    在宏定义中,“宏名称”和“宏字符串”是通过“空格”来区分的,某些朋友不要混淆了,接下来请祥看本文
    2012-12-12

最新评论