您的位置:首页 > 编程语言 > C语言/C++

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

2018-03-03 14:01 447 查看
总是会想,等进入一个相对稳定的公司(环境)后,我再努力,再搞数据结构和算法、再搞懂公司的框架、再学好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;
}


结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: