1. 程式人生 > >資料結構—連結串列經典面試題

資料結構—連結串列經典面試題

 連結串列面試題:

  • 從尾到頭列印單鏈表
  • 刪除一個無頭單鏈表的非尾節點(不能遍歷連結串列)
  • 在無頭單鏈表的一個節點前插入一個節點(不能遍歷連結串列)
  • 單鏈表實現約瑟夫環(JosephCircle)
  • 逆置/反轉單鏈表
  • 單鏈表排序(氣泡排序&快速排序)
  • 合併兩個有序連結串列,合併後依然有序
  • 查詢單鏈表的中間節點,要求只能遍歷一次連結串列
  • 查詢單鏈表的倒數第k個節點,要求只能遍歷一次連結串列
  • 刪除連結串列的倒數第K個結點
  • 判斷單鏈表是否帶環?若帶環,求環的長度?求環的入口點?並計算 每個演算法的時間複雜度&空間複雜度。
  • 判斷兩個連結串列是否相交,若相交,求交點。(假設連結串列不帶環)
  • 判斷兩個連結串列是否相交,若相交,求交點。(假設連結串列可能帶環) 【升級版】
  • 複雜連結串列的複製。一個連結串列的每個節點,有一個指向next指標指向 下一個節點,還有一個random指標指向這個連結串列中的一個隨機節點 或者NULL,現在要求實現複製這個連結串列,返回複製後的新連結串列。
  • 求兩個已排序單鏈表中相同的資料。void UnionSet(Node* l1, Node* l2);

從尾到頭列印單鏈表

問題分析:

方法一:利用兩層迴圈完成 ,外迴圈用 end 指標控制邊界,從最後一個節點指向的NULL開始走,每一次迴圈向前走一步;內迴圈完成輸出任務,讓內層迴圈的指標 cur 每次從連結串列的頭指標開始不斷往後走,直到指向 end 指標指向的前一個節點,完成對該節點資料域的列印工作

void SListPrintTailToHead(SListNode* pHead)
{
	assert(pHead);

	SListNode* end = NULL;
	while (end != pHead) {  //控制邊界,每次從後往前走一步
		SListNode* cur = pHead;

		while (cur->_next != end) {  //從頭開始遍歷,讓cur指向給end的前一個節點
			cur = cur->_next;
		}

		printf("%d ", cur->_data);
		end = cur;
	}

	printf("\n");
}

方法二:遞迴列印,實質是從第一個節點開始在棧空間中不斷向下建立函式棧幀,直到為最後一個節點建立完棧幀,然後從下往上不斷銷燬棧幀,這個過程中節點的遍歷其實是從後向前的,所以可以利用遞迴完成逆序列印

void SListPrintTailToHeadR(SListNode* pHead)
{
	if (pHead == NULL)
		return;

	SListPrintTailToHeadR(pHead->_next);
	printf("%d ",pHead->_data);
}

刪除一個無頭單鏈表的非尾節點(不能遍歷連結串列)

問題分析:題目中說的無頭連結串列不是連結串列沒頭的意思,只是命題者沒給你頭指標而已。這個題目中直接刪除 pos 指向的節點是無法實現的,需要做適當處理

void SListDelNonTailNode(SListNode* pos)
{
	assert(pos && pos->_next != NULL);  //pos不應該指向最後一個節點

	SListNode* next = pos->_next;  //pos指向的節點的下一個節點
	
	DataType tmp = pos->_data;  //進行資料交換
	pos->_data = next->_data;
	next->_data = tmp;

	pos->_next = next->_next;  //將pos指向的節點和next指向的節點的下一個節點連線起來

	delete next;
	next = NULL;
}

在無頭單鏈表的一個節點前插入一個節點(不能遍歷連結串列)

問題分析:同樣題目中說的無頭連結串列不是連結串列沒頭的意思,只是命題者沒給你頭指標而已。很明顯在 pos 指向的節點前直接插入是無法實現的,需要做適當處理

void SListInsertFrontNode(SListNode* pos, DataType x)
{
	assert(pos);

	SListNode* newnode = BuySListNode(pos->_data);  //給的資料是pos指標指向節點的

	newnode->_next = pos->_next;  //將新節點連到Pos指向的節點之後
	pos->_next = newnode;

	pos->_data = x;  //將pos指標指向的節點的資料改為新節點的初值
}

單鏈表實現約瑟夫環(JosephCircle)