本题要求实现一个函数,将给定的单链表逆转。
函数接口定义:
List Reverse( List L );
```其中List结构定义如下:
```c
typedef struct Node *PtrToNode;
struct Node {
ElementType Data; /* 存储结点数据 */
PtrToNode Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */
L是给定单链表,函数Reverse要返回被逆转后的链表。
裁判测试程序样例:
#include
#include
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();
L2 = Reverse(L1);
Print(L1);
Print(L2);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
5
1 3 4 5 2
输出样例:
1
2 5 4 3 1
List Reverse( List L )
{
List L3,Pnew;
L3=malloc(sizeof(List));
L3->Next=NULL;
while(L->Next!=NULL)
{
Pnew=malloc(sizeof(List));
Pnew->Next=L3->Next;
L3->Next=Pnew;
L3->Next->Data=L->Next->Data;
L=L->Next;
}
return L3;
}
参考GPT和自己的思路:
你的代码有两个问题:
修改后的代码如下:
List Reverse( List L )
{
List L3=NULL, Pnew=NULL;
while(L != NULL)
{
Pnew = malloc(sizeof(struct Node));
Pnew->Data = L->Data;
Pnew->Next = L3;
L3 = Pnew;
L = L->Next;
}
return L3;
}
参考GPT和自己的思路:
你的代码存在两个问题:
1.第一行malloc分配内存的大小应该是sizeof(struct Node)
,而不是sizeof(List)
,因为List是一个指向Node结构体的指针类型,而不是Node类型。
2.在循环中,你没有将L3指向链表的头节点,而是直接在空链表L3的基础上进行操作,导致最终返回的L3中只有一个空节点,没有包含原链表中的任何数据。你可以在函数开始时将L3指向链表头节点,然后在循环中进行修改。
修改后的代码如下:
List Reverse( List L )
{
List L3, Pnew;
L3 = malloc(sizeof(struct Node));
L3->Next = NULL;
PtrToNode p = L;
while (p != NULL)
{
Pnew = malloc(sizeof(struct Node));
Pnew->Data = p->Data;
Pnew->Next = L3->Next;
L3->Next = Pnew;
p = p->Next;
}
return L3->Next;
}
同样的代码也可以使用递归实现,更加简洁:
List Reverse(List L)
{
if (L == NULL || L->Next == NULL)
return L;
List new_head = Reverse(L->Next);
L->Next->Next = L;
L->Next = NULL;
return new_head;
}
其中,递归基为链表为空或者只有一个节点的情况,递归步骤为先递归反转链表的头节点之后的部分,再将头节点添加到链表的末端。
错误比较多,给你个完整的
#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();
L2 = Reverse(L1);
Print(L1);
return 0;
}
List Read(){
List L,head;
int num;
int i;
scanf("%d",&num);
head=L=(List)malloc(sizeof(struct Node));///头结点
L->Next=NULL;
for(i=0;i<num;i++){
L->Next=(List)malloc(sizeof(struct Node));
scanf("%d",&L->Next->Data);
L=L->Next;
}
L->Next=NULL;
return head;
}
/*这里是对不带头结点的链表进行逆转*/
List Reverse( List L ){
List S;
struct Node *temp;//定义一个临时节点,用来存放要从原链表取出即将插入新链表的那个节点
S=(List)malloc(sizeof(struct Node));//定义一个新链表
S->Next=NULL;
while(L!=NULL){
temp=L;//取原链表的第一个节点
L=L->Next;
temp->Next=S->Next;//插入到新链表的头结点后面
S->Next=temp;
}
return S->Next;//返回不带头结点的链表即返回头结点的下一个
}
void Print( List L ){
List N;
N=L;
while(N->Next!=NULL){
printf("%d ",N->Next->Data);
N=N->Next;
}
}
按照输入 输出 样例,修改如下,供参考:
#include <stdio.h>
#include <stdlib.h>
typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
ElementType Data;
PtrToNode Next;
};
typedef PtrToNode List;
List Read() /* 细节在此不表 */
{
List p=NULL,head=NULL,pt=NULL;
int num , i;
scanf("%d",&num);
for(i=0;i<num;i++){
p = (List)malloc(sizeof(struct Node));
p->Next = NULL;
scanf("%d",&p->Data);
if (!head)
head = p;
else
pt->Next = p;
pt = p;
}
return head;
}
void Print( List L ) /* 细节在此不表 */
{
List p;
p = L;
while(p != NULL){
printf("%d ",p->Data);
p=p->Next;
}
printf("\n");
}
List Reverse( List L );
int main()
{
List L1, L2;
L1 = Read();
L2 = Reverse(L1);
Print(L1);
Print(L2);
system("pause");
return 0;
}
/* 你的代码将被嵌在这里 */
List Reverse( List L )
{
List pL = L, pt = NULL;
L = NULL;
while(pL){
pt = pL;
pL = pL->Next;
pt->Next = L;
L = pt;
}
return L;
}