链表面试题总结(一)
2016-06-11 12:06
381 查看
基于上一次写的链表,现在,我们来讨论下面这些问题。
1.链表的冒泡排序
2.删除无头非尾节点
3.反转链表
4.在当前节点前插入一个数据x
5.查找链表的中间节点。
6.删除单链表的倒数第K个节点(K>1&&K<总长度)
对于上面这6个问题,我们进行分析与解答。
链表的代码我都已经写过博客:数据结构—单链表的实现
另外,我也在我的github上有链表的代码,github链接
如还有什么问题,可以发邮件到 953659912@qq.com
在这里我们的思路是先有两个指针,一个头指针,一个尾指针,第一次从头进行冒泡到尾,第二次从头冒泡到最后一个节点的前一个节点,就这样一次进行下去,一直到冒泡到第一个节点和第二个节点。
讲到这,我想大家应该明白了怎么实现了吧。
下面附上代码实现过程。
其实思路也挺简单的,就是我们要把删除的节点后的节点的数据放到要删除的节点上,删除了删除的节点后的节点,然后让删除节点指向删除删除的节点后的节点后的节点。
是不是感觉头都大了?
接下来,我用图解为大家分析下。
代码实现如下:
我们可以把插入节点的数据放到新节点上,把新节点的数据放到插入节点的数据上。
这样我们就可以实现在当前节点前插入一个节点了。
给一个快指针,让快指针每次移动两步,给一个慢指针,让慢指针每次移动一步,最后结果就是快指针移动到最后一个节点,慢指针最后移动到了中间的节点上。
当然,在这里面请你考虑一些异常的情况!
1.链表的冒泡排序
2.删除无头非尾节点
3.反转链表
4.在当前节点前插入一个数据x
5.查找链表的中间节点。
6.删除单链表的倒数第K个节点(K>1&&K<总长度)
对于上面这6个问题,我们进行分析与解答。
链表的代码我都已经写过博客:数据结构—单链表的实现
另外,我也在我的github上有链表的代码,github链接
如还有什么问题,可以发邮件到 953659912@qq.com
1.链表的冒泡排序
关于链表的排序问题是我们需要关心的,链表的排序,排序时比较方便的就是交换链表所保存的内容,所以接下来我们来提供一种思路来解决这个问题。在这里我们的思路是先有两个指针,一个头指针,一个尾指针,第一次从头进行冒泡到尾,第二次从头冒泡到最后一个节点的前一个节点,就这样一次进行下去,一直到冒泡到第一个节点和第二个节点。
讲到这,我想大家应该明白了怎么实现了吧。
下面附上代码实现过程。
void BubbleSort(pLinkList pList) { pLinkNode cur = NULL; pLinkNode tail = NULL; assert(pList); cur = pList->pHead; if ((pList->pHead == NULL)||(pList->pHead->next==NULL)) { return; } while (cur != tail) //当尾指针不等于头指针时进行冒泡 { while (cur->next != tail) //控制cur指针最后到的位置是倒数第二个节点 { if (cur->data > cur->next->data) { datatype tmp = cur->data; cur->data = cur->next->data; cur->next->data = tmp; } cur = cur->next; } tail = cur; cur = pList->pHead; } }
2.删除无头非尾节点
删除无头非尾的节点,我想乍一看大家可能会觉得没有什么思路,按照惯性思维,咱们删除一个节点的时候,应该对这个节点的前一个节点记住,然后让前一个系欸但指向删除节点的下一个节点,但是在这里我们说了已经是无头的节点。所以我们需要转换我们的思路,进行一种新的操作。其实思路也挺简单的,就是我们要把删除的节点后的节点的数据放到要删除的节点上,删除了删除的节点后的节点,然后让删除节点指向删除删除的节点后的节点后的节点。
是不是感觉头都大了?
接下来,我用图解为大家分析下。
代码实现如下:
void EraseNotTail(pLinkNode pos) { pLinkNode del = NULL; assert(pos->next != NULL); //断言,排除尾节点的情况 pos->data = pos->next->data; //让当前节点后面节点的数据赋给当前节点。 del = pos->next; //删除记录当前节点后的节点 pos->next = pos->next->next; //当前节点的nex指向删除节点的下一个节点。 free(del); del = NULL; }
3.反转链表
反转链表这个算法的实现也需要有一个清晰的思路,闲话就不多说了,咱们进入正题。对于反转链表,其实就是你把链表重新排下序。void Reverse(pLinkList plist) { pLinkNode tmp = NULL; //记录中间节点 pLinkNode cur = NULL; //记录链表的第一个节点 pLinkNode newnode = NULL; //记录翻转后的第一个节点 assert(plist); cur = plist->pHead; while (cur != NULL) { tmp = cur; // cur = cur->next; tmp->next = newnode; newnode = tmp; } plist->pHead = newnode; }
4.在当前节点前插入一个数据x
在当前节点之前插入一个数据,按照常规思路坑定也是不行的,这时候我们就要像删除无头节点一样有一个思维:我们可以把插入节点的数据放到新节点上,把新节点的数据放到插入节点的数据上。
这样我们就可以实现在当前节点前插入一个节点了。
void InsertFrontNode(pLinkNode pos, datatype x) { pLinkNode newnode = NULL; assert(pos); newnode = (pLinkNode)malloc(sizeof(LinkNode)); if (NULL == newnode) { printf("out of memory"); exit(EXIT_FAILURE); } newnode->data = pos->data; pos->data = x; newnode->next = pos->next; pos->next = newnode; }
5.查找链表的中间节点。
查找链表的中间节点,所采用的思路就是我们平时所说的快慢指针。给一个快指针,让快指针每次移动两步,给一个慢指针,让慢指针每次移动一步,最后结果就是快指针移动到最后一个节点,慢指针最后移动到了中间的节点上。
pLinkNode FindMidNode(pLinkList pList) { pLinkNode fast = NULL; pLinkNode slow = NULL; assert(pList); slow = fast = pList->pHead; while (fast != NULL) { if (fast->next != NULL) { fast = fast->next->next; } else { break;; } slow = slow->next; } return slow; }
6.删除单链表的倒数第K个节点(K>1&&K<总长度)
在这里,对于删除单链表的倒数第K个节点,我们采用的思路是首先给个front指针和back指针,让front指针移动K次,然后让front指针和back指针同时移动,一直到front指针指向为NULL,此时back指针指向的就是倒数第K个节点,然后我们就可以删除back节点,注意,这里所采用的删除的方法要和上面类似,采用交换删除的方式。当然,在这里面请你考虑一些异常的情况!
void DelKNode(pLinkList pList, int k) { pLinkNode front = NULL; pLinkNode back = NULL; pLinkNode del = NULL; assert(pList); if (pList->pHead == NULL) { printf("链表为空!!\n"); return; } if (k == 1) { printf("K应当大于1\n"); return; } front = back = pList->pHead; while (front != NULL) { 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); } }
相关文章推荐
- 空杯心态,一个程序员的自我修炼
- 程序员常用工具
- 面试题:给40亿个不重复的无符号整数,没排过序,给一个无符号整数如何快速判断这个数是否在这40亿个数中
- java 概念面试题
- 让程序员立于不败之地的七种武器
- 《程序员修炼之道--从小工到专家》阅读笔记03
- 面试题22:栈的压入、弹出序列
- 面试题21:包含min函数的栈
- 面试题20:顺时针打印矩阵
- 面试题19:二叉树的镜像
- 面试题18:树的子结构
- 面试题17:合并两个排序的链表
- 面试题16:反转链表
- 面试题15:链表中倒数第K个节点
- 面试题14:调整数组顺序使奇数位于偶数前面
- 面试题13:在O(1)时间 内删除链表节点
- 面试题12:打印1到最大的n位数
- 面试题11:数值的整数次方
- 记录面试需要的一些基本资料1
- 面试总结之查找算法