基于单链表的面试题-基础篇

来源:互联网 发布:淘宝海外直购 编辑:程序博客网 时间:2024/06/18 12:40
1.比较顺序表和链表的优缺点,说说它们分别在什么场景下使用? 

 顺序表:内存中地址连续,长度不可变更,支持随机查找 可以在O(1)内查找元素
适用于需要大量访问元素的 而少量增添/删除元素的程序

链表:内存中地址非连续,长度可以实时变化,不支持随机查找 查找元素时间复杂度O(n)
适用于需要进行大量增添/删除元素操作 而对访问元素无要求的程序

顺序表的CPU高速缓存效率更高,单链表CPU高速缓存效率低.

程序源代码

2从尾到头打印单链表 (用递归实现)

void PrintfTailtoHead(ListNode* pList)//递归{if (pList == NULL)return;PrintfTailtoHead(pList->next);printf("%d->", pList->data);

}

3.删除一个无头单链表的非尾节点

void EraseNonTail(ListNode* pos)//删除pos后面的结点{assert(pos);assert(pos->next);ListNode* next = pos->next;pos->next = next->next;free(next);}

4.在无头单链表的一个节点前插入一个节点 

void InsertNonHead(ListNode* pos,DataType x)//在pos前插入一个结点tmp{ListNode* tmp = BuyNode(x);ListNode* next = pos->next;pos->next = tmp;tmp->next = next;DataType tmpdata = pos->data;pos->data = tmp->data;tmp->data = tmpdata;}

5.单链表实现约瑟夫环

ListNode* JosePhRing(ListNode* list, int k){if (list == NULL)return NULL;ListNode* cur = list;while (cur != cur->next){int count = k;while (--count){cur = cur->next;}ListNode* next = cur->next;cur->data = next->data;cur->next = next->next;free(next);}return cur;}

6.逆置/反转单链表 

ListNode* Reverse(ListNode* list){ListNode* newlist = NULL;ListNode* cur = list;while (cur)//头插法{ListNode* tmp = cur;cur = cur->next;tmp->next = newlist;newlist = tmp;}return newlist;}

7.单链表排序(冒泡排序&快速排序)

void BubbleSort(ListNode* list){if (list == NULL || list->next == NULL){return;}ListNode* tail = NULL;while (tail != list->next){ListNode* cur = list;ListNode* next = cur->next;while (next != tail){if (cur->data > next->data){DataType data = cur->data;cur->data = next->data;next->data = data;}cur = cur->next;next = next->next;}tail = cur;}}
8.合并两个有序链表,合并后依然有序 

ListNode* Merge(ListNode* list1, ListNode* list2){ListNode* list = NULL;//取两个链表中最小的数做头结点if (list1->data < list2->data){list = list1;list1 = list1->next;}else{list = list2;list2 = list2->next;}ListNode* tail = list;while (list1&&list2){if (list1->data < list2->data){tail->next = list1;list1 = list1->next;}else{tail->next = list2;list2 = list2->next;}tail = tail->next;}if (list1)tail->next = list1;if (list2)tail->next = list2;return list;}
9.查找单链表的中间节点,要求只能遍历一次链表 

ListNode* FindMidNode(ListNode* list){ListNode* slow = list,*fast = list;while (fast&&fast->next){slow = slow->next;fast = fast->next->next;}return slow;}

10.查找单链表的倒数第k个节点,要求只能遍历一次链表

ListNode* FindTailkNode(ListNode* list, int k){ListNode *slow = list,*fast = list;while (k--){if (fast == NULL)return NULL;fast = fast->next;}while (fast){slow = slow->next;fast = fast->next;}return slow;}

测试2 3 5 6

void Test3(){ListNode* list = NULL;PushBack(&list, 1);PushBack(&list, 2);PushBack(&list, 3);PushBack(&list, 4);PrintList(list);PrintfTailtoHead(list);PushBack(&list, 1);PushBack(&list, 2);PushBack(&list, 3);PushBack(&list, 4);PrintList(list);ListNode* pos = Find(list, 2);EraseNonTail(pos);PushBack(&list, 1);PushBack(&list, 3);PushBack(&list, 4);PrintList(list);pos = Find(list, 3);InsertNonHead(pos, 2);PrintList(list);PushBack(&list, 1);PushBack(&list, 2);PushBack(&list, 3);PushBack(&list, 4);ListNode* newlist=Reverse(list);PrintList(newlist);}int main(){Test3();system("pause");return 0;}
测试4
void test4(){ListNode* list = NULL;PushBack(&list, 1);PushBack(&list, 2);PushBack(&list, 3);PushBack(&list, 4);PushBack(&list, 5);ListNode* pos = Find(list, 5);pos->next = list;ListNode* last = JosephRing(list, 3);printf("幸存者:%d\n", last->data);}int main(){//test7();//test6();     test4();//test8();system("pause");return 0;}
测试7
void test5(){ListNode* list = NULL;PushBack(&list, 2);PushBack(&list, 3);PushBack(&list, 1);PushBack(&list, 4);PushBack(&list, 6);PushBack(&list, 5);PrintList(list);BubbleSort(list);PrintList(list);}int main(){test5();system("pause");return 0;}
测试8
void test6(){ListNode* list1 = NULL;PushBack(&list1, 1);PushBack(&list1, 2);PushBack(&list1, 4);PushBack(&list1, 6);PushBack(&list1, 8);PrintList(list1);ListNode* list2 = NULL;PushBack(&list2, 2);PushBack(&list2, 3);PushBack(&list2, 5);PushBack(&list2, 6);PrintList(list2);ListNode* list = Merge(list1, list2);PrintList(list);}int main(){//test7();test6();//test4();system("pause");return 0;}

测试9

void test7(){ListNode* list = NULL;PushBack(&list, 1);PushBack(&list, 3);PushBack(&list, 5);PushBack(&list, 7);PushBack(&list, 9);ListNode* mid= FindMidNode(list);printf("%d\n", mid->data);}int main(){test7();//test6();//test4();system("pause");return 0;}
测试10
void test8(){ListNode* list = NULL;PushBack(&list, 1);PushBack(&list, 2);PushBack(&list, 3);PushBack(&list, 4);PushBack(&list, 5);ListNode* ret = FindTailkNode(list,3);printf("%d\n", ret->data);}int main(){//test7();//test6();//test4();test8();system("pause");return 0;}