c语言 链表逆置

链表逆置是笔试中的常见考题,笔者实现了两种不同的实现

1.非递归实现:

基本思想:

用两个指针保存,当前结点的父节点(上一个结点)和子节点(下一个结点)如图1所示;改变next指针指向父节点,然后更新父节点和当前结点,如图2所示;

循环指导当前结点的子节点为空,如图3所示;

代码实现:

 

/*********************************************************************************/
/* 非递归翻转:逆序要使当前的结点的NEXT指向,前面一个结点。因此记录结点当前的next*/
/* pre作为操作对象参数,本身不发生变化;cur->next指针要改变,作为操作对象;    */
/* cur->next->next作为操作对象的保存对象,在操作过程中保存下一个变量,使当前变量的下一个指针指向前一个变量*/
/********************************************************************************/
//程序设计中要先明确:参数变量(不发生改变),操作对象(发生改变),保存变量
int incover_list_3(pnode * plist)
{
	pnode pre,cur,next;
	pre = * plist;
	cur = pre->next;
	pre->next =NULL;
	while (cur ->next)
	{
		next =  cur->next;
		printf("cur data is %d\n", cur->key);
		cur->next = pre;
		pre = cur;
		cur = next;
	}
	cur->next = pre;
	*plist = cur;
  return 0;
}


2.递归实现

递归思想用于实现具有“先进后出”“后进先出”的访问顺序的函数结构。链表逆转的实现即具有这种特点:头结点先进栈,后续结点依次进栈。然后从后向前改变next指针。

因此链表的逆置可以用递归来实现。

实现过程:

实现1:递归中返回子节点;

/************************************************************************/
/* 递归实现链表翻转,递归中返回子节点的指针                                                     */
/************************************************************************/
pnode  incover_list_2(pnode p, pnode *plist)
{
	if (!p->next)
	{
		*plist = p;
		return p;
	}
	else
	{
		//引进子节点到父节点,递归保证了从低到顶
		pnode ptmp = incover_list_2(p->next,plist);
		ptmp->next = p;
		p->next = NULL;
		return p;
	}
}

2.直接改变子节点的next指针

/************************************************************************/
/* 递归实现链表翻转:直接到底部,从下向上                              */
/************************************************************************/
/*递归实现*/
void incover_list(pnode pl, pnode *plist)
{
	if (!pl || !(pl->next))
	{
		*plist = pl;
	}
	else
	{
		//pnode pnext = pl->next;
		//递归调用到底部,从底部向上步
		incover_list( pl->next, plist);
		pl->next->next = pl;
		pl->next = NULL;
	}
}


3.测试代码(全)

#include <stdio.h>
#include <stdlib.h>
typedef int nodetype;
typedef struct node
{
	nodetype key;
	struct node * next;
}*pnode;
/************************************************************************/
/* 递归实现链表翻转:直接到底部,从下向上                              */
/************************************************************************/
/*递归实现*/
void incover_list(pnode pl, pnode *plist)
{
	if (!pl || !(pl->next))
	{
		*plist = pl;
	}
	else
	{
		//pnode pnext = pl->next;
		//递归调用到底部,从底部向上步
		incover_list( pl->next, plist);
		pl->next->next = pl;
		pl->next = NULL;
	}
}
/************************************************************************/
/* 递归实现链表翻转,递归中返回子节点的指针                                                     */
/************************************************************************/
pnode  incover_list_2(pnode p, pnode *plist)
{
	if (!p->next)
	{
		*plist = p;
		return p;
	}
	else
	{
		//引进子节点到父节点,递归保证了从低到顶
		pnode ptmp = incover_list_2(p->next,plist);
		ptmp->next = p;
		p->next = NULL;
		return p;
	}
}
/*********************************************************************************/
/* 非递归翻转:逆序要使当前的结点的NEXT指向,前面一个结点。因此记录结点当前的next*/
/* pre作为操作对象参数,本身不发生变化;cur->next指针要改变,作为操作对象;    */
/* cur->next->next作为操作对象的保存对象,在操作过程中保存下一个变量,使当前变量的下一个指针指向前一个变量*/
/********************************************************************************/
//程序设计中要先明确:参数变量(不发生改变),操作对象(发生改变),保存变量
int incover_list_3(pnode * plist)
{
	pnode pre,cur,next;
	pre = * plist;
	cur = pre->next;
	pre->next =NULL;
	while (cur ->next)
	{
		next =  cur->next;
		printf("cur data is %d\n", cur->key);
		cur->next = pre;
		pre = cur;
		cur = next;
	}
	cur->next = pre;
	//pre->next = NULL;
	*plist = cur;
  return 0;
}
int insert_list(pnode * plist,nodetype data)
{
	pnode p;
	if (!(*plist))
	{
		p = (pnode)malloc(sizeof(pnode));
		if (!p)
		{
		   printf("malloc node failed\n");
		   return -1;
		}
		p->key = data;
		p->next= NULL;
		*plist = p;
		return 0;
	}
	pnode pl= *plist;
	p = (pnode)malloc(sizeof(pnode));
	if (!p)
	{
	   printf("malloc node failed\n");
	   return -1;
	}
	p->key = data;
	p->next= NULL;
	while (pl->next)
	{
		pl = pl->next;
	}
	pl->next = p;
	printf("%d next is %d\n", pl->key, pl->next->key);
	return 0;
}
void print_list(pnode plist)
{
	pnode pl;
	pl = plist;
	printf("list is ");
	while(pl)
	{
		printf("%d,",pl->key);
		pl= pl->next;
	}
	printf("\n");
}
/************************************************************************/
/* 递归实现链表输出:从后向前                                           */
/************************************************************************/
//凡是实现先进后出的逻辑顺序的函数,都可以用递归来实现
void printf_list2(pnode plist)
{
     if (plist)
     {   
		 
		 printf_list2(plist->next);
		 printf("%d,", plist->key);
     }
}
int main()
{
	pnode  plist = NULL;
	printf("sizeof double is %d\n", sizeof(double));
	printf("sizeof float is %d\n", sizeof(float));
	int a[10]= {1,2,3,4,5,6,7,8,9,10};
	int len = 10,i=0;
	for (i=0;i<10;i++)
	{
        insert_list(&plist, a[i]);
		printf("insert %d\n", a[i]);
	}
	print_list(plist);
	printf("倒序输出");
	 (plist);
	printf("\n");
	//print_list(incover_list(plist));
	//incover_list(plist, &plist);
	//incover_list_2(plist, &plist);
	incover_list_3(&plist);
	printf("逆置后输出:");
	print_list(plist);
	return 0;
}



 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言链表的代码可以如下编写: ```c #include <stdio.h> #include <stdlib.h> // 定义链表节点结构体 typedef struct Node { int data; // 数据域 struct Node* next; // 指向下一个节点的指针 } Node; // 创建节点 Node* createNode(int data) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->next = NULL; return newNode; } // 链表函数 Node* reverseList(Node* head) { Node* prev = NULL; // 当前节点的前一个节点 Node* current = head; // 当前节点 Node* next = NULL; // 当前节点的后一个节点 while (current != NULL) { next = current->next; current->next = prev; prev = current; current = next; } return prev; } // 打印链表 void printList(Node* head) { Node* temp = head; while (temp != NULL) { printf("%d ", temp->data); temp = temp->next; } printf("\n"); } int main() { Node* head = createNode(1); head->next = createNode(2); head->next->next = createNode(3); head->next->next->next = createNode(4); head->next->next->next->next = createNode(5); printf("原链表:"); printList(head); head = reverseList(head); printf("后的链表:"); printList(head); return 0; } ``` 这段代码定义了一个链表节点结构体Node,其中包括一个数据域和一个指向下一个节点的指针域。接着定义了创建节点函数createNode用于创建新的链表节点。 然后,代码中实现了链表函数reverseList,该函数使用三个指针prev、current和next来实现链表。在过程中,首先将current的next指针指向prev,然后依次更新prev、current和next指针的值。最后返回prev指针作为后的链表的头指针。 在主函数中,首先创建一个包含5个节点的链表。然后打印原链表,调用reverseList函数对链表进行,并打印后的链表。最后返回0,表示程序正常运行结束。 以上就是使用C语言实现单链表的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值