反转单链表。
例如链表为:1->2->3->4。反转后为4->3->2->1
链表的结构体定义如下:
/*链表节点存储的数据*/
typedef int ElemType;
/*链表节点结构*/
typedef struct LinkListNode
{
ElemType data;
struct LinkListNode* next;
} * pNode, LinkListNode;
初始化链表
void InitializeLinkList(preNode* Head) /*用键盘输入初始化一个链表,参数为链表头指针地址*/
{
preNode End = *Head; /*总是指向链表最后一个节点*/
preNode Temp = NULL; /*临时节点,存放当前输入的链表节点*/
int i = 1; /*节点记数*/
int a;
printf("请输入链表数据\n");
/*开始构造不带头节点的单向链表*/
while (1)/*不停地循环接受字符*/
{
Temp = (preNode)malloc(sizeof(LinkListNode)); /*为当前输入的链表节点分配空间*/
Temp->next = NULL;
printf("Node[%d]:", i);
scanf_s("%d", &a);
Temp->data = a; /*接受字符*/
if (Temp->data == 0) /*若输入为0,则结束输入*/
{
Temp = NULL;
break;
}
if (i == 1) /*如果当前输入的是第一个节点,则让头指针指向它*/
{
*Head = Temp;
End = *Head;
}
End->next = Temp; /*将当前输入的节点接到链表尾端*/
End = Temp;
i++;
}
}
既然有了输入,那么随之应该写一个输出函数
/*打印链表*/
void PrintLinkList(preNode p)
{
while (p)
{
printf("%d ", p->data);
p = p->next;
}
}
下面就是用递归实现反转单链表
/*递归实现反转不带头节点的单向链表*/
preNode ReverseLinkList(preNode PreNode, preNode CNode)
{
if (!CNode) /*如果当前节点指针为空,则返回NULL,此种情况只有在*/
return NULL; /*链表头指针为空时才可能执行到*/
if (!CNode->next) /*如果下一节点指针为空,则将当前节点next指针指向上一节点,并*/
{
/*返回当前节点指针,次种情况只有在当前节点为尾节点时才能执行到*/
CNode->next = PreNode;
return CNode;
}
else /*其他节点的情况,先调用递归函数反转后续节点,再反转当前节点*/
{
/*并将递归函数返回来的尾节点指针向上层函数返回*/
preNode p;
p = ReverseLinkList(CNode, CNode->next);
CNode->next = PreNode;
return p; /*返回的是尾节点的指针,即反转后新链表的头指针*/
}
}
下面给出主函数
int main()
{
preNode head = NULL; /*声明头指针*/
InitializeLinkList(&head); /*初始化链表*/
printf("打印原始链表\n");
PrintLinkList(head); /*打印原链表*/
head = ReverseLinkList(NULL, head); /*调用反转函数*/
printf("\n打印反转后的链表\n");
PrintLinkList(head); /*打印反转后的链表*/
return 1;
}