设计一个函数
void LinkReverse(List *pla)
其功能将带头结点的单向链表反转。la是一个带头结点的链表,函数的目的是逆转这个链表,
也就是第一个结点变成最后一个结点,第二个结点变为倒数第二个结点,以此类推。该函数的空间复杂度为O(1),也就是该函数不能定义数组变量和使用动态分配函数。其中List是如下结构体:
typedef struct T_Node{
int d;
struct T_Node *next;
} Node, *List;
如下的main函数执行后
//创建头指针为la的链表
void createlink(List *pla)
{
int i;
Node *p;
*pla = (Node *)malloc(sizeof(Node)); //创建头结点
p = *pla;
for(i = 1; i <=10;i++)
{
p->next = (Node *)malloc(sizeof(Node));
p = p->next;
p->d = i;
p->next = NULL;
}
}
void main( )
{
List la, p;
int i;
createlink(&la);
LinkReverse(&la);
p = la->next;
for(i = 1; i <=10;i++)
{
printf("%4d",p->d);
p = p->next;
}
printf("\n");
}
执行的结果为
10 9 8 7 6 5 4 3 2 1
函数代码如下:
void LinkReverse(List *pla)
{
Node *p,*q;
p=(*pla)->next; /*p为原链表的当前处理节点*/
(*pla)->next=NULL; /*逆置链表初始化为空*/
while(p!=NULL)
{
q=p->next; /*q保留原链表当前处理节点的下一个结点*/
p->next=(*pla)->next; /*将当前处理节点插入表头*/
(*pla)->next=p;
p=q; /*p指向下一个待插入的结点*/
}
}
整段代码如下:
#include<stdio.h>
#include<stdlib.h>
typedef struct T_Node{
int d;
struct T_Node *next;
}Node,*List;
void createlink(List *pla)
{
int i;
Node *p;
*pla = (Node *)malloc(sizeof(Node));
p=*pla;
for(i=1;i<=10;i++)
{
p->next=(Node *)malloc(sizeof(Node));
p=p->next;
p->d=i;
p->next=NULL;
}
}
void LinkReverse(List *pla)
{
Node *p,*q;
p=(*pla)->next;
(*pla)->next=NULL;
while(p!=NULL)
{
q=p->next;
p->next=(*pla)->next;
(*pla)->next=p;
p=q;
}
}
int main()
{
List la,p;
int i;
createlink(&la);
LinkReverse(&la);
p=la->next;
for(i=1;i<=10;i++)
{
printf("%4d",p->d);
p=p->next;
}
printf("\n");
return 0;
}
运行结果:
小结:
逆置插入的过程类似于头插法创建链表。在操作的过程中,引入一个q指针用来保留断开链表的首元节点。