单链表相关面试笔试题
来源:互联网 发布:linux c 绝对路径 编辑:程序博客网 时间:2024/06/03 22:40
1.链表节点结构定义
struct node {node * next ;int val ;node(int x):val(x),next(NULL){}};
/** 从数组中构造单项链表**/node * construct_list(int a[] ,int n){ node * head=NULL; node * p=NULL; node * q=NULL; for(int i=0;i<n;++i){ p= new node(a[i]); if(q!=NULL) q->next=p; if(i==0){ head=p; }; q=p; p=p->next; } return head;}/** 顺序输出单链表**/void output(struct node * head){ if(head == NULL){ cout<<"empty list !\n"; return ; } node * p = head; while(p!= NULL){ cout<<p->val<<" "; p=p->next; } cout<<"\n";}
2.链表的逆序输出以及链表的逆序操作
/** 逆序输出单链表,递归**/void reverse_output(struct node * head){ if(head == NULL){ return ; }else { node * p = head; reverse_output(p->next); cout<<p->val<<" "; }}/** 逆转单链表 思路:将node 一个个从链表中卸下来,然后逆序重组**/node * reverse_list(node * head){ if (head ==NULL ||head->next==NULL)return head; node * p=NULL, *q=NULL,*t=NULL; p=head; q=head->next; p->next=NULL; while(q){ t=q; q=q->next; t->next=p; p=t; } return p;}
//感觉这样可以少一个变量,但是不是很容易理解,主要是我们需要改变指针的值void reverse_list1(node * *head){ if (*head ==NULL ||(*head)->next==NULL)return ; node *q=NULL,*t=NULL; q=(*head)->next; (*head)->next=NULL; while(q){ t=q; q=q->next; t->next=(*head); (*head)=t; }}
3.判断链表中是否有环,有的话找出环的入口
/* 判断链表是否有环,如果有的话,找出环的入口 找环的入口2(x+y)=nr +(x+y) --> x=nr-y :其中x为开始到入口的步长,y为入口到首次相遇的步长 r为环的长度*/bool has_cicle(node * head){ bool has_cicle = false; if(head == NULL || head->next == NULL )return has_cicle; node * slow = head ,*fast = head ;//同一个起跑线 while(true){ slow = slow->next; fast = fast->next; if(fast) fast = fast->next; if(slow==NULL||fast==NULL)break; if(slow==fast){ has_cicle=true; break; } } if(has_cicle==true){//找到环的入口 node * start = head ; node * encounter = slow; while(start!=slow){ start=start->next; slow=slow->next; } cout<<"entry point :"<<start->val<<" \n" ; } return has_cicle;}
4.链表中的倒数第K个数
/** 找到单链表中的倒数第K个元素问题,只给出单链表的头指针 也是利用快慢两个指针,first指针首先走k步之后 如果再次之前first已经走完了那么就说明没有找到这样的值 否则,first 和second指针开始一起走,等到first指针走到最后, second 指针恰好走到了倒数第k个元素**/node * find_post_k_element(node * head,int k){ node * first = head ; node * second =NULL; while(first!=NULL&&k>0){ k--; first=first->next; } if(k>0) return NULL; else{ second= head; while (first){//当first在第k+1个元素的时候 second元素在第1个元素,相隔正好是k个元素 first=first->next; second=second->next; } } return second;}
5.求链表中间的元素
/** 找出链表的中间元素 好吧,还是两个指针吧,步长两倍关系即可**/node * find_mid_element(node * head){ if(head==NULL||head->next == NULL){ return head; } node * single = head; node * double_step = head; while(double_step){ double_step=double_step->next; if(double_step) double_step=double_step->next; if(double_step) single=single->next;//注意指针走动的顺序 } return single;}
6.有序链表的合并问题,包括递归和非递归的实现
/** 两个升序链表的合并问题,非递归**/node * merge_lists(node * head1 ,node * head2){ if(head1 == NULL)return head2; if(head2 == NULL)return head1; node * head = NULL; node * temp = NULL; while(true){ while(head1&&head2&&head1->val<=head2->val){//head1 head 2都得判断是否为空 if(temp == NULL){ temp = head1; head = temp; } else{ temp->next = head1; temp = temp->next;//指针要走动的 } head1 = head1->next; } while(head2&&head1&&head2->val<=head1->val){ if(temp == NULL) { temp = head2 ; head= temp; }else{ temp ->next = head2; temp=temp->next; } head2 = head2->next; } if(head1 == NULL){ while(head2){ temp ->next = head2; temp=temp->next; head2 = head2->next; } break; } if(head2 == NULL){ while(head1){ temp ->next = head1; head1 = head2->next; temp=temp->next; } break; } if(head1==NULL&&head2==NULL)break; } return head;}//递归版本node * merge_lists1(node * head1 , node * head2){ node * head = NULL; if(head1 == NULL)return head2; if(head2 == NULL)return head1; if(head1->val<=head2->val){ head = head1; head ->next = merge_lists1(head1->next,head2); }else{ head = head2 ; head ->next = merge_lists1(head1,head2->next); } return head;}
7.删除单链表中的重复数据,链表无序
常见的这个题目分为两个要求,一是在空间复杂度O(1),另一个则是木有限制,一般而言空间有限制的情况下只能通过暴力的遍历解决了,但是如果没什么限制的话使用hash表来帮助操作是比较省时的,时间复杂度为O(n),貌似C++11中才有的hash表可以用,代码如下:/** 未排序的链表中的重复值的删除 1.不限制空间复杂度 2.空间复杂度在O(1)的实现**///复杂度 O(n*n)void remove_duplicate1(node * head){ if(head==NULL||head->next==NULL)return; node * first =head,*second =NULL,* t = NULL; while(first){ second=first->next; t=first; while(second){ if(second->val==first->val){ t->next=second->next; delete second; second=t->next; }else{ t=second; second=second->next; } } first=first->next; }}void remove_duplicate2(node * head){ if(head==NULL||head->next==NULL)return; hash<int>h; h(head->val)=true; node * p = head->next,*q=head; while(p){ if(h(p->val)==true){ q->next=p->next; delete p; p=q->next; }else{ h(p->val)=true; q=p; p=p->next; } }}
0 0
- 单链表相关面试笔试题
- 网络相关面试笔试题
- 业务员面试笔试题
- 富士通 面试笔试题
- 面试笔试题网址
- java面试笔试题
- C++面试笔试题
- c#面试笔试题
- java面试笔试题
- 面试笔试题
- 面试笔试题
- 面试笔试题重要~
- 常见面试笔试题
- 4399 面试笔试题
- 面试笔试题总结
- linux面试笔试题
- android面试笔试题
- 经典面试笔试题
- OGRE SDK 1.9安装配置
- oracle 11g 减少内存后,启动实例报错:ORA-00845: MEMORY_TARGET not supported on this system
- 深入Objective-C的动态特性
- Java集合类详解
- 实现O(1)获取最大最小值的栈----java
- 单链表相关面试笔试题
- 笔试题积累
- hdu 1867 A + B for you again KMP算法
- 觉得帮助到你了,可以转载保存分享给身边的朋友。
- 关于集合Set里每一个元素前会自动添加一个空格,不知道为什么,有待研究
- Peach Blossom Spring - HDU 4085 斯坦纳树
- tuples
- 使用Tomcat配置域名
- android.permission权限请求汇总