常用的链表手撕代码整理

具体参考大佬的: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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值