`
langzhe
  • 浏览: 286380 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

单链表反转 指针坑

    博客分类:
  • c
 
阅读更多

单链表反转 指针坑 

当我看到单链表反转这题目时,感觉这么简单啊。事实很多坑,一不小心就跳进去了。到现在我都记不清跳了多少坑。

写代码时不是死循环就是就是丢数据。 这 其实本质上是 指针的坑。一不留神就over了。

 

因为前面已经实现过各种列表的插入。

1、我首先想到的是从A链表中取出数据再生成一个新的链表B,从表头脑插入这样成了链表的反转了。

就顺手写了下面代码[1],运行进入死循环。

出现错误的原因:

假设,有 A->B->C->D->E这样一个链表

for循环中第一个head默认是A,h->next(A的指向的一个元素)是B。当然调用insert时 head作为参数传入。在insert方法里面参数node 等价于head。 

所以node->next=head  <=> head->next =head; 这样就造成死循环了。

 

又想当然的在reverse中定义了pre [2].照样出错。原因跟上面是一样的,head的next指向了自己。

还犯了一个错误就是单链表最后一个next没有赋值NULL,还有各种尝试就不在一一列举了,总之都是忽视指针指向错误。

 

[1]reverse代码片段
 90 void reverse(void)
 91 {
 92     for(; head; head = head->next){
 93         insert(head);
 94     }
 95 }  
[2]
 90 void reverse(void)
 91 {
 92     link pre = malloc(sizeof pre);
 93     pre = head;
 94     for(; pre; pre = pre->next){
 95         printf("%c\n", pre->element);                                                                      
 96         insert(pre);
 97     }
 98 }
     static link head;
 66 void insert(link node)   
 67 {
 68     if(head==NULL){      
 69        tail = node;      
 70     }
 71     node->next = head;   
 72     head = node;
 73 }
 74

1、重新构造一个head,当同时记住head的下一个元素,并把head的next设置为NULL.

循环遍历前,先取的head->next的对称赋值给curn。curn用来记录遍历位置,并把head的next设置为NULL. head会变成尾,这样保证尾节点指向NULL.

方法1、
 void reverse(void)
163 {
164     link curn;
165     link temp;
166     if(head == NULL){
167         return;
168     }
169     curn = head->next,
170     head->next = NULL;
171     while(curn != NULL){
172         temp = curn;        //保存当前节点
173         curn = curn->next;  //改变curb指向下一个节点                                                                            
174         temp->next = head; // 把head赋值给temp指向的节点
175         head = temp;  //最后把temp赋值给head
176     }
177     return;
178 } 

方法2、
这里实现使用把curn指向的下一个节点保存起来,curn指向的下一个节点改为指向head。然后把curn赋值给head,并把temp赋值给curn
142 void reverse(void)
143 {
144     link curn;
145     link temp;
146     if(head == NULL){
147         return;
148     }
149     curn = head->next,
150     head->next = NULL;
151     while(curn != NULL){
152         temp = curn->next;
153         curn->next = head;
154         head = curn;
155         curn = temp;                                                                                       
156     }
157     return;
158 }  
159 
方法3
 1、如果head 或head->next为空直接返回
 2、进入循环前需要先把pre赋值为NULL,防止出现链表尾元素为非空
 99 void reverse(void)
100 {
101     link pre, cn;
102     if(head==NULL || head->next==NULL){
103         return;
104     }                                                                                                       
106     pre = NULL;             
107     while(head->next){     在循环中pre保存了每次遍历生成的新链表关系
108         cn = head->next;   //保存 当前head节点指向的节点head->next
109         head->next = pre;  //更改head指向 前一个pre保存的节点或NULL,
110         pre = head;           //然后pre在保存当前head
111         head = cn;           //最后从cn中循环中第一个语句保存的heade 指向的节点赋值给head
112     }
113     head->next = pre ;    //退出循环后,head已经是最后一个节点,只需把head 的next指向pre既可
114
115     return;
116 }

 

 

 

  • 大小: 2.4 MB
0
1
分享到:
评论

相关推荐

    C++ 单链表反转 C++ 单链表反转

    单链表反转是一个常见的操作,它将链表中的节点顺序颠倒。给定的代码实现了一个函数`Reverse`来完成这个任务。下面我们将详细讨论这个反转过程。 首先,我们需要检查输入的链表头是否为空。如果为空,则无需反转,...

    Java算法篇-单链表反转详解.pptx.pptx

    总结来说,单链表反转是数据结构与算法学习中的一个重要课题,它考察了对链表操作的理解和掌握,包括节点的创建、遍历、修改指针以及整体链表结构的变换。熟练掌握这一算法,不仅可以提升编程能力,也有助于解决实际...

    C语言实现单链表反转

    "C语言实现单链表反转" C语言实现单链表反转是指在C语言中实现单链表的反转操作,即将链表的结点顺序颠倒过来。这个操作需要对指针有深入的理解,否则很容易出现指针丢失和内存泄漏的问题。 一、理解指针 要想写...

    单链表的就地反转

    在Reverse函数中,我们使用头插法来实现单链表的就地反转,具体来说,就是将链表的每个结点的next指针反转过来。在destroy函数中,我们使用free函数来释放链表占用的内存空间。 在main函数中,我们首先调用initlist...

    已知head为单链表的表头指针,链表中存储的都是整形数据,实现下列运算的递归算法

    已知head为单链表的表头指针,链表中存储的都是整形数据,实现下列运算的递归算法: (1)求链表中的最大值。 (2)求链表中的结点个数。 (3)求所有整数的平均值。

    单链表反转python实现代码示例

    2. 递归实现单链表反转 递归方法则利用函数自身来实现链表的反转。基本思路是从链表的第二个节点开始,依次将每个节点的next指针指向前一个节点,直到链表的末尾。递归函数的终止条件是链表为空或只有一个节点。...

    链表反转的C语言程序

    定义一个5个节点的单链表,然后通过指针的移动调换链表节点的顺序,从而实现链表的反转

    设ha和hb分别是两个带头结点的非递减有序单链表的表头指针

    设ha和hb分别是两个带头结点的非递减有序单链表的表头指针,试设计一个算法,将这两个有序链表合并成一个非递减有序的单链表。要求结果链表仍使用原来两个链表的存储空间,不另外占用其他的存储空间。表中允许有重复...

    python如何实现单链表的反转

    单链表是一种基础的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。在Python中,我们可以使用类来表示链表节点。在本篇内容中,我们将探讨如何用Python实现单链表的反转操作。 首先,我们...

    设head为单链表的头指针,将单链表中元素按递增顺序就地排列

    单链表是一种常见的线性数据结构,每个节点包含两个部分:数据域(用于存储数据)和指针域(指向下一个节点)。在本例中,定义了一个简单的单链表节点结构体 `struct_Node`,其中 `data` 用来存储整型数据,`next` ...

    链表创建,单链表反转,逆序打印等等

    以上就是关于链表创建、单链表反转以及逆序打印的基本介绍。这些操作在面试中经常被考察,理解并熟练掌握它们对于成为一名合格的程序员至关重要。链表作为数据结构的基础,它的应用广泛且灵活,理解和运用好链表能...

    单链表的基本操作面试题

    单链表反转涉及更改每个节点的指针方向,使其指向其前一个节点。可以通过迭代或递归实现。迭代法通常使用三个指针:当前节点、前一个节点和临时节点,依次处理每个节点;递归法则从最后一个节点开始,每次调用自身...

    单链表操作中指针作为函数参数的典型错误.cpp

    单链表操作中指针作为函数参数的典型错误.cpp

    面试单链表问题总结-反转,逆序输出,判环,求交点

    首先,**单链表反转**是一个常见的面试题。单链表的基本结构由节点组成,每个节点包含数据和指向下一个节点的指针。反转链表就是将原本的前后关系颠倒,例如原本的A-&gt;B-&gt;C变成C-&gt;B-&gt;A。反转链表的方法通常有两种:...

    二级指针在单链表中的运用

    在实际编程中,二级指针的应用远不止于此,它还能用于实现其他高级操作,比如链表反转、合并两个有序链表等。因此,理解和熟练掌握二级指针的使用对于提升在数据结构和算法领域的技能至关重要。

    算法-单链表遍历及反转(java)(csdn)————程序.pdf

    单链表反转是指将单链表的顺序颠倒,使得原来最后一个节点变成第一个节点,原来第一个节点变成最后一个节点。 标签解释 由于没有提供标签信息,所以本节不进行解释。 部分内容解释 代码主要包括两个部分:单链表...

    单链表的反转,冒泡和选择排序

    通过这些文件,你可以进一步了解和学习单链表反转、冒泡排序和选择排序的具体实现细节。在实际编程中,理解并熟练掌握这些基础知识是非常重要的,它们不仅在面试中常被问到,也是构建更复杂数据结构和算法的基础。

    List-LinkedList 单链表就地反转

    ### List-LinkedList 单链表就地反转 #### 概述 本文主要介绍单链表的就地反转算法实现,并通过具体的C语言代码示例来解释这一过程。单链表是一种常见的线性数据结构,其中每个元素包含一个指向下一个元素的指针。...

    鼠标指针方案(如反转、黑色、特大)

    标题提及的“鼠标指针方案”包括反转、黑色以及特大等类型,这些都是为了满足不同用户在不同环境下的需求。 首先,我们来探讨一下反转指针方案。反转方案主要是针对那些在白色背景下工作或娱乐的用户,他们在寻找一...

Global site tag (gtag.js) - Google Analytics