算法初探001——单链表反转

单链表的反转问题是一道很基本的问题。题目如下:

有一个单链表 1 ->2->3->4->5->6 反转后链表为:6->5->4->3->2->1.

方法一

解析:可以使用三个指针pre ,temp,next对逐个节点进行反转。详细流程如下:

(4) 初始状态

pre = head;
tmp = head->next;
pre->next = null;

(2)第一次循环:

next = tmp->next;
tmp->next = pre;

pre 和 tmp 后移一位 , 第一次循环结束,第一个节点指向了头节点。

pre = tmp;
tmp = next;

(3) 第二次循环

next = tmp->next;
tmp->next = pre;

pre = tmp;
tmp = next;

(4)如此循环下去,直到最后一个节点被反转。

具体代码如下:

LinkList reverseLinkList(LinkList head){
if(head == NULL || head->next == NULL)
    return head;
//创建三个辅助指针pre,tmp,next
LinkList pre,tmp,next;
//初始化 pre , tmp
pre = head;
tmp = head->next;
pre->next =NULL;
//开始遍历
while(tmp != NULL){
    next = tmp->next;
    tmp->next = pre;
    pre = tmp;
    tmp = next;![这里写图片描述](http://img.blog.csdn.net/20151016235255459)
}
head = pre;
return head;
}

方法二

解析:从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,最后将第一个节点挪到新表的表尾。

(1)初始状态

p = head->next;

(2)开始循环。第一次循环将节点3插入到节点1后面(代码中的步骤分别对应下图中的步骤)

while(p->next){
  q = p->next;
  (1) p->next =q->next;
  (2) q->next = head->next;
  (3) head->next = q;
}

(3)将第一个节点加到链表尾部

    (1)p->next=head;//相当于成环
    (2)head=p->next->next;//新head变为原head的next
        p->next->next=NULL;//断掉环 

具体代码如下:

LinkList reverseLinkList(LinkList head){
if(head == NULL || head->next == NULL)
    return head;
LinkList p,q;

p = head->next;

//开始遍历
while(p->next){
  q = p->next;
  p->next =q->next;
  q->next = head->next;
  head->next = q;

}
  p->next=head;//相当于成环
    head=p->next->next;//新head变为原head的next
    p->next->next=NULL;//断掉环
    return head;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-19 15:43:33

算法初探001——单链表反转的相关文章

单链表反转问题

单链表反转问题 基本问题 如何将单链表反转? 算法实现 /** * * Description: 单链表反转. * * @param head * @return ListNode */ public static ListNode reverseList(ListNode head) { if (head == null) { return head; } ListNode prev = null; ListNode current = head; ListNode next = null;

时间复杂度为O(n)的非递归单链表反转【算法导论课后题】

单链表反转:1->2->3->4... 思路:先将1指向3,2指向1,结果为2->1->3->4,然后循环将3插入到2之前 <span style="font-size:18px;">void reverseLinkedList(List head) { List tmp,p; if(head==null) { return ; } tmp=head->next; while(tmp->next !=null){ p=tmp-

单链表反转(Singly Linked Lists in Java)

单链表反转(Singly Linked Lists in Java) 博客分类: 数据结构及算法 Java代码   package dsa.linkedlist; public class Node<E>{ E data; Node<E> next; } Java代码   package dsa.linkedlist; public class ReverseLinkedListRecursively { public static void main(String args[])

单链表反转(2)

今天会介绍另外一种反转单链表的方法,对于单链表反转这一类的算法,最重要的思想就是用临时变量来记住需要记住的节点.一个不够,那就用两个,或者用三个临时变量. 这次还是以图表来表现算法的过程,不同于上一篇,这次的头节点使用链表中的第一个节点. 该方法的思想就是遍历每个节点,将其插入到第一个节点之后. 如下图为链表的初始状态: 为了不断链,先将 P2 的后驱节点指向 P3 的后驱节点. 将P3插入 P1 和 P2 之间,也就是 将 P1 的后驱指向 P3.将 P3 的后驱指向 P2 P3 指向 P2

单链表反转的2种方法

1 public class ReverseDemo { 2 3 /** 4 * 单链表反转的两种方法 5 */ 6 public static void main(String[] args) { 7 Node head =new Node("a"); 8 Node node2=new Node("b"); 9 Node node3=new Node("c"); 10 head.setNext(node2); 11 node2.setNext(

链表 单链表反转

思路1:O(n^2). “狸猫换太子”,不进行改动链表结构,只首尾交换len/2次.但是在本函数中用到了定位函数,定位函数实际上是遍历了一遍整个链表,所以综合效率很低,达到O(n^2). //单链表反转(O(n^2)) void reverseList(Node* Head) { int count = numOfNodes(Head); //首尾交换 for(int i=1; i<=count/2; i++) { Node* p1 = locateNodeI(Head, i); Node* p

009实现一个算法来删除单链表中的一个结点,只给出指向那个结点的指针(keep it up)

呵呵,这个题不能直接删除已知的结点,因为是单链表,不知道前驱,只知道 后继结点,直接删除会使链表断开.不过我们可以删除已知结点的后继结点, 把后继结点的值赋值给已知结点. #include <iostream> struct Node { int data; Node* next; }; bool removeNode(Node* vNode) { if (vNode == NULL || vNode->next == NULL) return false; Node* pNext =

实现一个算法从一个单链表中返回倒数第n个元素(keep it up)

我们维护两个指针, 它们之间的距离为n.然后,我将这两个指针同步地在这个单链表上移动,保持它们的距离 为n不变.那么, 当第二个指针指到空时,第一个指针即为所求. #include <iostream> struct Node { int data; Node* next; }; void initList(Node* vNode) { for (int i=0; i < 20; ++i) { Node* TempNode = new Node; TempNode->data =

cc150:实现一个算法来删除单链表中间的一个结点,只给出指向那个结点的指针

实现一个算法来删除单链表中间的一个结点,只给出指向那个结点的指针. 例子: 输入:指向链表a->b->c->d->e中结点c的指针 结果:不需要返回什么,得到一个新链表:a->b->d->e 解答 这个问题的关键是你只有一个指向要删除结点的指针,如果直接删除它,这条链表就断了. 但你又没办法得到该结点之前结点的指针,是的,它连头结点也不提供.在这种情况下, 你只能另觅他径.重新审视一下这个问题,我们只能获得从c结点开始后的指针, 如果让你删除c结点后的某个结点,那