链表的一些练习
1.赋值当前结点到当前节点得后面和当前结点之间
2.赋值random指针
3.分离两个链表
struct RandomListNode { int label; struct RandomListNode *next, *random; RandomListNode(int x) :label(x), next(NULL), random(NULL) {} }; class Solution { public: RandomListNode* Clone(RandomListNode* pHead) { if(!pHead) return pHead; RandomListNode *p=pHead,*temp=NULL,*New=NULL; //复制当前节点到当前节点和它后面的结点之间 while(p) { temp=(*p).next; New=new RandomListNode((*p).label); (*New).next=(*p).next; (*p).next=New; p=temp; } p=pHead,New=(*p).next; while(p) { if((*p).random) (*New).random=(*(*p).random).next; p=(*New).next; if(p) New=(*p).next; } p=pHead,New=(*p).next; RandomListNode* NHead=New; while((*New).next) { temp=(*New).next; (*p).next=(*New).next; (*New).next=(*temp).next; p=temp; New=(*p).next; } (*p).next=NULL; return NHead; } };
找到新的头结点,逆置(此时要记录新的头结点和调整好的链表的尾)
#include<iostream> #include<string> #include<stack>//pop,top,push #include<vector> using namespace std; struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class KInverse { public: ListNode* inverse(ListNode* head, int k) { if(!head||k<2) return head; ListNode *p=head,*q=head,*LastTail=NULL; int i=1,count=0; while(q) { if(i==k) { if(!count)//第一次逆置,保存新的头结点 head=q; else//把新的头结点连接到已经逆置好的链表的尾部 (*LastTail).next=q; ListNode *temp1=(*q).next; while(q!=p) { ListNode *temp2=(*p).next; if((*q).next==temp1)//保存已经逆置好的链表的尾结点 LastTail=p; (*p).next=(*q).next; (*q).next=p; p=temp2; } p=q=temp1; i=1; count++; } if(q) q=(*q).next; i++; } return head; } }; class CreatListNode { public: ListNode* Creat(vector<int> A) { if(A.empty()) return NULL; ListNode *Head=new ListNode(A[0]),*p=Head; for(vector<int>::iterator iter=A.begin()+1;iter!=A.end();iter++) { (*p).next=new ListNode(*iter); p=(*p).next; } return Head; } void Print(ListNode* Head) { ListNode *p=Head; while(p) { cout<<(*p).val<<" "; p=(*p).next; } } }; int main() { int a[8]={1,2,3,4,5,6,7,8}; vector<int> arr(a,a+8); CreatListNode C; ListNode *HeadA=C.Creat(arr); KInverse D; ListNode *head=D.inverse(HeadA,3); C.Print(head); return 0; }
从头比较两个链表(A,B)的元素,若A->val<B->val,A继续向前移动,A->val>B->val,B继续向前移动,否则打印想等元素
#include<iostream> #include<string> #include<stack>//pop,top,push #include<vector> using namespace std; struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class Common { public: vector<int> findCommonParts(ListNode* headA, ListNode* headB) { vector<int> res; ListNode *p=headA,*q=headB; while(p&&q) { if((*p).val==(*q).val) { res.push_back((*p).val); p=(*p).next; q=(*q).next; } else if((*p).val<(*q).val) p=(*p).next; else q=(*q).next; } return res; } }; class CreatListNode { public: ListNode* Creat(vector<int> A) { if(A.empty()) return NULL; ListNode *Head=new ListNode(A[0]),*p=Head; for(vector<int>::iterator iter=A.begin()+1;iter!=A.end();iter++) { (*p).next=new ListNode(*iter); p=(*p).next; } return Head; } void Print(ListNode* Head) { ListNode *p=Head; while(p) { cout<<(*p).val<<" "; p=(*p).next; } } }; int main() { int a[7]={1,2,3,4,5,6,7},b[5]={2,4,6,8,10}; vector<int> arr(a,a+7),brr(b,b+5); CreatListNode C; ListNode *HeadA=C.Creat(arr); ListNode *HeadB=C.Creat(brr); Common D; vector<int> res=D.findCommonParts(HeadA,HeadB); for(vector<int>::iterator iter=res.begin();iter!=res.end();iter++) cout<<*iter<<" "; return 0; }
#include<iostream> #include<string> #include<stack>//pop,top,push #include<vector> using namespace std; struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class ChkIntersection { public: bool chkInter(ListNode* head1, ListNode* head2, int adjust0, int adjust1) { ListNode *entry1=chkLoop(head1),*entry2=chkLoop(head2); if(entry1!=NULL&&entry2!=NULL) return chkInter(head1,head2); if(entry1==NULL&&entry2==NULL) return chkIntersect(head1,head2); return false; } bool chkIntersect(ListNode* headA, ListNode* headB)//无环单链表判相交 { if(!headA||!headB) return false; //先求AB链表的长度 int NumofA=0,NumofB=0,count=0; ListNode *p=headA; while(p) { NumofA++; p=(*p).next; } p=headB; while(p) { NumofB++; p=(*p).next; } ListNode *L=NULL,*S=NULL; if(NumofA>NumofB) L=headA,S=headB; else L=headB,S=headA; count=(NumofA>NumofB)?(NumofA-NumofB):(NumofB-NumofA); while(count--) L=(*L).next; while(L&&S) { if(L==S) return true; L=(*L).next; S=(*S).next; } return false; } bool chkInter(ListNode* head1, ListNode* head2)//有环判相交 { ListNode *entry1=chkLoop(head1),*entry2=chkLoop(head2); if(entry1==NULL||entry2==NULL) return false; if(entry1==entry2)//判断两个环的入口节点是不是同一个结点 return true; else { ListNode *p=(*entry1).next; while(p!=entry1) { if(p==entry2) return true; p=(*p).next; } return false; } } ListNode* chkLoop(ListNode* head)//链表判环 { if(!head) return NULL; ListNode *slow=head,*fast=head; while(((*fast).next&&(*(*fast).next).next))//慢的链表一次走一步,快的一次走两步,若有环肯定在环内相交 { slow=(*slow).next; fast=(*(*fast).next).next; if(slow==fast) break; } if(!(*fast).next||!(*(*fast).next).next)//判断跳出while的原因,若是快指针走到表尾,则无环 return NULL; slow=head; while(slow!=fast)//找到环的入口 { slow=(*slow).next; fast=(*fast).next; } return fast; } }; int main() { return 0; }
执行元素复制操作,删除最后一个结点
#include<iostream> #include<string> #include<stack>//pop,top,push #include<vector> using namespace std; struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class Remove { public: bool removeNode(ListNode* pNode) { if((*pNode).next==NULL) return false; ListNode *p=(*pNode).next,*pre=pNode; while((*p).next!=NULL) { (*pre).val=(*p).val; pre=p; p=(*p).next; } (*pre).val=(*p).val; (*pre).next=NULL; delete p; p=NULL; return true; } }; int main() { return 0; }
#include<iostream> #include<string> #include<stack>//pop,top,push #include<vector> using namespace std; struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class InsertValue { public: ListNode* insert(vector<int> A, vector<int> nxt, int val) { if(A.empty()) { ListNode *Head=new ListNode(val); //(*Head).next=Head;//1 return Head; } //构造链表 ListNode *Head=new ListNode(A[0]),*p=Head; for(vector<int>::iterator iter=nxt.begin();iter!=nxt.end();iter++) { if(*iter==0) { (*p).next=Head; break; } (*p).next=new ListNode(A[*iter]); p=(*p).next; } //找到合适的地方插入新的节点 ListNode *pre=Head,*now=(*Head).next; while(now!=Head) { if((*pre).val<=val&&(*now).val>=val) { ListNode *p=new ListNode(val); (*p).next=now; (*pre).next=p; break; } else { pre=now; now=(*now).next; } } //要插入的元素小于链表中所有的元素或大于链表中所有的元素都会在链表的最后一个结点和第一个结点间插入元素 if(now==Head) { ListNode *p=new ListNode(val); (*p).next=now; (*pre).next=p; if(val<(*Head).val)//判断新头部的位置 Head=p; } //消除环 pre=Head,p=(*Head).next;//2 while(p!=Head) { pre=p; p=(*p).next; } (*pre).next=NULL;//2 return Head; } }; int main() { int a[7]={3,3,7,7,8,12,13},nxt[7]={1,2,3,4,5,6,0}; vector<int> arr(a,a+7),next(nxt,nxt+7); InsertValue s; ListNode* Head=s.insert(arr,next,11); ListNode *p=(*Head).next; cout<<(*Head).val<<" "; while(p!=NULL) { cout<<(*p).val<<" "; p=(*p).next; } return 0; }
#include<iostream> #include<string> #include<stack>//pop,top,push #include<vector> using namespace std; struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class Divide { public: ListNode* listDivide(ListNode* head, int val) { ListNode *smallh=NULL,*smallt=NULL,*bigh=NULL,*bigt=NULL,*p=head,*q=head; while(p) { q=p; if((*p).val<=val) { if(!smallh) smallh=smallt=p; else { (*smallt).next=p; smallt=p; } } else { if(!bigh) bigh=bigt=p; else { (*bigt).next=p; bigt=p; } } //断开链表 p=(*p).next; (*q).next=NULL; } if(smallh) { head=smallh; if(bigh) (*smallt).next=bigh; } else if(bigh) head=bigh; return head; } }; class CreatListNode { public: ListNode* Creat(vector<int> A) { if(A.empty()) return NULL; ListNode *Head=new ListNode(A[0]),*p=Head; for(vector<int>::iterator iter=A.begin()+1;iter!=A.end();iter++) { (*p).next=new ListNode(*iter); p=(*p).next; } return Head; } void Print(ListNode* Head) { ListNode *p=Head; while(p) { cout<<(*p).val<<" "; p=(*p).next; } } }; int main() { int a[5]={1620,1134,861,563,1}; vector<int> arr(a,a+5); CreatListNode C; ListNode *Head=C.Creat(arr); Divide D; Head=D.listDivide(Head,1134); C.Print(Head); return 0; }
1.用数组做额外空间,遍历一遍链表,从数组两端比较元素,额外空间复杂度O(n)
2.用栈做额外空间,把链表的前一半元素入栈,然后开始比较链表的后半段元素与栈中元素,额外空间复杂度0(n/2)
3.更改链表结构,从两端比较,如下
#include<iostream> #include<string> #include<stack>//pop,top,push #include<vector> using namespace std; struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class Palindrome { public: bool isPalindrome(ListNode* pHead) { if(!pHead||!(*pHead).next) return true; ListNode *slow=pHead,*fast=pHead; int odd=0; //快指针每次走两步,慢指针每次走一步,快指针走到表尾,满指针走到中间 while(fast->next&&fast->next->next) { fast=(*(*fast).next).next; slow=(*slow).next; } if(!fast->next) odd=1; /**< 以下代码是把链表:1->2->3->4->5->6变为:1->2->3->4<-5<-6*/ ListNode *pre=slow,*now=(*pre).next,*temp=NULL; (*slow).next=NULL; while(now) { temp=(*now).next; (*now).next=pre; pre=now; now=temp; } /**< 从两端向中间比较 */ bool res=true; ListNode *fwd=pHead,*tai=pre; while(tai!=slow) { if((*fwd).val!=(*tai).val) { res=false; break; } fwd=(*fwd).next; tai=(*tai).next; } //把链表归为 now=pre; pre=(*pre).next; (*now).next=NULL; while(pre) { temp=(*pre).next; (*pre).next=now; now=pre; pre=temp; } return res; } /*·½°¸Ò»£º bool isPalindrome(ListNode* pHead) { stack<ListNode *> res; ListNode *slow=pHead,*fast=pHead; int odd=0,even=odd; while(fast) { fast=(*fast).next; if(!fast) { odd=1; break; } fast=(*fast).next; if(!fast) { even=1; break; } res.push(slow); slow=(*slow).next; } if(odd) slow=(*slow).next; if(even) { res.push(slow); slow=(*slow).next; } while(slow) { if((*res.top()).val!=(*slow).val) return false; res.pop(); slow=(*slow).next; } return true; }*/ }; class CreatListNode { public: ListNode* Creat(vector<int> A) { if(A.empty()) return NULL; ListNode *Head=new ListNode(A[0]),*p=Head; for(vector<int>::iterator iter=A.begin()+1;iter!=A.end();iter++) { (*p).next=new ListNode(*iter); p=(*p).next; } return Head; } void Print(ListNode* Head) { ListNode *p=Head; while(p) { cout<<(*p).val<<" "; p=(*p).next; } } }; int main() { int a[5]={1,2,3,2,1}; vector<int> arr(a,a+5); CreatListNode C; ListNode *HeadA=C.Creat(arr); Palindrome D; bool res=D.isPalindrome(HeadA); cout<<res; C.Print(HeadA); return 0; }
#include<iostream> #include<string> #include<stack>//pop,top,push #include<vector> using namespace std; struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class ChkLoop { public: int chkLoop(ListNode* head, int adjust) { if(!head) return -1; ListNode *slow=head,*fast=head; while(((*fast).next&&(*(*fast).next).next)) { slow=(*slow).next; fast=(*(*fast).next).next; if(slow==fast) break; } if(!(*fast).next||!(*(*fast).next).next) return -1; slow=head; while(slow!=fast) { slow=(*slow).next; fast=(*fast).next; } return (*fast).val; } }; int main() { return 0; }
#include<iostream> #include<string> #include<stack>//pop,top,push #include<vector> using namespace std; struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class ClearValue { public: ListNode* clear(ListNode* head, int val) { if(!head) return head; ListNode *Head=NULL,*Tail=NULL,*p=head,*temp=NULL; while(p) { temp=(*p).next; if((*p).val==val) delete p; else { if(!Head) Head=p; else (*Tail).next=p; Tail=p; (*Tail).next=NULL; } p=temp; } return Head; } }; class CreatListNode { public: ListNode* Creat(vector<int> A) { if(A.empty()) return NULL; ListNode *Head=new ListNode(A[0]),*p=Head; for(vector<int>::iterator iter=A.begin()+1;iter!=A.end();iter++) { (*p).next=new ListNode(*iter); p=(*p).next; } return Head; } void Print(ListNode* Head) { ListNode *p=Head; while(p) { cout<<(*p).val<<" "; p=(*p).next; } } }; int main() { int a[7]={1,2,3,4,3,2,1}; vector<int> arr(a,a+7); CreatListNode C; ListNode *HeadA=C.Creat(arr); ClearValue D; ListNode *head=D.clear(HeadA,2); C.Print(head); return 0; }
#include<iostream> #include<string> #include<stack>//pop,top,push #include<vector> using namespace std; struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class CheckIntersect { public: bool chkIntersect(ListNode* headA, ListNode* headB) { if(!headA||!headB) return false; int NumofA=0,NumofB=0,count=0; ListNode *p=headA; while(p) { NumofA++; p=(*p).next; } p=headB; while(p) { NumofB++; p=(*p).next; } ListNode *L=NULL,*S=NULL; if(NumofA>NumofB) L=headA,S=headB; else L=headB,S=headA; count=(NumofA>NumofB)?(NumofA-NumofB):(NumofB-NumofA); while(count--) L=(*L).next; while(L&&S) { if(L==S) return true; L=(*L).next; S=(*S).next; } return false; } }; int main() { return 0; }
#include<iostream> #include<string> #include<stack>//pop,top,push #include<vector> using namespace std; struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class ChkIntersection { public: bool chkInter(ListNode* head1, ListNode* head2, int adjust0, int adjust1) { ListNode *entry1=chkLoop(head1),*entry2=chkLoop(head2); if(entry1==NULL||entry2==NULL) return false; if(entry1==entry2) { /*int Numof1=0,Numof2=0,count=0;//注释为返回第一个相交结点 ListNode *p=head1; while(p!=entry1) { Numof1++; p=(*p).next; } p=head2; while(p!=entry1) { Numof2++; p=(*p).next; } ListNode *L=NULL,*S=NULL; if(Numof1>Numof2) L=head1,S=head2; else L=head2,S=head1; count=(Numof1>Numof2)?(Numof1-Numof2):(Numof2-Numof1); while(count--) L=(*L).next; while(L!=entry1&&S!=entry2) { if(L==S) break; L=(*L).next; S=(*S).next; } return L;*/ return true; } else { ListNode *p=(*entry1).next; while(p!=entry1) { if(p==entry2) return true; p=(*p).next; } return false; } } ListNode* chkLoop(ListNode* head) { if(!head) return NULL; ListNode *slow=head,*fast=head; while(((*fast).next&&(*(*fast).next).next)) { slow=(*slow).next; fast=(*(*fast).next).next; if(slow==fast) break; } if(!(*fast).next||!(*(*fast).next).next) return NULL; slow=head; while(slow!=fast) { slow=(*slow).next; fast=(*fast).next; } return fast; } }; int main() { return 0; }
- 都无环:无环单链表判交
- 一个有环,一个无环:必然不想交,直接返回false
- 都有环:无环单链表判交
- 辅助函数:判断是否有环,返回入环结点。