每日微软面试题——day 5
2011-08-11 03:48
666 查看
<以下微软面试题全来自网络>
<以下答案与分析纯属个人观点,不足之处,还望不吝指出^_^>
<版权所有,转载不忘注明出处:http://blog.csdn.net/zhanxinhang>
题:两个链表,一升一降。合并为一个升序链表。
分析:(假设升序的链表为链表1,降序的链表为链表2,p1,p2分别作为它们的迭代器,还有一个合并链表用于存放合并后的数据)
法一、最容易想到的且容易实现的就是使两个表都变成升序,然后就是经典的合并排序算法的步骤了,步骤是构建p1,p2两个迭代器,分别用于迭代两个链表,每次遍历,若p1所指的节点数据大于p2所指的节点数据则将p1所指的节点数据插入到要合并链表中去且使p1指向下一个节点,否则将p2将所指的节点数据插入到合并链表中去且使p2指向下一个节点,直到p1和p2任意一个指向了NULL为止。最后可能两个链表中尚有剩余的节点,将其逐个插入到合并链表中去即可。
法二、使用递归方法后序遍历降序链表2,遍历顺序就相当于升序的顺序了。在递归遍历链表2的过程中,需要处理有以下三件事:(注意顺序)
(3) 如果p1为空,就直接将p2插入到合并链表中
(这个方法你想到了没!)
完整实现代码:
题:如何删除链表的倒数第m的元素?
分析:构建p0,p1两个迭代器,初始使p0和p1指向头结点,接着使p1移动到第m+1项,然后指向头得p0与p1同时前进,当p1指向空节点的时候结束,这时p0所指的位置就是倒数第m个,时间复杂度为O(n)
实现代码:(为了学习的需要,现在C++朋友采用c++实现,不能满足c朋友要采用c实现的愿望,此实为c++朋友的遗憾,不过一切重在思想。^_^)
上一篇:每日微软面试题——day
4 (最长等差数列)
=======
welcome to my HomePage(http://blog.csdn.net/zhanxinhang)
to have a communication =======
<以下答案与分析纯属个人观点,不足之处,还望不吝指出^_^>
<版权所有,转载不忘注明出处:http://blog.csdn.net/zhanxinhang>
题:两个链表,一升一降。合并为一个升序链表。
分析:(假设升序的链表为链表1,降序的链表为链表2,p1,p2分别作为它们的迭代器,还有一个合并链表用于存放合并后的数据)
法一、最容易想到的且容易实现的就是使两个表都变成升序,然后就是经典的合并排序算法的步骤了,步骤是构建p1,p2两个迭代器,分别用于迭代两个链表,每次遍历,若p1所指的节点数据大于p2所指的节点数据则将p1所指的节点数据插入到要合并链表中去且使p1指向下一个节点,否则将p2将所指的节点数据插入到合并链表中去且使p2指向下一个节点,直到p1和p2任意一个指向了NULL为止。最后可能两个链表中尚有剩余的节点,将其逐个插入到合并链表中去即可。
法二、使用递归方法后序遍历降序链表2,遍历顺序就相当于升序的顺序了。在递归遍历链表2的过程中,需要处理有以下三件事:(注意顺序)
(1) 如果p2的数据小于p1的就插入到合并链表中
(2) 如果p2的数据大于p1,那么就对链表1循环遍历,每次将p1中的数据插到合并链表中,直到p2不大于p1,且p1不为空
(3) 如果p1为空,就直接将p2插入到合并链表中
(这个方法你想到了没!)
完整实现代码:
/** Author:花心龟 Blog:http://blog.csdn.net/zhanxinhang **/ #include <stdio.h> #include <malloc.h> #include <stdlib.h> typedef struct list_node { int data; struct list_node * next; }list_node; list_node *list1=NULL; //链表头结点 list_node *list2=NULL; //链表头结点 void list_print(const list_node *p)//打印该链表函数 { if(p==NULL)return; while(p!=NULL) { printf("%d ",p->data); p=p->next; } printf("\n"); } void list_create(list_node* &head, int data[], int N) { if(data == NULL) return; int i; list_node *p; p = (list_node*)malloc(sizeof(list_node)); p->data = data[0]; p->next = NULL; head = p; for(i=1;i<N; i++) { p->next = (list_node*)malloc(sizeof(list_node)); p->next->data = data[i]; p->next->next = NULL; p=p->next; } } void list_reverse(list_node* &head) //使链表反序 { if(head == NULL) return ;//如果head1为空,则返回 list_node *p,*q; q=head; p=head->next; while(p!=NULL) { head->next=p->next; //将头指针的next指向p的下一个节点 p->next=q; //将p的next值反指向它的前一个节点q q=p; //q移向p的位置 p=head->next; //p移向它的下一个位置 } head = q; } void list_destroy(list_node *head) //销毁函数 { list_node *pmove=NULL,*pdel=NULL; pmove=head; while(pmove!=head) { pdel=pmove; free(pdel); pmove=pmove->next; } } list_node* merge_two_list() //合并链表1和链表2(法一) { list_reverse(list2); //反转链表使之与链表一样升序排列 list_node *list_merged; //和并后的链表 list_node *p1,*p2,*p0; list_merged = (list_node*)malloc(sizeof(list_node)); list_merged->data = 0; list_merged->next = NULL; p0 = list_merged; p1=list1; p2=list2; while(p1!=NULL && p2!=NULL) { if(p1->data < p2->data) { p0->next=(list_node*)malloc(sizeof(list_node)); p0->next->data=p1->data; p0->next->next=NULL; p0=p0->next; p1=p1->next; } else { p0->next=(list_node*)malloc(sizeof(list_node)); p0->next->data=p2->data; p0->next->next=NULL; p0=p0->next; p2=p2->next; } } while(p1!=NULL) { p0->next=(list_node*)malloc(sizeof(list_node)); p0->next->data=p1->data; p0->next->next=NULL; p0=p0->next; p1=p1->next; } while(p2!=NULL) { p0->next=(list_node*)malloc(sizeof(list_node)); p0->next->data=p2->data; p0->next->next=NULL; p0=p0->next; p2=p2->next; } return list_merged; } list_node* p0=(list_node*)malloc(sizeof(list_node)); list_node* phead=p0; list_node* &p1=list1; //p1与list1绑定 list_node* foreach(list_node* p2) //递归合并(法二) { if(p2==NULL) return phead; foreach(p2->next); if(p1->data > p2->data) { p0->next = (list_node*)malloc(sizeof(list_node)); p0->next->data = p2->data; p0->next->next = NULL; p0=p0->next; return phead; } while(p1!=NULL && p1->data<=p2->data) { p0->next = (list_node*)malloc(sizeof(list_node)); p0->next->data = p1->data; p0->next->next = NULL; p0=p0->next; p1 = p1->next; } if(p1==NULL) { p0->next = (list_node*)malloc(sizeof(list_node)); p0->next->data = p2->data; p0->next->next = NULL; p0=p0->next; } return phead; } //Blog:http://blog.csdn.net/zhanxinhang int main() { int list1_data[] = {1,4,6,8,10}; //链表数据升序 可在这里该数据进行测试 int list2_data[] = {14,9,3,2}; //链表数据降序 list_create(list1,list1_data,5); //构建单链表 list_create(list2,list2_data,4); //构建单链表 list_print(list1); list_print(list2); //list_node *list_merged=merge_two_list(); //合并两个链表 //list_print(list_merged->next); //打印合并后的链表 list_node *list_merged2=foreach(list2); //使用递归合并两个链表 list_print(list_merged2->next); list_destroy(list1); //销毁链表 list_destroy(list2); //销毁链表 // list_destroy(list_merged); //销毁合并后的链表 list_destroy(list_merged2); //销毁合并后的链表 system("pause"); return 0; }
题:如何删除链表的倒数第m的元素?
分析:构建p0,p1两个迭代器,初始使p0和p1指向头结点,接着使p1移动到第m+1项,然后指向头得p0与p1同时前进,当p1指向空节点的时候结束,这时p0所指的位置就是倒数第m个,时间复杂度为O(n)
实现代码:(为了学习的需要,现在C++朋友采用c++实现,不能满足c朋友要采用c实现的愿望,此实为c++朋友的遗憾,不过一切重在思想。^_^)
/** Author:花心龟 Blog:http://blog.csdn.net/zhanxinhang **/ #include <iostream> #include <list> using namespace std; class App { list<int> *plist; void delete_node_at_last(int m) //today`s topic { list<int>::iterator p0, p1; p0=p1=p2=plist->begin(); //使p1移到第m+1项 for(int i=1; i<=m; i++) p1++; //p0和p1同时前进,当p1到达终点时p0所指向的就是倒数第m个节点 while(p1!=plist->end()) p0++,p1++; //删除节点 plist->erase(p0); } void create_list() { int list_data[]={1,2,3,4,5,6,7,8,9}; //链表数据 plist = new list<int>(list_data, list_data+sizeof(list_data)/sizeof(int)); } void print_list() { list<int>::iterator it; for(it=plist->begin(); it!=plist->end(); it++) cout<<*it<<' '; } public: //test in run funtion void run() { create_list(); delete_node_at_last(3); //删除倒数第三个节点 print_list(); } ~App() { delete plist; } }; //Blog:http://blog.csdn.net/zhanxinhang int main() { App myapp; myapp.run(); system("pause"); return 0; }
上一篇:每日微软面试题——day
4 (最长等差数列)
=======
welcome to my HomePage(http://blog.csdn.net/zhanxinhang)
to have a communication =======
相关文章推荐
- 每日微软面试题——day 8(最大的二维子矩阵)
- 每日微软面试题——day 1
- 每日微软面试题——day 1
- 每日微软面试题——day 5
- 每日微软面试题——day 4 (最长等差数列)
- 每日微软面试题——day 4 (最长等差数列)
- 每日微软面试题——day 6(打印所有对称子串)
- 每日微软面试题——day 6(打印所有对称子串)
- 每日微软面试题——day 2
- 每日微软面试题——day 3
- 每日微软面试题——day 1
- 每日微软面试题——day 8(最大的二维子矩阵)
- 每日微软面试题——day 2
- 每日微软面试题——day 3
- 每日微软面试题——day 7(找数组中唯一出现两次的数)
- 每日微软面试题——day 7(找数组中唯一出现两次的数)
- 【算法】每日微软面试题——day 7(找数组中唯一出现两次的数)
- 每日一道算法题:微软面试题:在排序数组中,找出给定数字出现的次数
- 微软面试题day 6(打印所有对称子串)
- 微软面试题day 7(找数组中唯一出现两次的数)