单链表的创建和反转(C语言)

10 篇文章 0 订阅

总是会想,等进入一个相对稳定的公司(环境)后,我再努力,再搞数据结构和算法、再搞懂公司的框架、再学好shell和python,时间总是充裕的。殊不知秉承着这样的思想,只是吃不起苦而找借口的一种变体罢了。

生活总会以平等的方式来回报你。只要涉及当场手写代码的面试便碰壁,目前为止顺利的只有创业型小公司和外包而已。这想必也反映了我现在的水平吧。我祈求自己以后能将每一天物尽其用,走出自我易满足而选择easy模式,给自己一种“貌似很努力”的而自我感动的泥沼。

再说到面试,链表反转如此基础的题目已经考到第二次了。我以前最害怕写算法,现在看来不写是不行了;根据“面试宝典”来实现一下吧:


首先以一个以0结尾的数组的作为参数,生成单链表。遍历数组直到遇0停止,该链表末元素的next指针为NULL。

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

typedef struct _node{
	int num;
	_node* next;
}node;

node* createlink(int arr[])
{
	int* tmp=arr;
	node* head=(node*)malloc(sizeof(node));
	head->num=0;
	node* cur=head;
	node* nxt;

	while(*tmp!=0)
	{
		nxt=(node*)malloc(sizeof(node));
		nxt->num=*tmp;
		cur->next=nxt;
		tmp++;
		cur=nxt;
	}
	cur->next=NULL;
	return head;
}


打印整个链表,用指针遍历链表,遇NULL停止。

void printlink(node* head)
{
	node* cur=head->next;
	while(cur!=NULL){
		printf("%d ",cur->num);
		cur=cur->next;
	}
	printf("\n");
}


接着便是反转了。首先使用一个指针遍历链表是必需的。然而使用的这个指针却有讲究。

1). 将遍历指针定义为cur,即指向当前元素,cur=head。

如果cur->next=cur即1指向0后,然后cur移到1的位置。进行下次遍历时,由于是单向链表,1和2之间的关系已经被掐断,无法将2指向1。因此,遍历指针定义为cur是不可行的。


2). 将遍历指针定义为nxt,即指向当前元素的下一个元素,cur=head,nxt=cur->head。

考虑到刚才1)仅用到一个cur,由于next关系已经改变,无法访问到下一元素;而现在用到cur和nxt两个,在再次进入循环时,即便cur和nxt的next关系已经被掐断,依然可以让nxt->next=cur即2指向1。当然在nxt指针反转前,要先保存nxt->next供下次循环使用:


然后反转:


最后重置cur和nxt:


2->1的步骤和0->1的原理一样。另外考虑到本链表有头指针,因此指针反转前要判断cur是否是head。如是,则nxt->next=NULL。

当遍历到链表尾时nxt为NULL,则退出循环,将head指向cur。至此完成单链表反转。


代码:

node* reverse(node *head)
{
	if(head==NULL)
		return NULL;
	node *tmp,*cur,*nxt;
	cur=head;
	nxt=cur->next;
	while(nxt!=NULL){
		tmp=nxt->next;
		if(cur==head)
			nxt->next=NULL;
		else
			nxt->next=cur;
		cur=nxt;
		nxt=tmp;
	}
	head->next=cur;
	return head;
}

验证:

int main(int argc,char* argv[],char* envp[])
{
	int arry[]={1,2,3,4,5,6,7,0};
	node* nodhead=createlink(arry);
	printlink(nodhead);
	reverse(nodhead);
	printlink(nodhead);
	return 0;
}

结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值