【面试题】单链表的操作1
2016-01-19 10:47
253 查看
单链表的建立、插入等替他操作见本人博客:
单链表的基本操作 http://10741357.blog.51cto.com/10731357/1736387
【面试题】单链表的操作2 http://10741357.blog.51cto.com/10731357/1736403
介绍了6种有关单链表的面试题,对于以下链表要求的实现,解题的思路很重要。
各函数的实现,代码如下:
单链表的基本操作 http://10741357.blog.51cto.com/10731357/1736387
【面试题】单链表的操作2 http://10741357.blog.51cto.com/10731357/1736403
介绍了6种有关单链表的面试题,对于以下链表要求的实现,解题的思路很重要。
各函数的实现,代码如下:
#include"SListNode.h" void PrintTailToHead(SListNode* pHead)//从尾到头打印单链表 {//递归实现 if (pHead) { PrintTailToHead(pHead->next); printf("%d->", pHead->data); } } void DelNonTailNode(SListNode* pos)//删除一个无头单链表的非尾节点(删除pos节点) {//替换法 //1->2->3->4删除第2个节点时,将第三个节点值赋给第二个1->3->2->4,删除第3个节点 assert(pos); assert(pos->next); SListNode* del = pos->next; SListNode* next = del->next;//pos->next->next pos->data = del->data; pos->next = next; free(del); } void InsertFrontNode(SListNode* pos, DataType x)//在无头单链表的一个非头结点前插入一个节点 {//替换法 //1->2->4->5第三个节点4前插入3,则4、5间插入3(1->2->4->3->5),再互换第三、四个节点值 assert(pos); SListNode* tmp = _BuyNode(pos->data); tmp->next = pos->next; pos->next = tmp;//1->2->4->4->5 tmp->data = x; //SListNode* tmp = _BuyNode(x); //tmp->next = pos->next; //pos->next = tmp; //DataType temp = pos->data; //pos->data = tmp->data; //tmp->data = temp; } SListNode* Rverse(SListNode* pHead)//逆置/反转单链表 {//头插思想,注意反转要检查该单链表是否为空 //1->2->3->4新链表中依次取出1 2 3 4进行头插 if (pHead == NULL) { printf("SListNode is NULL!\n"); return NULL; } SListNode* newHead = NULL; SListNode* cur = pHead; while (cur) { SListNode* tmp = cur; cur = cur->next; tmp->next = newHead; newHead = tmp; } return newHead; } SListNode* FindMidNode(SListNode* pHead)//查找单链表的中间节点,要求只能遍历一次链表 {//利用快慢指针实现,快指针走2步的是慢指针走1步的2倍 SListNode* fast = pHead; SListNode* slow = pHead; while (fast && fast->next) { fast = fast->next->next; //链表总数为偶数时加上if返回较小数,无if时返回较大数 if (fast == NULL) break; slow = slow->next; } //while (fast) //{ // if(fast->next) // fast = fast->next->next; // else break; // slow = slow->next; //} return slow; } SListNode* FindMidNode(SListNode* pHead, DataType k)//查找单链表的倒数第k个节点,要求只能遍历一次链表 {//快慢指针,快指针走k步,慢指针走一步,之后同速度走 SListNode* fast = pHead; SListNode* slow = pHead; while (k-- && fast) fast = fast->next; if (k == -1) { while (fast) { slow = slow->next; fast = fast->next; } } else return NULL; //while (k-- && fast) //{ // fast = fast->next; // if (fast == NULL) // return NULL; //} //while (fast) //{ // slow = slow->next; // fast = fast->next; //} return slow; }各函数测试用例如下:
void Test4() {//【面试题一】从尾到头打印单链表 SListNode *phead = NULL; PushBack_Cpp(phead, 1); PushBack_Cpp(phead, 2); PushBack_Cpp(phead, 3); PushBack_Cpp(phead, 4); PushBack_Cpp(phead, 5); PushBack_Cpp(phead, 6); PrintSList(phead); printf("\n---------------------\n"); PrintTailToHead(phead); printf("NULL"); } void Test5() {//【面试题二】删除一个无头单链表的非尾节点 SListNode *phead = NULL; PushBack_Cpp(phead, 1); PushBack_Cpp(phead, 2); PushBack_Cpp(phead, 3); PushBack_Cpp(phead, 8); PushBack_Cpp(phead, 4); PushBack_Cpp(phead, 5); PrintSList(phead); printf("\n---------------------\n"); DelNonTailNode(Find(phead, 8)); PrintSList(phead); DestoryList(phead); } void Test6() {//【面试题三】在无头单链表的一个非头结点前插入一个节点 SListNode *phead = NULL; PushBack_Cpp(phead, 1); PushBack_Cpp(phead, 2); PushBack_Cpp(phead, 4); PushBack_Cpp(phead, 5); PushBack_Cpp(phead, 6); PrintSList(phead); printf("\n---------------------\n"); InsertFrontNode(Find(phead, 4), 3); PrintSList(phead); DestoryList(phead); } void Test7() {//【面试题四】逆置/反转单链表 SListNode *phead = NULL; PushBack_Cpp(phead, 1); PushBack_Cpp(phead, 2); PushBack_Cpp(phead, 3); PushBack_Cpp(phead, 4); PrintSList(phead); printf("\n---------------------\n"); SListNode *newphead = Rverse(phead); PrintSList(newphead); DestoryList(phead); } void Test8() {//【面试题五】查找单链表的中间节点,要求只能遍历一次链表 SListNode *phead = NULL; PushBack_Cpp(phead, 2); PushBack_Cpp(phead, 3); PushBack_Cpp(phead, 4); PushBack_Cpp(phead, 5); PushBack_Cpp(phead, 6); PushBack_Cpp(phead, 7); PrintSList(phead); printf("\n---------------------\n"); printf("%d\n",FindMidNode(phead)->data); DestoryList(phead); } void Test9() {//【面试题六】查找单链表的倒数第k个节点,要求只能遍历一次链表 SListNode *phead = NULL; PushBack_Cpp(phead, 1); PushBack_Cpp(phead, 2); PushBack_Cpp(phead, 3); PushBack_Cpp(phead, 5); PushBack_Cpp(phead, 6); PushBack_Cpp(phead, 7); PrintSList(phead); printf("\n---------------------\n"); SListNode *pos = FindMidNode(phead, 3); printf("%d\n",pos->data); DestoryList(phead); } int main() { Test4(); printf("\n***********************\n"); Test5(); printf("\n***********************\n"); Test6(); printf("\n***********************\n"); Test7(); printf("\n***********************\n"); Test8(); printf("\n***********************\n"); Test9(); system("pause"); }
相关文章推荐
- 文件遍历排序函数
- Lua 学习笔记之C API 遍历 Table实现代码
- C#遍历文件夹后上传文件夹中所有文件错误案例分析
- C#中遍历Hashtable的4种方法
- C#定义并实现单链表实例解析
- C#数据结构之单链表(LinkList)实例详解
- Erlang中遍历取出某个位置的最大值代码
- C++实现图的邻接矩阵存储和广度、深度优先遍历实例分析
- C++实现图的邻接表存储和广度优先遍历实例分析
- C语言实现单链表逆序与逆序输出实例
- C++非递归队列实现二叉树的广度优先遍历
- php遍历目录方法小结
- 一个目录遍历函数
- php遍历删除整个目录及文件的方法
- PHP遍历文件夹与文件类及处理类用法实例
- PHP遍历XML文档所有节点的方法
- php中使用key,value,current,next和prev函数遍历数组的方法
- C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法
- C#使用foreach遍历哈希表(hashtable)的方法
- php递归遍历多维数组的方法