分享

单链表翻转

 无名小卒917 2014-08-08
一次遍历链表,原地改变链表。不占用额外资源。
原理:不断的将前后两个节点的前驱和后继关系改变方向。

最后将原头节点变为尾节点,尾节点变为头节点。

 

 

单向链表的反转是一个经常

被问到的一个面试题,也是一个非常基础的问题。比如一个链表是这样的: 1->2->3->4->5 通过反转后成为5->4->3->2->1。最容易想到的方法遍历一遍链表,利用一个辅助指针,存储遍历过程中当前指针指向的下一个元素,然后将当前节点元素的指针反转后,利用已经存储的指针往后面继续遍历。源代码如下:

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

void reverse(linka*& head)
{
     if(head ==NULL)
          return;
     linka*pre, *cur, *ne;
     pre=head;
     cur=head->next;
     while(cur)
     {
          ne = cur->next;// 保留后面节点信息
          cur->next = pre; // 改变前驱后继关系
          pre = cur;//  两个指针平移
          cur = ne;
     }
     head->next = NULL;
     head = pre;
}

 

解释:对于头结点后的下一个结点cur如果不为空,则得到它的下一个结点保存在ne结点中,然后把cur的下一个结点赋为cur的前一个结点pre,这样就实现了cur和它的前一个结点的交换,然后把cur结点赋给pre结点,把ne结点赋给cur,这就实现了cur结点和pre结点都向后移了一个结点,然后循环下去,一直到cur结点为空时,说明已到链表尾,这时把头结点的后一个结点指向空,说明头结点已经成了尾结点了,这个时候把pre结点已经是原链表的最尾端了,如果要实现翻转,则把它赋给头结点。

 

如上图所示,它是先翻转head和p1,使p1指向head,然后pre=cur;cur=ne;到第二次,继续翻转p1,p2,使p2指向p1,然后持续下去,一直到第四次,这时cur为空,而pre已到了原链表的最后一个结点,这时如果head的下一个结点为空,则说明head为链尾了,而pre则变成了链头,然后把它赋给头结点即可。


C#版本

//链表翻转
            public void Reverse()
            {
                 Node<int> p = head;
                Node<int> q = head.Next;
                Node<int> r = new Node<int>();
                while(q!= null)
                {
                    r = q.Next;
                    q.Next = p;
                    p=q;
                    q = r;
                }
                head.Next = null;
                head = p;
            }

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多