努力写一个大家都能明白的单链表逆序
这里记录一下,c语言笔试题常见的单链表逆序算法,看了很多别人的教程,觉得写的太过于复杂难懂。决定自写一个。
首先我们要清楚,这里一般笔试要求都是不开辟另外的内存空间。
我们有 header 第一个节点 第二个节点 第三个节点 NULL
我们设立三个指针,一个pre表示逆序后的后节点,cur表示当前节点,temp暂时存储cur(当前节点)的next节点。
我们的思路:
- 逆序初始化,pre为第一个节点,cur为第二个节点,temp为第三个节点
- 相应指针指向改变,原来向后指,改为向前指。(及就是pre->next=NULL(首节点变为尾节点),cur->next=pre(逆序,改变单向链表的方向)
- 再向前移动pre,cur ,temp三个节点, pre=cur,cur=temp,temp=cur->next;(整个操作在while(cur !=NULL)里面,直到pre为尾节点,退出循环)
- 把head指针指向原来的尾节点,也即是新的逆序后的头节点。
具体代码如下:
struct node
{
int a;
struct node * next;
};
struct node *head=NULL;//head,只是一个头指针,这里不是一个标准的链表节点,不过不影响我们逆序
struct node one={1,NULL};
struct node two={2,NULL};
struct node three={3,NULL};
struct node four={4,NULL};
struct node five={5,NULL};
void Node_init()//简单初始化一个链表
{
head=&one;
one.next=&two;
two.next=&three;
three.next=&four;
four.next=&five;
five.next=NULL;
}
void Print_Node(struct node *head)//链表打印函数
{
while(NULL!=head)
{
printf("%d\n",head->a);
head=head->next;
}
}
void Reverse_Node(struct node*Head)//链表逆序函数
{
struct node *pre=NULL;
struct node *cur=NULL;
struct node *temp=NULL;//不能开辟另外的内存,这是用来循环位移的几个指针
/* 1、第一步初始化各节点的位置 */
pre=Head; //刚开始为第一个节点
cur=pre->next; //为第二个节点
pre->next=NULL; //把原来的头节点变成尾节点,所以头节点->next=NULL:
while(cur!=NULL)
{
temp=cur->next; //这里即使所谓的循环位移了
cur->next=pre; //先使得当前节点指向前一个节点,相当于逆序
pre=cur; //再使得前一个节点为当前节点,相当于pre往前走一步
cur=temp; //这里cur往前走一步
//后面就是一直循环,一直逆序了,直到当前节点为NULL,及就是pre为最后一个节点
}
head=pre; //把头指针指向原来的尾节点;及就是逆序后的头节点
}
int main(void)
{
Node_init();
Print_Node(head);
Reverse_Node( head);
Print_Node(head);
return 0;
}
上面代码codeblock编译执行通过
如果还是不能理解可以自己看着代码,或者上面的步骤讲解,画图帮忙理解。