链表的反转

题目:输入一个链表的头结点,反转该链表,并返回反转后链表的头结点。

struct ListNode
{
      int        data;
      ListNode*  next;
};


分析:首先这是一个单向链表的反转。其次反转后的链表的头变为尾,尾变为头。要实现此功能,就假设当前节点cur,前节点prev,下一个节点next.先看当前成员cur,它中的节点指针,要实现反序,只需要cur->next = prev.但这仅仅是完成了部分工作,往下就是怎么实现循环实现呢?

  那就要把在执行cur->next = prev之前,把cur->next的成员保存下来,即tmp = cur->next;保存下一个节点的目的,是为了实现循环执行。再执行cur->next =prev.这样当前节点的操作已经完成。之后就是把当前节点变为前一节点,把下一个节点变为当前节点。即prev = cur, cur = tmp.再执行循环。

      循环结束后,把实际的尾指针变为NULL,即head->next = NULL.把实际的头指针变为head。即head = prev;

代码:

ListNode *Rever(ListNode *head)
{
    ListNode *prev, *cur, *next, *reverhead;
    /*check memory NULL*/
    if((head == NULL) || (head->next == NULL))
        return 0;
    /*get the link and it is prev from second*/
    prev = head;
    /*get cur link*/
    cur = head->next;
    /*loop change rever*/
    while(cur != NULL)
    {         
        /*save next point*/
        next = cur->next;
        if(next == NULL){
            reverhead = cur;
        }
        /*change cur next point to prev*/
        cur->next = prev;
        /*change cur to prev*/
        prev = cur;
        /*change next to cur*/
        cur = next;
    }
    /*change NULL for head that is tail now*/
    head->next  = NULL;
    /*change the head location*/
    head = prev;
    return reverhead;
} 


为了表达方便,用了四个ListNode,如果想更精炼,可以写成:

ListNode *Rever(ListNode *head)
{
    ListNode *prev, *cur, *next;
    /*check memory NULL*/
    if((head == NULL) || (head->next == NULL))
        return 0;
    /*get the link and it is prev for second*/
    prev = head;
    /*get cur link*/
    cur = head->next;
    /*loop change rever*/
    while(cur != NULL)
    {         
        /*save next point*/
        next = cur->next;
        /*change cur next point to prev*/
        cur->next = prev;
        /*change cur to prev*/
        prev = cur;
        /*change next to cur*/
        cur = next;
    }

    /*change NULL for head that is tail now*/
    head->next  = NULL;
    /*change the head location*/
    head = prev;

    return prev;
}

另外还有一个算法就是递归:

  node* reverse( node* pNode, node*& head)
    {
        if ( (pNode == 0) || (pNode->next == 0) ) // 递归跳出条件
        {
            head = pNode; // 将链表切断,否则会形成回环
            return pNode;
        }

        node* temp = reserve(pNode->next, head);// 递归
        temp->next = pNode;// 将下一节点置为当前节点,既前置节点
        return pNode;// 返回当前节点
    }

这个方法是采用了递归算法,也就是在反转当前节点之前先反转其后继节点,说白了其实就是利用函数的调用堆栈构建了一个临时链表罢了,挺废的一个算法,权当作是写着好玩,没有什么实在的意义。
采用此算法需要注意的是,头结点必须要传入的是引用,因为在递归跳出的时候要切断链表,否则链表将会形成一个回环。

递归算法是网上摘抄,看看即可。

在写程序时,最好不要用递归,想一想所谓的函数也是有入口地址,在运行的过程中,突然又跳到本身函数的入口地址。

你要有胆,你就用。我水平菜,我不敢用。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值