【单链表】尾插法建立,头插法就地逆置

 

题目:1.请用尾插法建立一个带头结点的单链表,并用头插法完成单链表的就地逆置,输出单链表中的数据,验证程序是否正确。

    看到刚入门单链表的同学在为这些头插法,尾插法迷惑时,我愿意来讲解一下


总体代码:

#include<stdio.h>
#include<stdlib.h>
typedef int datatype;

typedef struct node{
	  
	  datatype num;
	  struct node *next; 	
}Node, * LinkList; 


//函数
void LinkInitialize(LinkList head);			//用于链表初始化
void LinkBuildRear(LinkList head);			//尾插法建立单链表
void LinkPrint(LinkList head);  			//用于链表输出
void LinkReverse(LinkList head);			//就地逆置(迭代法) 
										

int main()
{
	
	Node node1;
	LinkList p;
	p = &node1;
	//结点指针,用于传入函数改变链表内容 
	LinkInitialize(p);				//结点的初始化 
	LinkBuildRear(p);               //链表的尾插法建立 
	printf("打印原链表:\n");
	LinkPrint(p);
	LinkReverse(p);  				//链表的逆置 
	printf("打印逆置后链表:\n");
	LinkPrint(p);
	
	return 0;
}


/*用于链表初始化*/ 
void LinkInitialize(LinkList head)  //先动态分配内存,再进行结点的指针域赋初值 
{
     head = (LinkList)malloc(sizeof(Node));
     head->next = NULL;
} 


/*尾插法建立单链表*/ 

//先定义结点指针 rear , p ;分别用来指向尾结点,新结点;
//接着新结点中存入数据,让新结点成为 rear 的后继结点
//然后rear指向尾结点
//最后新结点创建结束,即输入数据结束;将 rear 的指针域置为 NULL 
void LinkBuildRear(LinkList head)	
{
	LinkList  rear = head , p;
	datatype num1;
	printf("请输入若干个datatype型数据,以-1为结束:\n");
	while(scanf("%d",&num1),num1 != -1)
	{
		p = (LinkList)malloc(sizeof(Node)); //开辟新结点并输入数据 
		p->num = num1;
		
		rear->next = p;			//让新结点作为rear的后继结点 
		rear = p;      			//让rear总是指向尾结点 	
	}
	  rear->next = NULL;	//数据输入结束,即新结点开辟结束 	
}			


/*用于链表输出*/
//先定义一个结点指针,用于指向首元结点
//接着循环遍历输出每个结点的数据域中的数据
//最后为了输出后看起来清晰,记得换行 
void LinkPrint(LinkList head)
{
	LinkList p = head->next;
	
	while(p != NULL)  //循环遍历,直至指向尾结点的后继结点(NULL) 
	{
		printf("%d ",p->num);
		p = p->next; 	
	}
	printf("\n");
}



/*就地逆置(头插法)*/	
//首先定义两个结点指针 p ,q;分别指向首元结点和次首元结点(p用来遍历,q用来头插) 
//接着先让头结点的指针域置为 NULL;
// q先去找 p 所指的结点,让 p 后移遍历链表;
//然后让 q 指向的结点进行头插		
void LinkReverse(LinkList head)
{
	LinkList p , q;
	p = head->next;
	head->next = NULL; 
	
	while(p != NULL)
	{
	   q = p; 
	   p = p->next; 			//指针p用来遍历链表中的结点 
	   
	   q->next =head->next;		//q进行头插 (核心代码) 
	   head->next = q;	
	}
}		 


对于刚接触单链表的同学,可能这些代码会有两个不懂的地方:

1.尾插法建立带头结点的单链表

2.头插法进行就地逆置


 

 1.尾插法图解

 


2.头插法 (就地逆置)图解:

         /*就地逆置(头插法)*/    
首先定义两个结点指针 p ,q;分别指向首元结点和次首元结点(p用来遍历,q用来头插) 
接着先让头结点的指针域置为 NULL;
 q先去找 p 所指的结点,让 p 后移遍历链表;
然后让 q 指向的结点进行头插

      学完这些小知识,其实就地逆置还有一种方法:运用递归的。和题目要求不符,所以针对性地进行解答哦。

 

  • 14
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
好的,我可以帮你解答这个问题。 首先,让我们了解一下尾插法建立单链表的思路: 1. 定义一个头指针和一个尾指针,初始时它们都指向头结点; 2. 定义一个新结点,输入数据; 3. 将新结点插入到尾结点之后,并将尾指针指向新结点; 4. 重复步骤2和3,直到输入完所有数据。 接下来,我们来看一下头插法完成单链表的逆置并输出逆置后的单链表的思路: 1. 定义一个新链表的头结点,并初始化为空; 2. 从原链表的头结点开始,依次取出每个节点,将其插入到新链表的头结点之后; 3. 重复步骤2,直到原链表中的所有节点都被取出并插入到新链表中; 4. 输出新链表的所有节点。 下面是C++代码实现尾插法建立单链表头插法完成单链表的逆置并输出逆置后的单链表: ```c++ #include <iostream> using namespace std; struct ListNode { int val; ListNode* next; ListNode(int x): val(x), next(nullptr) {} }; ListNode* createList() { ListNode* head = new ListNode(0); ListNode* tail = head; int x; while (cin >> x) { ListNode* p = new ListNode(x); tail->next = p; tail = p; } return head->next; } ListNode* reverseList(ListNode* head) { ListNode* newHead = nullptr; while (head) { ListNode* p = head; head = head->next; p->next = newHead; newHead = p; } return newHead; } void printList(ListNode* head) { while (head) { cout << head->val << " "; head = head->next; } cout << endl; } int main() { ListNode* head = createList(); head = reverseList(head); printList(head); return 0; } ``` 希望能够帮到你!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值