<剑指offer>之链表题目
2012-09-13 11:04
218 查看
【引言】
这几天在看<剑指offer>写的很好,跟July的各有千秋,更加注重归纳总结,笔试面试临时抱佛脚,决定要啃下这其中的46道题目。OK,把每道题目自己实现,相同的归成一类。这次把所有的与list相关的题目列出来。【题目5】从尾到头打印list
//思路:从尾到头打印list的话,考虑用stack先把各节点保存起来,遍历完以后再将stack弹出打印即可#include <stack> void print_list_reverse(list_node* head) { stack<char> m_list; if (head == NULL) return; list_node* node = head->m_pNext; while(node != NULL) { m_list.push(node->m_data); node = node->m_pNext; } while(!m_list.empty()) { cout<<m_list.top()<<" "; m_list.pop(); } }//思路:用递归模拟stack,每次遍历list当前节点的时候,递归调用下一个节点,直到list结尾
void print_list_reverse_res(list_node* head) { if (head == NULL) return; list_node* node = head; if (node->m_pNext != NULL) { node = node->m_pNext; print_list_reverse_res(node); cout<<node->m_data<<" "; } }
【题目13】在O(1)时间内删除链表节点
//void delete_node_O1(list_node* head, list_node* pto_delete)函数形式;可以看出,已经给出了要删除node的指针,我们可以很方便地找到要删除node的下一个node//将下一个node的信息复制到当前node,再将下一个node删除,这正好相当于将当前node删除!时间复杂度是O(1),需要注意的是假设当前node是最后一个的话
//node->next为空,上面的思路就不行了,我们还是需要找到尾节点的上一个节点!如果所有链表只有一个节点,那么我们将head置空即可。so,代码如下:
void delete_node_O1(list_node* head, list_node* pto_delete) { if (pto_delete == NULL || head == NULL) return; list_node* nextNode; if (pto_delete->m_pNext != NULL) { nextNode = pto_delete->m_pNext; pto_delete->m_data = nextNode->m_data; pto_delete->m_pNext = nextNode->m_pNext; delete nextNode; nextNode = NULL; } else if (pto_delete == head) { delete pto_delete; pto_delete = NULL; head = NULL; } else //list尾,没办法,要将前一个节点的m_pNext置为NULL只能遍历一次 { list_node* node = head; while(node->m_pNext != pto_delete) node = node->m_pNext; nextNode = node->m_pNext; node->m_pNext = NULL; delete nextNode; nextNode = NULL; } }
【题目15】寻找list中倒数第k个节点
//题目给出一个list,输出该链表中倒数第k个节点。//为符合习惯本题目,从1开始计数,即list的最后一个节点是倒数第一个
//思路:使用两个指针,刚开始同时指向list头,然后第二个指针p2前进k-1步,然后第一个指针p1和p2
//同时前进,知道p2到达list尾,这时p1指向倒数第k个节点
list_node* find_k_reverse(list_node* head, int k) { if (head == NULL || k < 1) return NULL; list_node *p1, *p2; p1 = p2 = head; int i = 0; while(p2->m_pNext != NULL && (++i != k)) p2 = p2->m_pNext; if (p2->m_pNext == NULL)//list长度小于k-1 return NULL; while(p2->m_pNext != NULL) { p1 = p1->m_pNext; p2 = p2->m_pNext; } return p1; }
【题目16】反转list
//给定一个list,输入参数是头结点,要求反转list,输出翻转后list的头结点//这类问题,都不难,最好画画图啥的,需要注意的中间需要一些节点保存指针,要不会造成list的断裂,需要三个指针,当前指针,当前指针前一个指针,当前指针后一个指针
list_node* reverse_list(list_node* head) { if (head == NULL) return NULL; //一共需要三个指针,当前节点之前,当前节点,当前节点之后的节点,这样才不会造成 //调整过程中的list的断裂 list_node* p_node = head; list_node* p_pre = NULL; list_node* p_next = p_node->m_pNext; while (p_next != NULL) { p_node->m_pNext = p_pre; p_pre = p_node; p_node = p_next; p_next = p_next->m_pNext; } if (p_next == NULL)//这个时候p_node就是原来的尾节点 { p_node->m_pNext = p_pre; } return p_node; }
【题目17】合并两个有序list
list_node* merge_order_list(list_node* first, list_node* second) { //有链表为空的情况 if(first == NULL) return second; if(second == NULL) return first; list_node* p_result = NULL; if (first->m_data < second->m_data) { p_result = first; p_result->m_pNext = merge_order_list(first->m_pNext, second); } else { p_result = second; p_result->m_pNext = merge_order_list(first, second->m_pNext); } return p_result; }
相关文章推荐
- <剑指offer>之链表题目
- <剑指offer>之栈和队列所有题目
- <剑指offer>之栈和队列所有题目
- <剑指Offer>--链表从尾到头输出
- <九度 OJ>题目1012:畅通project
- <九度 OJ>题目1028:继续畅通工程
- <九度 OJ>题目1545:奇怪的连通图
- 【2015/11/15】 数据结构学习日志_Day16 链表 我的<LinkList.c>
- <数据结构> 第二章 线性表之循环链表的代码粗实现
- <九度 OJ>题目1061:成绩排序
- <九度 OJ>题目1545:奇怪的连通图
- <九度 OJ>题目1112:拦截导弹
- <数据结构>单链表元素按插入方法排序实现
- <剑指offer>二叉树专题
- <数据结构学习与实验指导>2-4递增链表的插入
- <剑指offer>二叉树专题
- <模板>米勒拉宾素数判定 题目是hdu4910
- <笔试><面试>C/C++单链表相关(4)判断两链表是否相交,求交点(链表不带环/可能带环)
- <有道笔试题>链表加法的递归实现
- <剑指offer>_有趣的数组