關於單鏈表的基本操作,之前已經總結過了,那些掌握之後算是了解了單鏈表是什麼?不過現在面試的題中,肯定不會只讓你回答單鏈表的基礎操作,總是會改變一些東西,或是擴充套件一下。
下面就是一些關於單鏈表的擴充套件內容:
#include
#include
#include
#pragma
warning (disable:4996)
#define datatype int
typedef struct pnodenode,*pnode;
//建立新的節點
pnode buynode(datatype data);
//初始化單鏈表
void initlist(pnode* phead);
//尾插
void pushlist(pnode* phead, datatype data);
//列印單鏈表
void printlist(pnode phead);
// 從尾到頭列印單鏈表
void printlistfromtail2head(pnode phead);
// 刪除無頭單鏈表的非尾結點
void deletenottailnode(pnode pos);
// 在無頭單鏈表非頭結點前插入置為data的結點
void insertnotheadnode(pnode pos, datatype data);
// 用單鏈表實現約瑟夫環
pnode josephcircle(pnode phead, size_t m);
// 逆置單鏈表--三個指標
pnode reverselist(pnode phead);
// 逆置單鏈表--頭插法
pnode reverselist_p(pnode phead);
// 對單鏈表進行氣泡排序--公升序
void bubblesort(pnode phead);
// 查詢單鏈表的中間結點,要求只能夠遍歷一次鍊錶
pnode findmidnode(pnode phead);
// 查詢單鏈表的倒數第k個結點,只能夠遍歷一次鍊錶
pnode findlastknode(pnode phead, size_t k);
//// 刪除單鏈表的倒數第k個結點
//pnode deletelastknode(pnode phead, size_t k);
////// 合併兩個已序單鏈表,合併之後依然有序
//pnode mergelist(pnode phead1, pnode phead2);
有些內容就不能按照常規的思路來看,我記得第一次上課的時候,老師出了一道智力題,
說是有兩隻分布不均勻的香,但是它們都能燃燒乙個小時,如果我們想要測量一刻鐘的時間,該如何做?
當時很多人都說將香掐成兩段,然而,香並不是均勻的,所以不行。
最後給出了答案:將兩隻香同時點燃,不過,要乙隻點燃一頭,另乙隻點燃兩頭,這樣,等其中乙隻燃燒完了之後,時間剛好過了半個小時,再將另一頭也點上,這樣,剩餘的香就能燃燒一刻鐘的時間了。
同樣的道理,這裡的一些問題也是這樣的想法,比如求中點的問題,只要給出兩個指標,慢的一次走一步,快的一次走兩步,等快的走到最後,那麼慢的剛好走到中間。
下面就是這些函式的實現了:
#include
"linklist.h"
//建立新的節點
pnode buynode(datatype data)
return node;
}//初始化單鏈表
void initlist(pnode * phead)
//尾插
void pushlist(pnode* phead, datatype data)
else
pcur->next = newnode; }}
void printlist(pnode phead)
printf("\n");
}// 從尾到頭列印單鏈表
void printlistfromtail2head(pnode phead)
printf("\n");
}// 刪除無頭單鏈表的非尾結點,不能遍歷單鏈表
void deletenottailnode(pnode pos)
pnode pdel = pos->next;//將pos後面的節點儲存
pos->
data
= pdel->
data;//將pos後面的值,賦給pos中的data
pos->next = pdel->next;//將pos的下乙個位置指向待刪除的下乙個位置
free(pdel);//釋放空間
}// 在無頭單鏈表非頭結點前插入置為data的結點
void insertnotheadnode(pnode pos, datatype data)
pnode newnode = buynode(pos->
data);
if (newnode) }
// 用單鏈表實現約瑟夫環
pnode josephcircle(pnode phead, size_t m)
pnode pcur = phead;
while (pcur != pcur->next)
pnode pdel = pcur->next;
pcur->
data
= pdel->
data;
pcur->next = pdel->next;
free(pdel);
} return pcur;
}// 逆置單鏈表--三個指標
pnode reverselist(pnode phead)//不太理解
pnode prev = phead;
pnode pcur = prev->next;
pnode pnext = pcur->next;
while (pnext)
pcur->next = prev;
phead->next =
null;
return pcur;
}// 逆置單鏈表--頭插法
pnode reverselist_p(pnode phead)
pnode pcur = phead->next;
pnode newnode =
null;
while (pcur)
phead->next = newnode;
newnode = phead;
return newnode;
}// 對單鏈表進行氣泡排序--公升序
void bubblesort(pnode phead)
pnode pcur = phead;
pnode ptail =
null;
datatype flag =
0; while (ptail != phead)
pcur = pcur->next;
} if (!flag)
ptail = pcur; }}
// 查詢單鏈表的中間結點,要求只能夠遍歷一次鍊錶
pnode findmidnode(pnode phead)
//使用一快一慢兩個指標,快的是慢的的二倍
pnode pslow = phead;
pnode pfast = phead;
while (pfast&&pfast->next)//分兩種情況考慮
return pslow;//快的指標到尾部,慢的指標就在中間,所以返回慢的指標即可
}// 查詢單鏈表的倒數第k個結點,只能夠遍歷一次鍊錶
pnode findlastknode(pnode phead, size_t k)
pnode pslow = phead;
pnode pfast = phead;
while (--k)//先讓快的指標走k步
pfast = pfast->next;
} while (pfast->next)//再一起走,等到快的走到尾部,慢的剛好到倒數第k個節點
return pslow;//返回慢的指標即可
} //刪除單鏈表的倒數第k個結點
pnode deletelastknode(pnode phead, size_t k)
pnode pos = findlastknode(phead, k);
earse(phead, pos);
} //合併兩個已序單鏈表,合併之後依然有序
pnode mergelist(pnode phead1, pnode phead2)
if (null
== phead2)
pnode ptail=
null;
pnode newnode =
null;
if (phead1->
data
< phead2->
data)
else
newnode = ptail;
while (phead1&&phead2)
else
}if (phead1)
else
return newnode;
}
#include
"linklist.h"
void funtest()
int main()
單鏈表面試題
1.倒序列印鍊錶 void reverseprint slistnode pfirst 有兩種方法 1.遞迴操作 2.非遞迴操作 2 非遞迴 slistnode pend slistnode pcur pend null while pfirst pend pend pcur printf d pe...
單鏈表(面試題)
鍊錶反轉思路 1.單鏈表中有效節點的個數 2.查詢單鏈表中弟第k個節點 3.單鏈表的反轉 實現 如下 public class testlink 1單鏈表中有效節點的個數 遍歷得出個數 public static intcount heronode head int count 0 while tr...
鏈表面試題 反轉單鏈表
反轉乙個單鏈表。示例 輸入 1 2 3 4 5 null 輸出 5 4 3 2 1 null解決方案 頭插法開闢新鍊錶並逐個讀取舊鍊錶,頭插進新鍊錶,這樣新的鍊錶與原鍊錶的結構就是反的,需要借助輔助空間 definition for singly linked list.struct listnod...