具体参考大佬的:https://blog.csdn.net/qq_37466121/article/details/88204678
#include <iostream>
#include <vector>
using namespace std;
struct listnode{
int val;
listnode* next;
//listnode(int x):val(x),next(NULL){}
};
listnode * createnode(int val)
{
listnode* p=new listnode;
p->val=val;
p->next=NULL;
return p;
}
listnode* addnode(listnode *head,int pos,int val)
{
listnode *p=head;
for(int i=1;i<pos;i++){
p=p->next;
if(p==NULL){
return p;
}
}
listnode* newnode=new listnode;
newnode->val=val;
newnode->next=p->next;
p->next=newnode;
return p;
}
/**
题目:
删除带头结点的单链表L中的结点p,p不是最后一个结点,要求时间复杂度为O(1)。
问题解答:
如果删除的结点p可能是最后一个结点,怎么办?
解题思路:此时只能保证删除结点的平均时间复杂度为O(1),当p不是最后一个结点,
时间复杂度为O(1),当p是最后一个结点时,时间复杂度为O(n)。
由于输入只有一个节点,且不包括链表的其他信息,所以我们没办法根据 “找前驱,改后继” 的方法来进行操作,所以在这里提出一个新的方法,“替换法”。
将待删除的节点元素值改为下一个节点的值,然后删除一个节点的值。根据 p->next = p->next->next 即把待删除节点当作前驱
*/
void delenode(listnode* deletenode){
if(deletenode==NULL) return ;
listnode* p=deletenode->next;
deletenode->val=p->val;
deletenode->next=p->next;
delete(p);
p=nullptr;
}
listnode * deleten_node(listnode *head,int n)
{
listnode *fastnode=new listnode;
listnode *slownode =new listnode;
listnode *dummy=new listnode;
dummy->next=head;
fastnode=dummy;
slownode=dummy;
for(int i=1;i<=n;i++){
fastnode=fastnode->next;
}
while(fastnode->next!=NULL){
fastnode=fastnode->next;
slownode=slownode->next;
}
delete(slownode->next);
slownode->next=slownode->next->next;
return dummy->next;
}
listnode* reverselist(listnode* head)
{
if(head==NULL||head->next==NULL){
return NULL;
}
listnode * p=head;
listnode * newnode=nullptr;
while(p){
listnode *temp=p->next;
p->next=newnode;
newnode=p;
p=temp;
}
return newnode;
}
/**
* @brief hascycle给一个链表,判断是否有环存在。为了表示链表中的环,我们用一个整数pos来表示环的位置,如果pos等于-1,则表示没有环
* @param head
* @return
*/
bool hascycle(listnode *head){
listnode *slow=head;
listnode *fast=head;
while(fast&&fast->next){
slow=slow->next;
fast-fast->next->next;
if(fast==slow){
return true;
}
}
return false;
}
void displaylist(listnode * head)
{
listnode *p=head;
while(p!=NULL){
cout<<p->val<<" ";
p=p->next;
}
}
//loop come cross
listnode * loopnode(listnode* head)
{
if(!head||!head->next){
return NULL;
}
listnode * fast=head;
listnode * slow=head;
while(fast!=nullptr&&fast->next!=nullptr)
{
fast=fast->next->next;
slow=slow->next;
if(slow==fast){
break;
}
}
fast=head;
if(fast==NULL||fast->next==NULL) return NULL;
while(fast!=slow){
fast=fast->next;
slow=slow->next;
}
return slow;
}
//如果存在环,求环上节点的个数
int numinloop(listnode* head)
{
listnode * fastnode=head;
listnode * slownode=head;
int count;
while(fastnode!=nullptr&&fastnode->next!=nullptr)
{
fastnode=fastnode->next->next;
slownode=slownode->next;
if(slownode==fastnode){
break;
}
}
if(slownode!=fastnode) return 0;
listnode* temp;
temp=slownode;
while(slownode!=fastnode){
slownode=slownode->next;
count++;
}
return count;
}
//两个链表相交的第一个公共节点
listnode* findfirstconmonNode(listnode* head1,listnode *head2)
{
listnode * p1=head1;
listnode * p2=head2;
while(p1!=p2){
p1=(p1==NULL)?head2:p1->next;
p2=(p2==NULL)?head1:p2->next;
}
return p1;
}
//在一个排序的链表中,如何删除重复的节点?例如,1-2-3-3-4-4-5删除之后变成了1-2-5
int main()
{
listnode *p = createnode(1);
addnode(p,1,2);
addnode(p,2,3);
addnode(p,3,4);
listnode *revnode=reverselist(p);
listnode *delnode=deleten_node(revnode,2);
displaylist(delnode);
return 0;
}