您的位置:首页 > 职场人生

常见算法面试链表

2017-07-03 15:15 447 查看

算法总结——链表

算法总结——链表:

数组建立链表
打印链表
插入节点(头插)
查找节点
删除节点
反转链表
找出单链表的倒数第k个元素
两个单链表相交,计算相交点
找出中间节点
单链表排序,时间复杂度O(n2)
单链表排序,时间复杂度O(nlogn)——归并排序,详见leetcode sort list
合并两个有序链表,虚拟节点法——详见归并排序的merge
判断链表是否有环,如果有环,计算环的长度;如果无环,则返回-1
删除单链表中重复的元素,借助map实现
用链表模仿大整数加法,leetcode有类似题目,当时用的是循环,此次试试递归
二级链表,每个节点指向一个链表,将其转为单链表
 

#include <iostream>
#include <map>
#include <vector>
using namespace std;

struct ListNode{
int val;
ListNode* next;
ListNode(int x):val(x),next(NULL){};
};

//数组建立链表
ListNode* ConstructLinkedList(vector<int> List){
if(List.size()==0)
return NULL;
ListNode* head = new ListNode(List[0]);
ListNode* p=head;
for(int i=1;i<List.size();i++){
p->next=new ListNode(List[i]);
p=p->next;
}
p->next=NULL;
return head;
}

//打印链表
void PrintList(ListNode* head){
if(head==NULL)
return;
ListNode *p=head;
while(p!=NULL){
cout<<p->val<<"->";
p=p->next;
}
return;
}

//插入节点(头插)
ListNode* InsertNode(ListNode* head,int val){
ListNode* p= new ListNode(val);
p->next=head;
head=p;
return head;
}
//查找节点
ListNode* FindNode(ListNode* head,int val){
if(head==NULL)
return NULL;
ListNode* p=head;
while(p!=NULL){
if(p->val==val)
return p;
p=p->next;
}
return NULL;
}
//删除节点
ListNode* DeleteNode(ListNode* head,int val){
if(head==NULL){
cout<<"List is empty!"<<endl;
exit(1);
}
//delete the head node
ListNode* p=head;
if(head->val==val){
head=head->next;
delete(p);
return head;
}
ListNode* q=p;
while(p!=NULL){
if(p->val==val){
//delete the tail node
if(p->next==NULL){
q->next=NULL;
delete(p);
}
else{
q->next=p->next;
delete(p);
}
}
p=p->next;
q=p;
}
return head;
}
//反转链表
ListNode* ReverseList(ListNode* head){
if(head==NULL||head->next==NULL)
return head;
ListNode* p=head->next,*q=head,*l=head;
while(p->next!=NULL){
l=p->next;
p->next=q;
q=p;
p=l;
}
p->next=q;
head->next=NULL;
return p;
}
//找出单链表的倒数第k个元素
ListNode* FindTheNode(ListNode* head,int k){
if(head==NULL||k==0)
return NULL;
ListNode* p=head,*q=head;
int len=abs(k);
while(len>0){
p=p->next;
--len;
}
if(k<0)
return p;
while(p!=NULL){
p=p->next;
q=q->next;
}
return q;
}
//两个单链表相交,计算相交点
//解法1:对齐长度后再循环判断
//解法2:链表A的尾巴指向链表B的头部,判断环入口点
ListNode* FindInsectNode(ListNode* l1,ListNode* l2){
ListNode* p=l1;
ListNode* q=l2;
int len1=0,len2=0;
while(p!=NULL)
len1++;
while(q!=NULL)
len2++;

for(int i=0;i<len1-len2;i++)
p=p->next;
for(int j=0;j<len2-len1;j++)
q=q->next;
while(q!=NULL&&p!=NULL&&q->val!=p->val){
p=p->next;
q=q->next;
}
return q;
}
//找出中间节点
ListNode* FindMiddleNode(ListNode* head){
if(head==NULL||head->next==NULL)
return head;
ListNode* p=head,*q=head;
while(p&&p->next!=NULL){
p=p->next->next;
q=q->next;
}
return q;
}
//单链表冒泡排序,时间复杂度O(n2)
ListNode* SortList1(ListNode* head){
if(head==NULL||head->next==NULL)
return head;
ListNode* p=head;
int length;
while(p!=NULL){
length++;
p=p->next;
}
while(length>0){
ListNode* j=head;
ListNode* k=j->next;
if(j->val>k->val){
int tmp=j->val;
j->val=k->val;
k->val=tmp;
}
}
}
//单链表插入排序

ListNode* insertionSortList(ListNode* head) {
if(head==NULL||head->next==NULL)
return head;
ListNode* newhead = new ListNode(-2147483648);
newhead->next=head;
ListNode* q=head;
ListNode* p=head->next;
while(p!=NULL){
ListNode* s1=newhead;
ListNode* s2=s1->next;
while(s2!=p&&s2->val<=p->val){
s1=s2;
s2=s2->next;
}
if(s2!=p){
s1->next=p;
q->next=p->next;
p->next=s2;

p=q->next;}
else{
q=p;
p=p->next;
}
}
return newhead->next;
}
//单链表排序,时间复杂度O(nlogn)——归并排序,详见leetcode sort list
//合并两个有序链表,虚拟节点法——详见归并排序的merge
//判断链表是否有环

bool hasCycle(ListNode *head) {
if(head==NULL||head->next==NULL||head->next->next==NULL)
return false;
if(head->next==head||head->next->next==head)
return true;
ListNode* quick=head->next->next;
ListNode* slow=head->next;
while((quick!=NULL&&quick->next!=NULL)&&slow!=quick){
quick=quick->next->next;
slow=slow->next;
}
if(quick==NULL||quick->next==NULL)
return false;
return true;
}

//判断链表是否有环,如果有环,计算环的长度;如果无环,则返回-1
bool CalCircle(ListNode* head,ListNode* intersect,int& cirlen){
intersect=NULL;
cirlen=-1;
int step=0;
if(head==NULL||head->next==NULL||head->next->next==NULL)
return false;
if(head->next==head){
intersect=head;
cirlen=0;
return true;

}
if(head->next->next==head){
intersect=head;
cirlen=1;
     return true;
}
ListNode* quick=head->next->next,*slow=head;
while((quick!=NULL&&quick->next!=NULL)||slow!=quick){
quick=quick->next->next;
slow=slow->next;
step++;
}
if(quick==NULL||quick->next==NULL)
return false;
if(slow==quick){
intersect=slow;
cirlen=step/2;
}
return true;
}

//删除单链表中重复的元素,借助map实现
ListNode* DeleteCopy(ListNode* head){
if(head==NULL||head->next==NULL)
return head;
map<int,int> List;
ListNode* p=head,*q=head;
while(p!=NULL){
if(List.find(p->val)==List.end()){
List[p->val]=1;
q=p;
p=p->next;
}
else{
q->next=p->next;
delete(p);
p=q->next;
}
}
return head;
}

//用链表模仿大整数加法,leetcode有类似题目,当时用的是循环,此次试试递归
ListNode* AddNumber(ListNode* l1,ListNode* l2,int& carry)
{
if(!l1&&!l2){
if(carry>0)
return new ListNode(carry);
else return NULL;
}
ListNode* tmp=l1;
if(l1==NULL||l2==NULL){
if(l1==NULL){
tmp=l2;
carry+=tmp->val;
tmp->val=carry%10;
carry/=10;
tmp->next=AddNumber(l1,l2->next,carry);
}
else {
tmp=l1;
carry+=tmp->val;
tmp->val=carry%10;
carry/=10;
tmp->next=AddNumber(l1->next,l2,carry);
}
return tmp;
}

carry+=(l1->val+l2->val);
tmp->val=carry%10;
carry/=10;
tmp->next=AddNumber(l1->next,l2->next,carry);
return tmp;
}

struct ListofList{
ListNode* head;
ListofList* next;
};
//二级链表,每个节点指向一个链表,将其转为单链表
ListNode* GenerateList(ListofList* HList){
if(HList==NULL)
return NULL;
ListofList *p=HList;
ListNode *ret=HList->head;
while(p->next!=NULL)
{
ListNode *q=p->head;
while(q->next!=NULL)
q=q->next;
q->next=p->next->head;
p=p->next;
}
return ret;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐