数据结构练习 单链表的区间翻转(代码与实现原理)

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stdlib.h>

typedef int data_t;
typedef struct node
{
	data_t data;//成员数据类型
	struct node* next;//存放下一节点地址

}listnode, *linklist;

//将链表指定部分翻转
int link_reverse(linklist p, int origin, int terminal);

头文件LinkList.h

#include "LinkedList.h"

int main()
{
	linklist p;
	p = link_creat();

	//测试部分
	int val = 0;
	for (data_t i = 1; i < 6; i++)
	{
		link_insert(p, i, &i);
	}
	link_show(p);
	printf("#######\n\n");
	link_reverse(p, 0, 1);
	link_show(p);
	//
	return 0;
}

 测试文件test.c

#include "LinkedList.h"

int link_reverse(linklist p, int origin, int terminal)
{
	if (p == NULL)
	{
		printf("Pointer is NULL.\n");
		return -1;
	}
	if (origin < 1 || origin >= terminal)
	{
		printf("Input Error.\n");
		//输入区间的起点过小
		//输入区间的起点大于等于终点
		return -1;
	}

	int i = 0;
	linklist head = p;
	linklist tail = p;
	linklist temp;
	linklist rest;
	
	for (int i = 0; i < terminal; i++)
	{
		tail = tail->next;
		if (tail == NULL)
		{
			printf("Input Error.\n");
			//输入区间的终点过大
			return -1;
		}
	}
	rest = tail->next;
	tail->next = NULL;

	for (int i = 0; i < origin - 1; i++)
	{
		head = head->next;
	}
	temp = head->next;
	head->next = NULL;

	while (i < terminal - origin + 1)
	{
		tail = temp;
		while (1)
		{
			if (tail->next == NULL)
			{
				head->next = tail;
				tail->next = rest;
				break;
			}
			else if (tail->next->next == NULL)
			{
				head->next = tail->next;
				head = head->next;
				tail->next = NULL;
				break;
			}
			else
			{
				tail = tail->next;
			}
		}
		i++;
	}
	return 0;
}

 函数实现LinkList.c

实现原理:

拿1-> 2-> 3-> 4-> 5的单链表举例,将第2个到第4个节点进行翻转。

图中p->next是该单链表的头结点,指向该单链表的第一个结点1(p指向的其实是一个数据域为0的结点,这个结点的指针域存放的是这个单链表头结点)

要将第2个到第4个节点进行翻转分为以下三步:

1.        将该单链表待翻转的部分与剩余部分断开。剩余部分分为两部分,指针head指向剩余部分的前半部分最后一个结点,指针rest指向剩余部分的后半部分第一个结点。指针temp指向待翻转部分的第一个结点。

2.        将待翻转部分的最后一个结点连接到剩余部分的前半部分

这个过程中使用了一个指针tail来定位待翻转部分的最后一个结点,该指针初始化时与temp指针指向同一结点然后不断后移直到指向最后一个结点

               

 3.        将head指针重新指向前半部分的最后一个结点,开始新一次的循环

当temp指向的已经是待翻转部分的最后一个元素时,翻转就已经到了最后一步,将三部分依次连接即完成翻转。

这种方法虽然比较麻烦,但很容易理解,可以在不开辟新的动态空间条件下完成翻转。

运行效果如下(其余的函数功能实现在我的上一篇博客中 数据结构单链表C语言实现

        首先生成了一个1-> 2-> 3-> 4-> 5的单链表,通过link_reverse函数将该单链表的第2到第4个节点进行翻转。

将整个链表进行翻转

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值