【C++】链表实现的各种情况(含面试题)
来源:互联网 发布:股票评测软件 编辑:程序博客网 时间:2024/06/05 18:06
1.比较顺序表和链表的优缺点,描述他们分别在什么场景下使用?
答:顺序表在空间上是连续的,并支持随机访问,用下标会很方便。在不增容的情况下,尾插的效率很高,但其他情况就不是很乐观。顺序表的高速缓存的利用率比链表高。而链表的头插以及中间插入的效率要比顺序表的效率要高,链表若需要增容会比顺序表要方便的多。
以下代码下面的题目的通用:
#include<stdio.h>#include<stdlib.h>#include<assert.h>typedef int DataType;typedef struct Node{ DataType data; struct Node* next;}Node;void PushBack(Node** ppHead,DataType x);void PrintList(Node* pHead);void TailToHead(Node* pHead);void NoneHead(Node* pos);void Insert(Node* pos, DataType x);Node* Find(Node* pList, DataType x);Node* Josephus(Node* hus,int k);void Reverse(Node** ppHead);void SortList(Node* pHead);Node* MergeList(Node* list1, Node* list2);Node* FindMid(Node* pHead);Node* FindK_Node(Node* pHead,size_t k);
#include"test.h"//创建节点Node* BuyNode(DataType x){ Node* tmp = (Node*)malloc(sizeof(Node)); if (tmp != NULL) { tmp->data = x; tmp->next = NULL; } return tmp;}Node* Find(Node* pList, DataType x){ assert(pList); while (pList->next != NULL) { if (pList->data == x) { return pList; } pList = pList->next; } return pList;}//打印void PrintList(Node* pList){ assert(pList); Node* Node = pList; while (Node) { printf("%d ", Node->data); Node = Node->next; } printf("\n");}//尾插void PushBack(Node** ppList, DataType x){ if (*ppList == NULL) { *ppList = BuyNode(x); } else { Node* list = *ppList; while (list->next != NULL) { list = list->next; } list->next = BuyNode(x); }}
//main函数#define _CRT_SECURE_NO_WARNINGS 1#include"List.h"int main(){ test1(); test2(); test3(); test4(); test5(); test6(); test7(); test8(); test9(); system("pause"); return 0;}
2.从尾到头打印一个单链表
//从尾到头打印一个单链表void PrintTailToHead(Node* List){ if (List == NULL) return; PrintTailToHead(List->next); printf("%d ", List->data);}//测试void test1(){ Node* list = NULL; PushBack(&list, 1); PushBack(&list, 2); PushBack(&list, 3); PushBack(&list, 4); PushBack(&list, 5); PrintList(list); PrintTailToHead(list); printf("\n");}
3.删除一个无头单链表的非尾节点
//删除一个无头单链表的非尾节点void NoneHead(Node* pos){ assert(pos&&pos->next); Node* next; next = pos->next; pos->data = next->data; pos->next = next->next; free(next);}void test2(){ Node* list = NULL; PushBack(&list, 1); PushBack(&list, 2); PushBack(&list, 3); PushBack(&list, 4); PushBack(&list, 5); PrintList(list); Node* pos = list; pos = pos->next; NoneHead(pos); PrintList(list); printf("\n");}
4.在无头单链表的一个节点前插入一个节点
//在无头单链表的一个节点前插入一个节点void Insert(Node* pos,DataType x){ assert(pos); Node* next = pos->next; Node* tmp = BuyNode(pos->data);//新建一个pos位置的节点 pos->data = x;//把要插入的数赋给pos位置的data; pos->next = tmp; tmp->next = next;}void test3(){ Node* list = NULL; PushBack(&list, 1); PushBack(&list, 2); PushBack(&list, 3); PushBack(&list, 4); PushBack(&list, 5); PrintList(list); Node* pos = list; pos = pos->next; Insert(pos,30); PrintList(list); printf("\n");}
5.单链表实现约瑟夫环
//单链表实现约瑟夫环Node* Josephus(Node* hus, int k){ assert(hus); while (hus->next != hus)//当剩下的还有其他时就进去 { int count = k; while (--count) { hus = hus->next;//循环k-1次,直到数到k的那个人出现就停止这时,hus就是要删除的那个。 } Node* next = hus->next;//以下三步分别是将后面的数据,next依次往前挪动 hus->data = next->data; hus->next = next->next; free(next); } return hus;}void test4(){ Node* tail; Node* list = NULL; PushBack(&list, 1); PushBack(&list, 2); PushBack(&list, 3); PushBack(&list, 4); PushBack(&list, 5); PrintList(list); tail = Find(list, 5); tail->next = list; printf("留下的是:%d\n", Josephus(list, 3)->data); printf("\n");}
6.逆置/翻转单链表
void Reverse(Node** ppHead){ Node* n0, *n1, *n2; if (*ppHead == NULL) { return; } n0 = NULL; n1 = *ppHead; n2 = n1->next; while (n1 != NULL) { n1->next = n0;//逆置 //后移 n0 = n1; n1 = n2; if (n2) n2 = n2->next; } *ppHead = n0;//把n0置为头}void test5(){ Node* list = NULL; PushBack(&list, 1); PushBack(&list, 2); PushBack(&list, 3); PushBack(&list, 4); PushBack(&list, 5); PrintList(list); Reverse(&list); PrintList(list); printf("\n");}
7.单链表排序
//单链表排序void SortList(Node* pHead){ Node* tail=NULL; if (pHead == NULL || pHead->next == NULL) { return; } Node* cur = pHead, *next = cur->next; while (next != NULL) { //若前一个数据大于后一个数据则交换两个数据 if (cur->data > next->data) { DataType tmp = cur->data; cur->data = next->data; next->data = tmp; } cur = cur->next;//当前的指针指向下一个 next = next->next;//下一个指针指向下下一个 } tail= cur;//当没有两个可以比较的数据时,将最后一个数据直接赋上}void test6(){ Node* list = NULL; PushBack(&list, 1); PushBack(&list, 2); PushBack(&list, 8); PushBack(&list, 3); PushBack(&list, 4); PrintList(list); SortList(list); PrintList(list);}
8.合并两个有序链表,合并后依然有序
//合并两个有序的链表,合并后依然有序Node* MergeList(Node* list1, Node* list2){ Node* list = NULL; if (list1 == NULL) { return list2; } if (list2==NULL) return list1; if (list1->data > list2->data) { list = list2; list2 = list2->next; } else { list = list1; list1 = list->next; } Node* 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;}void test7(){ Node* list1 =NULL; Node* list2=NULL; PushBack(&list1, 1); PushBack(&list1, 3); PushBack(&list1, 5); PushBack(&list1, 7); PushBack(&list1, 9); PrintList(list1); PushBack(&list2, 0); PushBack(&list2, 2); PushBack(&list2, 4); PushBack(&list2, 6); PushBack(&list2, 8); PrintList(list2); Node* list=MergeList(list1, list2); PrintList(list);}
9.查找一个单链表的中间节点,要求只遍历一次链表
//查找单链表的中间节点,要求只遍历链表一遍//定义快慢指针,快指针每次走两步,慢指针每次走一步Node* FindMid(Node* pHead){ Node* slow = pHead, *fast = pHead; while (fast&&fast->next) { slow = slow->next; fast = fast->next->next; } return slow;}void test8(){ Node* list = NULL; PushBack(&list, 1); PushBack(&list, 3); PushBack(&list, 5); PushBack(&list, 7); PushBack(&list, 9); PrintList(list); printf("中间节点为:%d \n",FindMid(list)->data);}
10.查找单链表的倒数第k个节点,要求只能遍历一遍链表
//查找单链表的倒数第k个节点,要求只能遍历一遍链表Node* FindK_Node(Node* pHead,size_t k){ Node* slow = pHead, *fast = pHead; while (--k) { if (fast == NULL) return NULL; fast = fast->next; } while (fast->next) { slow = slow->next; fast = fast->next; } return slow;}void test9(){ Node* list = NULL; PushBack(&list, 1); PushBack(&list, 3); PushBack(&list, 5); PushBack(&list, 7); PushBack(&list, 9); PrintList(list); printf("中间节点为:%d \n", FindK_Node(list,2)->data);}
阅读全文
0 0
- 【C++】链表实现的各种情况(含面试题)
- c面试题总结(含答案)
- [各种面试题] 堆的实现
- [C/C++]各种面试题
- [C/C++]各种面试题
- [C/C++]各种面试题
- [各种面试题] 复制带随机节点的链表
- (C语言)关于位段空间的使用情况的经典面试题解析
- Spring,hibernate,struts的面试笔试题(含答案)
- hibernate,struts,Spring的面试笔试题(含答案)
- hibernate,struts,Spring的面试笔试题(含答案)
- hibernate,struts,Spring的面试笔试题(含答案)
- hibernate,struts,Spring的面试笔试题(含答案)
- hibernate,struts,Spring的面试笔试题(含答案)
- Spring,hibernate,struts的面试笔试题(含答案)
- Spring,hibernate,struts的面试笔试题(含答案)
- 微软的数据结构算法面试题(含答案)
- Spring,hibernate,struts的面试笔试题(含答案)
- hdu 6178 Monkeys (dfs+FastIO)
- 购物车(cookie和session各自的优缺点)
- 图文演示怎么将cad转换成pdf格式文件的技巧分享
- 异常记录
- JavaJDBC学习-DAO
- 【C++】链表实现的各种情况(含面试题)
- NYG的动态数点
- Take it easy II
- Lua —— 面向对象
- SPI总线 通俗易懂讲解
- Android屏幕分辨率和运行系统兼容性问题-总结
- Java调用MATLAB常见问题总结
- PollToRefresh
- 转自AndyJee