链表面试题(一)
2016-06-14 13:47
330 查看
在前边的博客中,我已经整理了链表的基本操作,在这篇文章,我来整理关于链表的一部
分面试题:
1.删除无头指针的非尾节点
2.逆序链表
3.在当前节点前插入一个元素(不给出链表的头指针)
4.查找链表的中间节点
5.删除链表的倒数第k个结点
下边我一一给出解释(尽量画图),和对应的代码:
先给出下边代码要用到的结构体的声明:
1.删除无头指针的非尾节点
代码:
测试用例:pos为当前链表的最后一个结点。
pos为当前链表的第一个结点。
2.逆序链表
3.在当前节点前插入一个元素(不给出链表的头指针)
由于这个比较简单,可以类比1,我们无法在pos前边插入元素,但是可以在后边插入,
完了把pos和pos的下一个位置的元素交换就好了~~
测试用例:pos为当前链表的第一个结点、最后一个结点、中间任意结点。三种情况都
应该测到。
4.查找链表的中间节点
代码:
要是以奇数的判定条件还能判定偶数吗???当然是不可以的嘛。为什么我这样说呢!
以为一开始我写的代码,while里边只有一个条件fast->next,这是不对的。并且两个条
件之间逻辑与。(只要有一个条件不满足,循环就结束。)
测试用例:结点总数 为奇数;
结点总数为偶数。
5.删除链表的倒数第k个结点
代码:
测试用例:k = 1时assert不通过,报错。
k = 5(假设链表总共5个结点)会正常删除
k = 3。
这些都要测试到。
注意:不要总是一遇到特殊情况就特殊处理~~不然代码全是特殊处理~
测试函数:
分面试题:
1.删除无头指针的非尾节点
2.逆序链表
3.在当前节点前插入一个元素(不给出链表的头指针)
4.查找链表的中间节点
5.删除链表的倒数第k个结点
下边我一一给出解释(尽量画图),和对应的代码:
先给出下边代码要用到的结构体的声明:
typedef struct LinkNode { DataType data; struct LinkNode *next; }LinkNode,*pLinkNode; typedef struct LinkList { LinkNode *pHead; }LinkList,*pLinkList;
1.删除无头指针的非尾节点
代码:
//删除无头结点的非尾节点 void EarseNotTail(pLinkNode pos) { assert(pos && pos->next); pLinkNode del = pos->next; pos->data = pos->next->data; pos->next = pos->next->next; free(del); }
测试用例:pos为当前链表的最后一个结点。
pos为当前链表的第一个结点。
2.逆序链表
//逆序链表 void Reverselist(pLinkList plist) { assert(plist); pLinkNode cur = plist->pHead; pLinkNode tmp = NULL; pLinkNode newHead = NULL; while (cur) { tmp = cur; cur = cur->next; tmp->next = newHead; newHead = tmp; } plist->pHead = newHead; }
3.在当前节点前插入一个元素(不给出链表的头指针)
由于这个比较简单,可以类比1,我们无法在pos前边插入元素,但是可以在后边插入,
完了把pos和pos的下一个位置的元素交换就好了~~
//在当前节点前插入一个元素(同样不给出链表的头指针) void InsertFrontNode(pLinkNode pos, DataType x) { assert(pos); pLinkNode newNode = CreatNode(x); DataType tmp = 0; newNode->next = pos->next; pos->next = newNode; tmp = pos->data; pos->data = pos->next->data; pos->next->data = tmp; }
测试用例:pos为当前链表的第一个结点、最后一个结点、中间任意结点。三种情况都
应该测到。
4.查找链表的中间节点
代码:
//查找链表的中间节点 pLinkNode FindMidNode(pLinkList plist) { assert(plist); pLinkNode fast = plist->pHead; pLinkNode slow = plist->pHead; while (fast&&fast->next) { fast = fast->next->next; slow = slow->next; } return slow; }
要是以奇数的判定条件还能判定偶数吗???当然是不可以的嘛。为什么我这样说呢!
以为一开始我写的代码,while里边只有一个条件fast->next,这是不对的。并且两个条
件之间逻辑与。(只要有一个条件不满足,循环就结束。)
测试用例:结点总数 为奇数;
结点总数为偶数。
5.删除链表的倒数第k个结点
代码:
//删除链表的倒数第k个结点 void DelKNode(pLinkList plist, DataType k) { assert(plist); assert(k > 1); if (plist->pHead == NULL) { return; } pLinkNode front = plist->pHead; pLinkNode back = plist->pHead; pLinkNode del = plist->pHead; while (front) { k--; if (k < 0) { back = back->next; } front = front->next; } if (k <= 0) { back->data = back->next ->data; del = back->next; back->next = back->next->next; free(del); } }
测试用例:k = 1时assert不通过,报错。
k = 5(假设链表总共5个结点)会正常删除
k = 3。
这些都要测试到。
注意:不要总是一遇到特殊情况就特殊处理~~不然代码全是特殊处理~
测试函数:
void test2() { LinkList list; pLinkNode pos = NULL; //pLinkNode ret = NULL; InitLinkList(&list); PushBackLinkList(&list, 1); PushBackLinkList(&list, 2); PushBackLinkList(&list, 3); PushBackLinkList(&list, 4); PushBackLinkList(&list, 5); PrintLinkList(&list); //测试删除 /*pos = find(&list, 4); EarseNotTail(pos);*/ //测试逆序 //Reverselist(&list); //测试插入函数 /*pos = find(&list,5); InsertFrontNode(pos, 7);*/ pos = FindMidNode(&list); printf("%d",pos->data); //PrintLinkList(&list); DelKNode(&list, 1); PrintLinkList(&list); DestroyLinkList(&list); }
相关文章推荐
- 栈和队列相关面试题(1)
- 面试题9:递归和非递归
- 面试题22 栈的压入、弹出序列
- Java程序员也应该知道的系统知识系列之(网卡,cpu,内存,硬盘,虚拟化)
- 编程之法:面试和算法心得
- 要准备了:JAVA面试题及答案汇总
- 腾讯面试全程
- 面试腾讯全过程
- 程序员,应该掌握的英语词汇
- 面试题21 包含Min函数的栈
- 非技术相关的面试技巧(文章内容来自他人博客)
- 升级您的ERP系统
- 写给嵌入式程序员的循环冗余校验(CRC)算法入门引导
- Android面试题(文章内容来自他人博客)
- 与WWDC大会同步,黑马程序员iOS4.0课程震撼出炉
- Java笔试面试题整理第八波
- 面试题47-2:不使用新的变量,交换两个变量的值
- 面试题47:不用加减乘除做加法
- 程序员面试50题(1)—查找最小的k个元素[算法]
- 运维面试题和答案