最近临近毕业季,本人本着积累面试经验,学习相关岗位的技能要求的想法,为秋招作准备,试水了下一般的软开岗位的笔试,发现自己有很多的不足,其中遇到一题是要求创建链表并设计反转链表的函数,在网上找了一些资料,谢谢博主的启发(https://blog.youkuaiyun.com/fx677588/article/details/72357389),总结如下:
先贴代码:
#include<iostream>
using namespace std;
#define LEN 5
typedef struct LNode
{
int data;
struct LNode *next;
}LNode;
LNode* Creatlist(int a[],int n) // 建表
{
LNode *head = NULL; // 指向链表第一个数据节点
LNode *tail = NULL; // 指向链表最后一个节点
for(int i=0;i<LEN;i++){
//申请新节点内存,并填进数据
LNode *newnode=(LNode*)malloc(sizeof(LNode));
newnode->data=a[i];
newnode->next=NULL;
if(head==NULL){
//若表头为NULL,说明新节点要作为第一个节点,既做表头也做表尾
head=tail=newnode;
}else{
//否则说明已经存在链表,新节点要连接到表尾,并更新表尾
tail->next=newnode;
tail=newnode;
}
}
//返回链表头节点的指针
return head;
}
void show(LNode *temp ) // 显示表
{
for(int i=0;i<LEN;i++) {
cout<< temp->data<<' ';
temp = temp->next;
}
cout<< endl;
}
/***非递归方式***/
LNode* reverseList(LNode* H)
{
if (H == NULL || H->next == NULL) //链表为空或者仅1个数直接返回
return H;
LNode* p = H, *newH = NULL;
while (p != NULL) //一直迭代到链尾
{
LNode* tmp = p->next; //暂存p下一个地址,防止变化指针指向后找不到后续的数
p->next = newH; //p->next指向前一个空间
newH = p; //新链表的头移动到p,扩长一步链表
p = tmp; //p指向原始链表p指向的下一个空间
}
return newH;
}
/***递归方式***/
LNode* In_reverseList(LNode* H)
{
if (H == NULL || H->next == NULL) //链表为空直接返回,而H->next为空是递归基
return H;
LNode* newHead = In_reverseList(H->next); //一直循环到链尾
H->next->next = H; //翻转链表的指向
H->next = NULL; //记得赋值NULL,防止链表错乱
return newHead; //新链表头永远指向的是原链表的链尾
}
int main()
{
int a[LEN];
for(int i=0;i<LEN;++i)
cin>>a[i];
LNode* first=Creatlist(a,5);
show(first);
LNode* end1=reverseList(first);
show(end1);
return 0;
}
创建链表的过程用图表示如下:
其中反转链表的函数可见前文中的博客链接,有非常详细的图文解释,程序能完美运行。