单链表反转

单链表的翻转是一道很基本的算法题。    

typedef struct LNode
{
    int     data;
    struct LNode    *next;
}LNode, *LinkedList;


这个单链表有一个头指针list指向第一个结点,最后一个结点指向NULL,容易理解(可以把头结点当做第一结点处理)。


        方法1:将单链表储存为数组,然后按照数组的索引逆序进行反转。

        方法2:重新建立一个单链表newList,每次将list中的第一个结点放到newList(头结点)后面

        方法3:使用三个指针遍历单链表,逐个链接点进行反转。

        方法1和方法2的问题是浪费空间。一般方法3较为常用,时间复杂度为0(n)。


方法1:比较简单可以参考C字符串数组的反转  http://blog.csdn.net/acpchenpeng/article/details/50162359


方法2:此方法注意新链表的头结点初始化。

LinkedList ReverseSinglyLinkedList(LinkedList list)
{
    LinkedList  newList;    //新链表的头结点
    LNode       *tmp;       //指向list的第一个结点,也就是要摘除的结点
 
    //参数为空或者内存分配失败则返回NULL
    if (list == NULL || (newList = (LinkedList)malloc(sizeof(LNode))) == NULL)
    {
        return NULL;
    }
 
    //初始化newList(头结点)
    newList->data = list->data;
    newList->next = NULL;
 
    //依次将list的第一个结点放到newList的第一个结点位置
    while (list->next != NULL)
    {
        tmp = newList->next;         //保存newList中的后续结点
        newList->next = list->next;       //将list的第一个结点放到newList中
        list->next = list->next->next;     //从list中摘除这个结点
        newList->next->next = tmp;        //恢复newList中后续结点的指针
    }
 
    //原头结点应该释放掉,并返回新头结点的指针
    free(list);
    return newList;
}


方法3:

Node * ReverseList(Node *head)  
{  
    Node *p1,*p2,*p3;  
    if(head==NULL||*head==NULL)  
    return head;  
    p1=head;  
    p2=p1->next;  
    while(p2)             //注意条件  
    {  
        p3=p2->next;       //每次交换两个结点(要改变p2->next的指针,所以必须先保留p2->next)          
        p2->next=p1;  
        p1=p2;             //循环往后  
        p2=p3;  
    }  
    head->next=NULL;   //原先的head已经变成tail,别忘了置空,只有到这步才能置空  
    head=p1;           //p1变成头结点
    return head;  
}  



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值