3-2-链表 单链表逆转 (20分)

本题要求实现一个函数,将给定的单链表逆转。

函数接口定义:

List Reverse( List L );

其中List结构定义如下:

typedef struct Node PtrToNode; struct Node {
ElementType Data; /
存储结点数据 /
PtrToNode Next; /
指向下一个结点的指针 / }; typedef PtrToNode List; / 定义单链表类型 */

L是给定单链表,函数Reverse要返回被逆转后的链表。

裁判测试程序样例:

 #include <stdio.h>
 #include <stdlib.h>
 
 typedef int ElementType; typedef struct Node *PtrToNode; struct Node {
     ElementType Data;
     PtrToNode   Next; }; typedef PtrToNode List;
 
 List Read(); /* 细节在此不表 */
  void Print( List L ); /* 细节在此不表 */
 
 List Reverse( List L );
 
 int main() {
     List L1, L2;
     L1 = Read();//L1指向链表一开始的首元素
     L2 = Reverse(L1);//L1还是指向链表一开始的首元素 但这是这个元素已经在链表尾巴了
     Print(L1);
     Print(L2);
     return 0; }
 
 /* 你的代码将被嵌在这里 */

输入样例:

5
1 3 4 5 2

输出样例:

1
2 5 4 3 1

//法一:
List Reverse(List L) {
    List head=NULL, temp=NULL;
    while (L)
    {
        temp = L->Next;
        L->Next = head;
        head = L;
        L = temp;
    }
    return head;
}
//类似法二 也是头插法 但法二更好理解
//法二:
List Reverse(List L)
{
    List p = L;
    L = NULL;
    while (p)
    {
        List temp = p;
        p = p->Next;
        temp->Next = L;
        L = temp;
    }
    return L;
}
//先设定一个指针p指向链表
//然后将指针L置空(指向空)
//通过**头插法**将p的各元素逐渐接到L上
//返回L

法二有一个注意点就是:
指针的指向:
假设链表一开始是1 2 3 4 5,链表的输入是采用尾插法,所以一开始头节点是首元素1的(L1指向1),通过逆序函数以后,链表变成了5 4 3 2 1,因为是通过头插法逆序的所以指针的头节点为5(指向最后一个元素)
但是,在逆序的过程中,我们只是改变了链表各节点的链接顺序,而没有改变原指针的指向,所以第一行输出的只有1(L1指向的是1,链表此时是5 4 3 2 1,L1指向尾巴)
类似这个;
交换的是指针 但指针的指向是不变的
类似这个

输入三个数:1 2 3
在这里插入图片描述
读入和输出的函数:

List Read()
{
    int len = 0;
    int num = 0;
    PtrToNode list = NULL;
    PtrToNode last = NULL;

    scanf("%d", &len);
    if (len == 0)
        return NULL;

    scanf("%d", &num);
    list = (PtrToNode)malloc(sizeof(struct Node));
    list->Data = num;
    list->Next = NULL;
    last = list;
    len--;
    while (len) {
        scanf("%d", &num);
        PtrToNode node = (PtrToNode)malloc(sizeof(struct Node));
        node->Data = num;
        node->Next = NULL;
        last->Next = node;
        last = node;
        len--;
    }
    return list;
}
void Print(List L)
{
    if (L == NULL)
        return;
    while (L != NULL) {
        printf("%d ", L->Data);
        L = L->Next;
    }
    putchar('\n');
}

然后上面两种方法借鉴了一下两篇博客
//总的来说都是头插法,就是写的不一样
下面这个是自己最开始写的 emmm奇奇怪怪还很麻烦

List Reverse(List L)
{
    List head;
    List p = L;
    head = NULL;
    if (L == NULL) {
        return L;
    }
    while (p)
    {
        List q = p;
        List temp = (List)malloc(sizeof(struct Node));
        temp->Next = NULL;
        temp->Data = p->Data;
        temp->Next = head;
        head = temp;
        p = p->Next;
        //free(q);
    }
    L->Next = NULL;

    return head;
}

posted on 2021-01-22 10:06  不依法度  阅读(52)  评论(0)    收藏  举报

导航