对单链表实现就地逆置

70 篇文章 3 订阅
30 篇文章 11 订阅

        对单链表实现就地逆置 

/*
对单链表实现就地逆置 
*/
#include <stdio.h>
#include "malloc.h"

typedef struct LNode{
	int data;
	struct LNode *next;
}LNode,*LinkList;//线性链表类型

//逆置 
//先把头结点后一个结点i放在末尾,然后在之前末尾结点和当前末尾结点i之间插入结点如:1 2 3 4 -->2 3 4 1 --> 4 3 2 1 
void inverse(LinkList a)
{
	//注意有个 头结点这样就转化为 把第一个放在末尾知道,最后一个元素(标识)放到了头,形式上就逆置了
	LinkList head = a;//头结点
	LinkList p = head->next;
	//找到最后一个元素,并标识为p指向
	while(p->next != NULL)
	{
		p = p->next;
	}
	//把头结点后一个结点i放在末尾
 	LinkList q = head->next;
 	
 	head->next = q->next;//剔除头结点后一个结点 
 	q->next = NULL;//初始化这个被剔除结点
 	p->next = q;//链接到 末尾
 	LinkList tail = q;//tail指向插入点的后一个结点,p始终指向最开始的末尾结点4 
 	//开始进行剩余结点的逆置,插入到上述变为2 3 4 1则在4 1中插入首结点2为3 4 2 1然后4 2插入3为4 3 2 1逆置完成 
	while(1)//始终保持 在最初的尾结点p后插入结点 
	{
		//若q等于p了说明最后一个结点到了首结点,结束循环
		q = head->next;//初始化q指向当前 头结点后一个结点 
		if(q == p)//后一个结点 等于 最后一个结点 
		{
			break;//逆置完毕 退出 
		}
		//否则继续逆置
		head->next = q->next;//剔除当前 首结点(头结点后一个结点)
		q->next = tail;//首结点 指向插入点的后一个结点 
		p->next = q;   //前一个结点next指向该结点
		tail = q;//插入点下一个结点更新 
		
	}
 	
	return;
}

//打印 单链表 元素 
void prin_Link(LinkList a);
//释放链表 
void free_link(LinkList a);
//构造一个单链表 
LNode * create_list();//返回头结点地址 

int main()//main* 
{
	LNode * a;//指向首结点的 指针 
	
	//构造单链表,并添加数据 
	a = create_list();//a接收 首结点 
	
	//查看构造结果
	prin_Link(a); 
	
	//逆置 
	inverse(a);
	//查看逆置结果
	prin_Link(a); 
	
	//程序结束,释放链表 
	free_link(a);
	
	return 0;
}

//构造一个单链表 
LNode * create_list()
{
	LinkList a;
	LinkList q,p;
	int size = sizeof(LNode);//获取结点空间 
	a = (LinkList)malloc(size);//当作头结点 不保存数据,可以使删除算法统一 
	a->next = NULL;
	a->data = 0;
	 
	
	q = (LinkList)malloc(size);//当作头结点 不保存数据
	q->next = NULL;
	q->data = 3;
	a->next = q;//q这里作为第一个 有数据结点

	for(int i = 4;i < 13;i ++)
	{
		//初始一个结点 
		p = (LinkList)malloc(size);
		p->next = NULL;
		p->data = i;
		
		q->next= p;//q下一个结点指向新创建的p结点 
		q = p;   //q 移到p的位置 
		p = p->next;//p指向NULL 
	}
	return a;//返回 首结点 
} 

//打印 单链表 元素 
void prin_Link(LinkList a)
{
	LinkList p = a->next;
	
	while(p != NULL)
	{
		printf("%d ",p->data);
		p = p->next;
	}
	printf("\n");
	return;
}
//释放链表 
void free_link(LinkList a)
{
	LinkList p = a->next;
	while(p != NULL)
	{
		//从头结点后一个位置,开始释放 
		a->next = p->next;
		free(p);
		p = a->next;
	}
	
	//最后释放 头结点
	free(a); 
	a =NULL;//初始指针 
	return;
}

  • 4
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值