zoukankan      html  css  js  c++  java
  • 反转单链表的几种方法

     

     

      先来一个最常见的题目:反转单链表。假设单链表的数据结构定义如下:

      

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

      并且这个单链表有一个头指针list指向第一个结点,最后一个结点指向NULL,很容易理解。

      最容易想到的第一种方法就是重新建立一个单链表newList,每次将list中的第一个结点放到newList后面。注释比较详细,所以就不具体说了,直接看代码吧:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    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;
    }

      第二种方法是每次都将原第一个结点之后的那个结点放在list后面,下图是原始的单链表。单链表反转示例图片

      为了反转这个单链表,我们先让头结点的next域指向结点2,再让结点1的next域指向结点3,最后将结点2的next域指向结点1,就完成了第一次交换,顺序就变成了Header-结点2-结点1-结点3-结点4-NULL,然后进行相同的交换将结点3移动到结点2的前面,然后再将结点4移动到结点3的前面就完成了反转,思路有了,就该写代码了:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    LinkedList ReverseSinglyLinkedList(LinkedList list)
    {
        LNode   *tmp = NULL;
        LNode   *p = NULL;
     
        if (list == NULL)
        {
            return NULL;
        }
        tmp = list->next;
        while (tmp->next != NULL)
        {
            p = tmp->next;
            tmp->next = p->next;
            p->next = list->next;
            list->next = p;
        }
        return list;
    }

      第三种方法跟第二种方法差不多,第二种方法是将后面的结点向前移动到头结点的后面,第三种方法是将前面的结点移动到原来的最后一个结点的后面,思路跟第二种方法差不多,就不贴代码了。

      我只想到这三种方法,如果你还知道其它方法,欢迎留言告诉我,多谢。

  • 相关阅读:
    改造vant日期选择
    css3元素垂直居中
    npm综合
    (转)网页加水印方法
    Mac下IDEA自带MAVEN插件的全局环境配置
    隐藏注册控件窗口
    High performance optimization and acceleration for randomWalk, deepwalk, node2vec (Python)
    How to add conda env into jupyter notebook installed by pip
    The Power of WordNet and How to Use It in Python
    背单词app测评,2018年
  • 原文地址:https://www.cnblogs.com/zengda/p/5568377.html
Copyright © 2011-2022 走看看