反转链表遍历算法-代码实例讲解

  反转链表有几种方法,在这先介绍一种时间复杂度为O(n)的遍历算法。

  反转链表就是让所有节点的链接反向:本指向下一个节点的指针指向上一个节点。因此:

  1. 我们首先想到初始化一个当前指针cur指向与head指向相同的节点,cur=head;
  2. 然后初始化一个prev=NULL, 此时我们就想让cur所指向节点的指针指向prev;因此, cur->next=prev
  3. 但是当cur->next=prev时,问题出现了,我们没有办法继续访问cur指向节点的下一个节点,因为cur->next指向了prev,而不是原来指向的节点。
  因此,需要再引入一个next指针。此时算法变为:
  1. 我们首先想到初始化一个当前指针cur指向与head指向相同的节点,cur=head; prev=NULL;
  2. 当cur不等于NULL的时候,一直循环遍历:
循环内容:
  1. 找出next; 通过next=cur->next;
  2. 让cur所指向节点的指针指向prev,通过cur->next=prev;
  3. 将prev指向cur所指向的节点,即prev前移,通过prev=cur;
  4. cur指针移动到下一个节点,通过cur=next;
循环完毕后,让head指向prev所指向的节点。

代码实例:
//
//  main.cpp
//  
//

#include <iostream>

using std::cin;
using std::cout;
using std::endl;

//Build the node of linked list
struct node{
    int data;
    struct node* next;
};

struct node* newnode(int data){
    //Make the pointer points to the node!
    struct node* linkedlist=new struct node;
    linkedlist->data=data;
    linkedlist->next=NULL;
    return linkedlist;
}

void print(struct node *head){
    struct node *cur;
    cur=head;
    while (cur!=NULL) {
        cout<<cur->data<<" ";
        cur=cur->next;
    }
    cout<<endl;
}

//Reverse the linked list
void reverseLinkedlist(struct node *&head){
    struct node *cur;
    struct node *prev;
    cur=head;
    prev=NULL;
    //如果我们只用cur, prev,我们首先打断cur指向节点到下一个节点的链接,让其指向prev,此时我们再想访问cur指向节点的下一个节点时我们就无法访问,因此还要引入一个next
    struct node *next;
   
    //一直遍历直到cur指向的节点为NULL
    while (cur!=NULL) {
        next=cur->next;
        cur->next=prev;
        prev=cur;
        cur=next;
    }
    head=prev;
}

int main(){
    struct node* head;
    head=NULL;
    struct node* cur=newnode(5);
    head=cur;
    cur->next=newnode(2);
    cur->next->next=newnode(6);
    cur->next->next->next=newnode(1);
    cur->next->next->next->next=NULL;
    
    print(head);
    
    reverseLinkedlist(head);
    
    print(head);
}

注意: head指针一定要通过引用传入,否则head在函数中发生变化不会对调用函数者产生影响,即无法传出。 可以这样理解:不管指向什么类型的指针,指针就起本身就是一种类型,它也有它的存储空间,即存在地址。因此我们用引用传递,其实也是为调用者的传入参数生成了一个新名字而已,其代表都是同一个地址的同一个事物;也因此操作姓名A,也就是操作姓名B。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值