题目:试编写在带头结点的单链表L中对链表的元素进行逆置(所谓就地是指辅助空间复杂度为O(1))
本人第一次在博客发文,希望对网友有用,同时积累数据结构的经验。恳请大佬指正,勿喷
首先,对链表的逆置处理可以根据数组的性质,对链表进行逆置处理,但!!!!链表逆置利用数组时只适用于静态链表,所以不建议利用数组的方法进行处理。因此我们采用了以下的方法。废话不多说,先上代码
方法一
void Inverts_List(PList L)
{
PList p;
p = L->next;
while(p!=NULL)
{
printf("%d\n",p->data);
p = p->next;
}
}
可以发现所谓的逆置只是一个遍历输出函数,仿佛没有什么技术含量(忽略不计),专业术语解释就是:将头节点摘下,然后从第一个节点开始,依次插入到头节点的后面,知道头节点到达最后一个节点,这样就是实现了链表的逆置。或许你没有听懂,开始的时候我也是没有理解透彻,所以介绍了第二种方法,或许可以帮助各位同学理解和分析。
完整代码如下:
#include<stdio.h>
#include<stdlib.h>
/*
编写一个算法实现逆置链表的元素
*/
typedef struct Node
{
int data;
struct Node *next;
}List,*PList;
PList Init_List(PList &L);
void trverse_List(PList L);//不加L等形参也可以,但注意类型必须一致
//个人喜好函数在前面进行声明
int main(void)
{
PList L;
L = (PList)malloc(sizeof(List));
printf("程序开始\n");
Init_List(L);
printf("输出开始\n");
trverse_List(L);
return 0;
}
//这里利用头插法
PList Init_List(PList &L)
{
int x;
L->next = NULL;//保证头节点的后继是空的
scanf("%d",&x);
while(x!=9999)//在建立链表时输入9999时,程序退出建立链表阶段
{
PList a = (PList)malloc(sizeof(List));
a->data = x;
a->next = L->next;
L->next = a;
scanf("%d",&x);
}
return L;
}
void trverse_List(PList L)
{
PList p;
p = L->next;
while(p!=NULL)
{
printf("%d\n",p->data);
p = p->next;
}
}
方法二
不同于方法一,方法二加深了对指针的理解,更加注重对指针的使用。毕竟在数据结构中“指针满天飞”啊!!!废话不多说,直接上代码
PList Inverts_List(PList L)
{
PList pre,p,r;//pre作为临时指针
//依次遍历链表L,并且将节点的指针进行反转
p = L->next;
r = p->next;
//当r为空的时候,p为最后一个节点
p->next = NULL;
while(r!=NULL)
{
pre = p;
p = r;
r = r->next;
//可以理解为后来者居前,
p->next = pre;//指针进行反转
}
L->next = p;
return L;
}
完整代码如下:
#include<stdio.h>
#include<stdlib.h>
/*
编写一个算法实现逆置链表的元素
*/
typedef struct Node
{
int data;
struct Node *next;
}List,*PList;
PList Init_List(PList &L);
void trverse_List(PList L);
PList Inverts_List(PList &L);
int main(void)
{
PList L;
L = (PList)malloc(sizeof(List));
printf("程序开始\n");
Init_List(L);
printf("输出开始\n");
//
Inverts_List(L);
trverse_List(L);
//trverse_List(L);
return 0;
}
PList Init_List(PList &L)
{
int x;
PList b;
b = L;
L->next = NULL;//保证头节点的后继是空的
scanf("%d",&x);
while(x!=9999)
{
PList a = (PList)malloc(sizeof(List));
a->data = x;
a->next = NULL;
b->next = a;
b = a;
scanf("%d",&x);
}
return L;
}
void trverse_List(PList L)
{
PList p;
p = L->next;
while(p!=NULL)
{
printf("%d\n",p->data);
printf("执行\n");
p = p->next;
}
}
PList Inverts_List(PList &L)
{
PList pre,p,r;//pre作为临时指针
//依次遍历链表L,并且将节点的指针进行反转
p = L->next;
r = p->next;
p->next = NULL;
//当r为空的时候,p为最后一个节点
while(r!=NULL)
{
pre = p;
p = r;
r = r->next;
//可以理解为后来者居前,
p->next = pre;//指针进行反转
}
L->next = p;//将头节点的指向调为正确的
return L;
}