实现带头结点的单链表元素就地逆置

题目:试编写在带头结点的单链表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;
}

  • 13
    点赞
  • 94
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值