出現位置:第一輪基礎類筆試或技術一面
難度係數:中
面試題目:
實現一個單鏈表的反轉。例如:
10 9 8 7 6 5 4 3 2 1
反轉後應該爲:
1 2 3 4 5 6 7 8 9 10
要求10分鐘內寫出代碼,注意代碼風格及時間複雜度/空間複雜度。
考點分析:
(1)基本概念:鏈表基礎,代碼規範問題,代碼健壯性問題。
(2)對時間複雜度的敏感。
解題思路:
“一問,二畫,三答”
一問:問清題目,跟面試官交流,找出面試官看重什麼,出題的目的是什麼。
二畫:不先寫代碼,先理清思路,在紙上畫一畫。
初步思路如下:
1、額外再申請一個鏈表,使用前插入的方法即可。(涉及到空間複雜度的問題)
2、先找最後一個,再找倒數第二個。(涉及到時間複雜度的問題)
所以,以上兩條都不滿足條件。這時就得和面試官交流是不是重點考察複雜度的問題。
有的面試官直接要求時間複雜度爲O(n)。
則可以有下面的解題思路:
next = temp->next; //一個初始狀態
temp->next = prew; //改變指針的指向,實現反轉
temp = next; //後移一位
prev = temp; //後移一位
循環的條件是temp!=NULL
寫出規範的代碼的話,需要考慮特殊情況:
1、NULL的時候
2、1個節點的時候
代碼如下:
#include <stdio.h>
#include <stdlib.h>
typedef struct node //定義了一個鏈表的結構體
{
int iData;
struct node *next;
}LNode, *LinkList; //typedef 是用後面的兩個名字替代結構體類型名
LinkList Link_insert(LinkList p,int num)
{
LinkList temp = NULL;
temp = (LinkList)malloc(sizeof(LNode)); //爲節點temp動態分配內存
if (NULL==temp)
{
perror("malloc");
//錯誤輸出函數
exit(EXIT_FAILURE);
}
temp->iData=num;
temp->next=p;
p=temp;
return p;
}
void Link_print(LinkList temp)
{
while (temp!=NULL)
{
printf("%d\t",temp->iData);
temp = temp->next;
}
printf("\n");
}
LinkList reverse_link(LinkList list)
{
if (list==NULL || list->next==NULL)
return list;
LinkList temp,prev,next;
//定義3個臨時變量
prev = list;
//prev進行初始化
temp = list->next;
//temp從第二個節點開始(初始化)
prev ->next = NULL;
//第一個節點的next要爲NULL
while (temp != NULL)
//構成一個循環體
{
next = temp->next;
temp->next=prev;
//反轉
prev = temp;
//後移
temp = next;
//後移
}
return prev;
//返回最後一個節點,prev指向最後一個節點,它變成了新的鏈表的頭
}
int main()
{
LinkList head = NULL;
int temp = 0;
int i;
for (i=0;i<10;i++)
{
printf("輸入一個數:");
scanf("%d",&temp);
head = Link_insert(head,temp);
Link_print(head);
}
printf("在反轉後:\n");
head = reverse_link(head);
Link_print(head);
return 0;
}