日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

常见单链表面试题

發布時間:2025/3/16 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 常见单链表面试题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

面試中經常被問到有關鏈表的問題,現總結如下:(此處的鏈表結構為不帶頭結點的單鏈表)

單鏈表結構

struct ListNode {int val;ListNode *next;ListNode(int val = 0) : val(val), next(NULL) { } };

1、尾插法建立單鏈表

ListNode* BuildListTail(int n) {int val;ListNode *head = NULL;ListNode *p = head;for(int i = 0; i < n; ++i) {cin >> val;ListNode *node = new ListNode(val);if(head == NULL) {head = node;p = head;}else {p->next = node;p = p->next;}}return head; }// 輸入1 2 3 4,輸出1 2 3 4

2、頭插法建立單鏈表

ListNode *BuildListHead(int n) {int val;ListNode *head = NULL;for(int i = 0; i < n; ++i) {cin >> val;ListNode *node = new ListNode(val);node->next = head;head = node;}return head; }//輸入1 2 3 4,輸出4 3 2 1

3、打印鏈表內容

void PrintList(ListNode *head) {if(head == NULL) {cout << "NULL" << endl;return ;}ListNode *p = head;while(p != NULL) {cout << p->val << " ";p = p->next;}cout << endl; }

4、反轉單鏈表

ListNode *ReverseList(ListNode *head) {ListNode *reversedHead = NULL;ListNode *cur = head;ListNode *pre = NULL;while(cur != NULL) {ListNode *next = cur->next;if(next == NULL)reversedHead = cur;cur->next = pre;pre = cur;cur = next;}return reversedHead; }

5、求單鏈表的長度

int GetListLength(ListNode *head) {int length = 0;ListNode *p = head;while(p != NULL) {length++;p = p->next;}return length; }

6、合并兩個有序鏈表

//遞歸式合并 ListNode *Merge(ListNode *head1, ListNode *head2) {if(head1 == NULL)return head2;if(head2 == NULL)return head1;ListNode *mergeHead = NULL;if(head1->val < head2->val) {mergeHead = head1;mergeHead->next = Merge(head1->next, head2);}else {mergeHead = head2;mergeHead->next = Merge(head1, head2->next);}return mergeHead; }// 非遞歸式合并 ListNode* Merge(ListNode *head1, ListNode *head2) {if(head1 == NULL)return head2;if(head2 == NULL)return head1;ListNode *head = NULL;if(head1->val <= head2->val) {head = head1;head1 = head1->next;}else {head = head2;head2 = head2->next;}ListNode *p = head;while(head1 != NULL && head2 != NULL) {if(head1->val <= head2->val) {p->next = head1;head1 = head1->next;}else {p->next = head2;head2 = head2->next;}p = p->next;}if(head1 != NULL)p->next = head1;if(head2 != NULL)p->next = head2;return head; }

7、求鏈表的中間節點,若長度為偶數,則返回前面的節點

ListNode* GetMidNode(ListNode *head) {if(head == NULL || head->next == NULL) // 0個或1個節點,直接返回return head;ListNode *fast = head->next;ListNode *slow = head; // fast走2步,slow走1步while(fast != NULL) {if(fast->next != NULL)fast = fast->next->next;else break;slow = slow->next;}return slow; }

8、求鏈表的倒數第k個節點

ListNode *FindKthToTail(ListNode *head, int k) {if(head == NULL || k <= 0)return NULL;ListNode *ahead = head;ListNode *behind = NULL;for(int i = 0; i < k - 1; ++i) { //先向前走 k-1 步,兩個指針的距離保持在k-1if(ahead->next != NULL)ahead = ahead->next;elsereturn NULL;}behind = head;while(ahead->next != NULL) {ahead = ahead->next;behind = behind->next;}return behind; }

9、判斷鏈表中是否存在環

// 若返回節點不是NULL則存在環 // 一快一慢兩個指針,快的一次走2步,慢的一次走一步,若存在環,快的肯定能追上慢的 ListNode *MeetingNode(ListNode *head) {if(head == NULL || head->next == NULL)return NULL; // 鏈表為空或者只有1個節點,則不存在環ListNode *slow = head;ListNode *fast = slow->next;while(fast != NULL && slow != NULL) {if(fast == slow)return fast;slow = slow->next;fast = fast->next;if(fast->next != NULL)fast = fast->next;}return NULL; }

10、求鏈表中環的入口節點

// 判斷出有環后,求出環中的節點數目,最后求入口節點 ListNode *EntryNodeOfLoop(ListNode *head) {ListNode *meetingNode = MeetingNode(head);if(meetingNode == NULL)return NULL;// 得到環中的節點數目int nodesInLoop = 1;ListNode *node1 = meetingNode;while(node1->next != meetingNode) {++nodesInLoop;node1 = node1->next;}// 先移動node1,次數為環中的節點數目node1 = head;for(int i = 0; i < nodesInLoop; ++i)node1 = node1->next;// 再同時移動node1和node2ListNode *node2 = head;while(node1 != node2) {node1 = node1->next;node2 = node2->next;}return node1; }

11、判斷兩個鏈表是否相交(是否是Y字型)

// 判斷兩個鏈表的最后一個節點是否相等 ListNode *InterSect(ListNode *head1, ListNode *head2) {if(head1 == NULL || head2 == NULL)return NULL;ListNode *p = head1;while(p->next != NULL) {p = p->next;}ListNode *q = head2;while(q->next != NULL) {q = q->next;}if(p->val == q->val) return p;return NULL; }

?

12、兩個鏈表的第一個公共節點

ListNode *FindFirstCommonNode(ListNode *head1, ListNode *head2) {int length1 = GetListLength(head1);int length2 = GetListLength(head2);int lengthDiff = length1 - length2;ListNode *longList = head1;ListNode *shortList = head2;if(length2 > length1) {longList = head2;shortList = head1;lengthDiff = length2 - length1;}ListNode *FirstCommonNode = NULL;// 先在長鏈表上走幾步,再同時在兩個鏈表上遍歷for(int i = 0; i < lengthDiff; ++i)longList = longList->next;while((longList != NULL) && (shortList != NULL)) {if(longList->val == shortList->val) {FirstCommonNode = longList;break;}longList = longList->next;shortList = shortList->next;}return FirstCommonNode; }

13、單鏈表快速排序(交換節點時只需交換節點的值即可)

// 求單鏈表的劃分位置,該位置將鏈表劃分為左右兩個子鏈表 ListNode *Partition(ListNode *head, ListNode *tail) {if(head == tail || head == NULL || head->next == NULL)return head;int key = head->val;ListNode *p = head;ListNode *q = head->next;while(q != tail) {if(q->val < key) {p = p->next;swap(p->val, q->val);}q = q->next;}swap(p->val, head->val);return p; }void QuickSort(ListNode *head, ListNode *tail) {if(head == NULL || head == tail || head->next == NULL)return ;ListNode *partitionPos = Partition(head, tail);QuickSort(head, partitionPos);QuickSort(partitionPos->next, tail); }調用形式為QuickSort(head, NULL)

14、單鏈表歸并排序

// 合并兩個有序鏈表 ListNode* Merge(ListNode *head1, ListNode *head2) {if(head1 == NULL)return head2;if(head2 == NULL)return head1;ListNode *head = NULL;if(head1->val <= head2->val) {head = head1;head1 = head1->next;}else {head = head2;head2 = head2->next;}ListNode *p = head;while(head1 != NULL && head2 != NULL) {if(head1->val <= head2->val) {p->next = head1;head1 = head1->next;}else {p->next = head2;head2 = head2->next;}p = p->next;}if(head1 != NULL)p->next = head1;if(head2 != NULL)p->next = head2;return head; }//求單鏈表的中間節點 ListNode* GetMidNode(ListNode *head) {if(head == NULL || head->next == NULL) // 0個或1個節點,直接返回return head;ListNode *fast = head->next;ListNode *slow = head; // fast走2步,slow走1步while(fast != NULL) {if(fast->next != NULL)fast = fast->next->next;else break;slow = slow->next;}return slow; }// 單鏈表歸并排序 ListNode *MergeSort(ListNode *head) {if(head == NULL || head->next == NULL)return head; // 0個或1個節點,直接返回ListNode *head1 = head;ListNode *midNode = GetMidNode(head);ListNode *head2 = midNode->next;midNode->next = NULL;head1 = MergeSort(head1);head2 = MergeSort(head2);// 各自排序后再歸并返回return Merge(head1, head2); }// 調用形式為MergeSort(head)

?

總結

以上是生活随笔為你收集整理的常见单链表面试题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。