链表的逆序排列

qq595165543 2016-03-28 07:28:47
写个VOID函数,获取整个列表,反转节点顺序,函数接收传引用参数,指向表头的指针。链表还是这个链表,仅仅只是顺序不一样。相反,函数不能创建和销毁任何节点,仅重新排列。

自学看到这题,苦思不得解,望高人指点。
...全文
154 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_33910202 2016-03-30
  • 打赏
  • 举报
回复
引用 4 楼 chehw_1的回复:
[quote=引用 3 楼 qq_33910202 的回复:] 将第一个与最后一个的数据元素值交换,以此类推,第二个与……是这个意思吗?
不需要数值交换。直接反转每个节点的指针指向即可。 例如:



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

typedef struct sl_node
{
	int data;
	struct sl_node * next;
}sl_node_t;

typedef sl_node_t * sl_list_t; // sl_list_t 是(sl_not_t *)的别名

//*******************************************************
//** sl_list_add: 向单链表的尾部添加数据,返回值为新的尾部指针
//**     last == 当前链表的尾部指针, data == 添加的数据 
sl_node_t * sl_list_add(sl_node_t * last, int data)
{
	sl_node_t * node = (sl_node_t *)malloc(sizeof(sl_node_t));
	assert(NULL != node);
	node->data = data;
	node->next = NULL;	
	if(NULL != last) last->next = node;
	return node;
}

//*******************************************************
//** sl_list_add: 翻转单链表,并将新的表头指针写回到 dst 参数中
//** 返回值:也可以直接将新表头通过返回值返回(这样就无须 * dst 参数)
sl_list_t sl_list_reverse(sl_list_t src, sl_list_t *dst)
{
	sl_node_t * prev = NULL;
	sl_node_t * curr = src;
	sl_node_t * next; 
		
	while(curr)
	{			
		next = curr->next; // 先获取下一个指针
		curr->next = prev; // 反转指针指向		
		if(NULL == next) break; // 如果已经处理到了链表结尾,则结束
		prev = curr;
		curr = next;
	}
	if(NULL != dst) * dst = curr; // 将新的表头指针写入到dst
	return curr;
}

//*******************************************************
//** sl_list_destroy: 释放链表所分配的内存
void sl_list_destroy(sl_list_t sl)
{
	sl_node_t * next = sl;
	while(next)
	{		
		sl = next;
		next = next->next;
		free(sl);
	}
}


int main(int argc, char **argv)
{
#define ITEMS_COUNT (20)

	int i = 0;	
	sl_node_t * last;
	sl_list_t sl = sl_list_add(NULL, i);	// 保存第一次添加时所返回的指针,该指针即为表头指针
	printf("sl = %p\n", sl);
	
	
	last = sl; // 当前的链表尾部指针 == 表头指针	
	// 向链表中添加些数据	
	for(i = 1; i < ITEMS_COUNT; ++i)
	{
		last = sl_list_add(last, i);
	}
	
	// 显示当前链表内容
	last = sl;  // 从表头开始显示
	while(last)
	{
		printf("%3d ", last->data);
		last = last->next;
	}
	printf("\n");
	
	// 反转链表
	sl = sl_list_reverse(sl, &last);
	
	// 显示当前链表内容	
	while(last)
	{
		printf("%3d ", last->data);
		last = last->next;
	}
	printf("\n");
	
	// 释放内存(用C编程时,必须养成这种习惯)
	sl_list_destroy(sl);
	
#undef ITEMS_COUNT
	
	return 0;
}

[/quote] 嗯嗯,学习了(内容少于十个字不能发送?)
starytx 2016-03-29
  • 打赏
  • 举报
回复
DATA *pT = pHead;
DATA *pF = pHead->next;
if(pT)
pT->next = NULL;
while(pF && pT)
{
DATA *p = pF->next;
pF->next = pT;
pT = pF;
pF = p;
}
pHead = pT;

这样就可以反转单链表了
ri_aje 2016-03-29
  • 打赏
  • 举报
回复
遍历链表,把每一个结点插入到另一个链表中,然后调整原头节点,指向这个调整过的链表即可。
chehw_1 2016-03-28
  • 打赏
  • 举报
回复
引用 3 楼 qq_33910202 的回复:
将第一个与最后一个的数据元素值交换,以此类推,第二个与……是这个意思吗?
不需要数值交换。直接反转每个节点的指针指向即可。 例如:



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

typedef struct sl_node
{
	int data;
	struct sl_node * next;
}sl_node_t;

typedef sl_node_t * sl_list_t; // sl_list_t 是(sl_not_t *)的别名

//*******************************************************
//** sl_list_add: 向单链表的尾部添加数据,返回值为新的尾部指针
//**     last == 当前链表的尾部指针, data == 添加的数据 
sl_node_t * sl_list_add(sl_node_t * last, int data)
{
	sl_node_t * node = (sl_node_t *)malloc(sizeof(sl_node_t));
	assert(NULL != node);
	node->data = data;
	node->next = NULL;	
	if(NULL != last) last->next = node;
	return node;
}

//*******************************************************
//** sl_list_add: 翻转单链表,并将新的表头指针写回到 dst 参数中
//** 返回值:也可以直接将新表头通过返回值返回(这样就无须 * dst 参数)
sl_list_t sl_list_reverse(sl_list_t src, sl_list_t *dst)
{
	sl_node_t * prev = NULL;
	sl_node_t * curr = src;
	sl_node_t * next; 
		
	while(curr)
	{			
		next = curr->next; // 先获取下一个指针
		curr->next = prev; // 反转指针指向		
		if(NULL == next) break; // 如果已经处理到了链表结尾,则结束
		prev = curr;
		curr = next;
	}
	if(NULL != dst) * dst = curr; // 将新的表头指针写入到dst
	return curr;
}

//*******************************************************
//** sl_list_destroy: 释放链表所分配的内存
void sl_list_destroy(sl_list_t sl)
{
	sl_node_t * next = sl;
	while(next)
	{		
		sl = next;
		next = next->next;
		free(sl);
	}
}


int main(int argc, char **argv)
{
#define ITEMS_COUNT (20)

	int i = 0;	
	sl_node_t * last;
	sl_list_t sl = sl_list_add(NULL, i);	// 保存第一次添加时所返回的指针,该指针即为表头指针
	printf("sl = %p\n", sl);
	
	
	last = sl; // 当前的链表尾部指针 == 表头指针	
	// 向链表中添加些数据	
	for(i = 1; i < ITEMS_COUNT; ++i)
	{
		last = sl_list_add(last, i);
	}
	
	// 显示当前链表内容
	last = sl;  // 从表头开始显示
	while(last)
	{
		printf("%3d ", last->data);
		last = last->next;
	}
	printf("\n");
	
	// 反转链表
	sl = sl_list_reverse(sl, &last);
	
	// 显示当前链表内容	
	while(last)
	{
		printf("%3d ", last->data);
		last = last->next;
	}
	printf("\n");
	
	// 释放内存(用C编程时,必须养成这种习惯)
	sl_list_destroy(sl);
	
#undef ITEMS_COUNT
	
	return 0;
}

qq_33910202 2016-03-28
  • 打赏
  • 举报
回复
将第一个与最后一个的数据元素值交换,以此类推,第二个与……是这个意思吗?
qq595165543 2016-03-28
  • 打赏
  • 举报
回复
我这里指的是结构指针之间组成的链表,不是stl啊。。。。。 struct{ int a; struct *next; } 这种。。。。
szn_409 2016-03-28
  • 打赏
  • 举报
回复
std::list中不是有sort么

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧