筆試or面試 尋找單鏈表倒數第n個元素

2021-06-27 05:05:16 字數 4216 閱讀 4827

在各種面試筆試中,單鏈表考察的最多。其中有一道經典的題目「尋找單鏈表倒數第n個元素」。

如果僅僅是這麼問,大多數人想到這不是很簡單麼:先遍歷整個鍊錶獲知整個鍊錶長度l,然後再l-n+1個節點就是所求節點。

但很顯然面試官不滿足於這種問題,而是「一次遍歷尋找單鏈表倒數第n個元素」。這樣的話,該如何找到思路呢?

首先,我們來弄懂幾個細節:

正序和逆序之間的關係:倒數第n個節點的位置=(鍊錶長度-n+1)個節點所在位置。

比如說,鍊錶為:3,4,5,6,7,8,9,我們要查詢倒數5個節點,也就是正數第(7-5+1)=3節點處。到現在問題就變成了,如何合理的設定迴圈次數移動指標。

由於乙個遍歷鍊錶時,我們通過指標只能控制是否到鍊錶末尾(比如p->next!=null),因此我們考慮新增另外乙個指標(p),通過設定這個指標的指向鍊錶的不同位置,來控制另外乙個指標(p1)移動的次數。因此思路為:

建立兩個指標,第乙個先走n步,然後第2個指標也開始走,兩個指標步伐(前進速度)一致。當第乙個結點走到鍊錶末尾時,第二個節點的位置就是我們需要的

倒數第n個節點的值。

**如下:

#include#include#includetypedef int elemtype;

typedef struct nodenode;

//1、初始化鍊錶

void init(node** pnode)

//1、建立鍊錶

node* create(node* phead)

memset(p1, 0, sizeof(node));

printf("輸入節點值(非正數結束):");

scanf_s("%d", &p1->element);//輸入新節點

p1->next = null;

while (p1->element > 0)

else

p2 = p1;//重新讓p2做尾節點

p1 = (node*)malloc(sizeof(node));

if (p1 == null || p2 == null)

memset(p1, 0, sizeof(node));

printf("輸入節點值(非正數結束):");

scanf_s("%d", &p1->element);

p1->next = null;

} printf("鍊錶建立成功\n");

return phead;

}//列印鍊錶

void print(node* phead)

else

printf("\n"); }}

//清空鍊錶

void clear(node* phead)

while (phead->next != null)

printf("鍊錶清空\n");

}//鍊錶長度

int size(node* phead)

printf("鍊錶長度%d\n", size);

return size;

}//鍊錶是否為空

int isempty(node* phead)

printf("鍊錶非空\n");

return 0;

}//獲取指定位置的元素

elemtype get(node* phead, int pos)

if (phead == null)

while (phead != null)

phead = phead->next;

} if (i < pos)

return phead->element;

}elemtype *getaddr(node* phead, elemtype x)

if (x < 0)

while ((phead->element != x) && (phead->next != null))

if ((phead->element != x) && phead != null)

if (phead->element == x)

return &(phead->element);

}//修改指定位置的元素

int modify(node* pnode, int pos, elemtype x)

if (pos < 1)

while (phead != null)

phead = phead->next;

} if (i < pos)

pnode = phead;

pnode->element = x;

printf("modifyelem函式執行,修改%d出值為%d\n",pos,x);

return 1;

}//插入頭節點

int inserthead(node** pnode, elemtype ele)

//插入尾節點

int insertlast(node** pnode, elemtype ele)

phead->next = pinsert;

*pnode = ptmp;

printf("向表尾插入元素:%d\n",ele);

return 1;

}//在指定位置插入元素

int insertmid(node** pnode, int pos, elemtype ele)

if (pos < 1)

while (phead != null)

phead = phead->next;

} if (i < pos)

nhead = phead->next;//儲存後乙個節點

pinsert->next = phead->next;

phead->next = pinsert;

printf("插入中間節點\n");

return 1;

}//刪除指定位置元素

int deletemidele(node** pnode, int pos)

while (phead != null)

phead = phead->next;

} de = phead->next;

phead->next=de->next;

printf("刪除元素成功\n");

return 1;

}//刪除第乙個節點

int delhead(node** pnode)

if (phead->next == null)

phead = phead->next;//設定原先頭節點的下乙個節點為頭節點

*pnode = phead;

printf("刪除頭節點成功\n");

return 1;

}//刪除尾節點

int dellast(node** pnode)

while (phead->next!= null)

printf("刪除尾節點\n");

free(phead);

predel->next = null;

return 1;

}//逆序鍊錶

void reverse(node** pnode)

current = *pnode;//a1

while (current->next!=null)

printf("逆序鍊錶\n");}/*

*判斷鍊錶中是否有環,同時設定兩個指標,每個指標步長不一樣,若有環則一定相遇

*/int hasloop(node* pnode)}}

} printf("hasloop函式執行,不存在環\n");

return 0;

}int hasloop2(node* pnode)

else

}s2 = s2->next;

} s1 = s1->next; }

printf("hasloop2函式執行,不存在環\n");

return 0;

}//一次遍歷查詢倒數第n個元素

int getnodefromback(node* phead, int n, elemtype *e)

if (p->next == null&&i < n - 1)

node* p2 = phead;

while (p != null)

*e = p2->element;

printf("倒數第%d個元素是:%d\n", n, *e);

return 1;

}void main()

經典面試題 尋找單鏈表倒數第n個節點 C C

面試中經常出現的程式設計題之一。最直接的辦法是先遍歷一遍單鏈表,記下鍊錶的節點數,然後再次遍歷,直到到達節點數減去n的節點,返回結果。實際情況中若鍊錶數目很多而n相對不大,這種方法需要大約兩次遍歷。更簡單的實現方法是採用雙指標。乙個指標先從煉表頭開始步進n步,然後另乙個指標從頭開始,兩個指標一同步進...

刪除單鏈表倒數第n個節點

如何刪除單鏈表中的倒數第n個節點?先遍歷一遍單鏈表,計算出單鏈表的長度,然後,從單鏈表頭部刪除指定的節點。description 刪除單鏈表倒數第n個節點,常規解法.param head param n return listnode public static listnode removenth...

尋找單鏈表中倒數第k個結點

題目描述 輸入乙個鍊錶,輸出該鍊錶中倒數第k個結點。為了符合大多數人的習慣,本題從1開始計數,即鍊錶的尾結點是倒數第1個結點。例如乙個鍊錶有6個結點,從頭結點開始它們的值依次是1,2,3,4,5,6.這個鍊錶的倒數第3個結點是值為4的結點。思路分析 為了得到倒數第k個結點,很自然的想法是先走到鍊錶的...