数据结构单链表OJ题

数据结构单链表OJ题_第1张图片

目录

合并两个有序链表

反转链表

链表的中间节点

链表中倒数第k个节点

链表分割

相交链表

链表的回文结构

链表分割

链表中倒数第k个结点



合并两个有序链表

21. 合并两个有序链表 - 力扣(LeetCode)

struct ListNode*head=NULL;
    struct ListNode*tail=NULL;
   //带哨兵位的单链表
   head=tail=(struct ListNode*)malloc(sizeof(struct ListNode));
//    if(list1==NULL)
//    return list2;
//     if(list2==NULL)
//    return list1;
   while(list1&&list2)
   {
       if(list1->valval)
       {
           tail->next=list1;
           tail=list1;
           list1=tail->next;
       }
       else
       {
            tail->next=list2;
           tail=list2;
           list2=tail->next;
       }
   }
   if(list1)
   {    
       tail->next=list1;
   }
    if(list2)
   {
       tail->next=list2;
   }
     if(list1==NULL&&list2==NULL)
     return NULL;
     struct ListNode *list=head->next;
     free(head);

反转链表

206. 反转链表 - 力扣(LeetCode)


struct ListNode* reverseList(struct ListNode* head){
    if(head==NULL)
    return NULL;
    else
    {
    struct ListNode* n1,*n2,*n3;
    n1=NULL;
     n2=head;
    n3=head->next;
    while(n2)
    {//反转
        n2->next=n1;
        //迭代
        n1=n2;
        n2=n3;
        if(n2!=NULL)
        n3=n3->next;


    }
    return n1;
}

}

定义n3是为了找到n2的next。

这道题有两处需要额外考虑的点:一个是head为空。n2=head,n3=n2->next会报错

还有一个就是n3为空,n3的next会报错 


struct ListNode* reverseList(struct ListNode* head){
    struct ListNode*cur=head;
    struct ListNode*next;
    struct ListNode*newhead=NULL;
    while(cur)
    {   //头插
        next=cur->next;
        cur->next=newhead;
        newhead=cur;
        //迭代
        cur=next;
    }
    return newhead;


}
这个是头插法
struct ListNode* reverseList(struct ListNode* head){
    struct ListNode*newhead=NULL;
    struct ListNode*cur=head;
     struct ListNode*curNext;
    while(cur)
    {   curNext=cur->next;
        cur->next=newhead;
        newhead=cur;
        cur=curNext;
    }
    return newhead;
}


876. 链表的中间结点 - 力扣(LeetCode)

链表的中间节点

这道题用到了快慢指针,快指针一次走两步,慢指针一次走1步,这样快指针到尾的时候慢指针到中间,(当为奇数的时候中间只有一个慢指针指向中间,当为偶数的时候中间有两个,慢指针指向中间靠后的那一个)

注意:循环的结束条件 当为偶数的时候快指针结束的时候指向空,当为奇数个的时候快指针结束的时候指向最后一个。

while(fast!=NULL&&fast->next!=NULL)

struct ListNode* middleNode(struct ListNode* head){
    struct ListNode*slow=head,*fast=head; 
    while(fast!=NULL&&fast->next!=NULL)
    {
        fast=fast->next->next;
        slow=slow->next;
    }
    return slow;
}
用到了快慢指针,快指针速度是慢指针的两倍这样快指针走到尾的时候慢指针走到中间。还要考虑大小的奇偶性
奇数的中间就是中间,偶数的中间有两个,slow指向的是靠后的那一个,
偶数的时候fast一直走结果是NULL,奇数一直走结果是最后一个。画个图就容易明白了。


链表中倒数第k个结点_牛客题霸_牛客网 (nowcoder.com)

链表中倒数第k个节点


21. 合并两个有序链表 - 力扣(LeetCode)

合并两个有序链表

不带哨兵位的

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    struct ListNode*head=NULL;
    struct ListNode*tail=NULL;
    if(list1==NULL)
    return list2;
       if(list2==NULL)
    return list1;

    while(list1&&list2)
    {   
        if(list1->valval)
        {  
             if(head==NULL)
             {
                 head=tail=list1;
             }
             else
             {
                 tail->next=list1;
                 tail=list1;
             }
             list1=list1->next;
        }
        else
        {
            if(head==NULL)
            {
                head=tail=list2;
            }
            else
            {
                tail->next=list2;
                tail=list2;
            }
            list2=list2->next;
        }
    }
    if(list1)//list2为NULL
    {
        tail->next=list1;
    }
    if(list2)//list1为NULL
    {
        tail->next=list2;
    }
    return head;
}

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    struct ListNode*head=NULL;
    struct ListNode*tail=NULL;
   //带哨兵位的单链表
   head=tail=(struct ListNode*)malloc(sizeof(struct ListNode));
//    if(list1==NULL)
//    return list2;
//     if(list2==NULL)
//    return list1;
   while(list1&&list2)
   {
       if(list1->valval)
       {
           tail->next=list1;
           tail=list1;
           list1=tail->next;
       }
       else
       {
            tail->next=list2;
           tail=list2;
           list2=tail->next;
       }
   }
   if(list1)
   {    
       tail->next=list1;
   }
    if(list2)
   {
       tail->next=list2;
   }
     if(list1==NULL&&list2==NULL)
     return NULL;
     struct ListNode *list=head->next;
     free(head);
   return list;
}


链表分割_牛客题霸_牛客网 (nowcoder.com)

链表分割

    struct ListNode*lessHead=(struct ListNode*)malloc(sizeof(struct ListNode));
        struct ListNode*greaterHead=(struct ListNode*)malloc(sizeof(struct ListNode));
        struct ListNode*lesstail=lessHead;
        struct ListNode*greatertail=greaterHead;
        struct ListNode*cur=pHead;
        while(cur)
        {
            if(cur->valnext=cur;
                lesstail=cur;
                cur=cur->next;
            }
            else
            {
                greatertail->next=cur;
                greatertail=cur;
                cur=cur->next;
            }
            
        }
        greatertail->next=NULL;
        lesstail->next=greaterHead->next;
        return lessHead->next;





    }

160. 相交链表 - 力扣(LeetCode)

相交链表

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
//    if(headA==NULL||headB==NULL)
//    return NULL;
//找到两个链表的尾它们的地址相同则为相交链表,不相同不是。
//然后让长的链表早走(它们的长度差距步),然后它俩一起走,直到地址相同
    struct ListNode *tailA=headA;
    struct ListNode *tailB=headB;
    int lengA=1;
    while(tailA->next)
    {   lengA++;
        tailA=tailA->next;
    }
        int lengB=1;
       while(tailB->next)
    {   lengB++;
        tailB=tailB->next;
    }
    if(tailA!=tailB)
    {
        return NULL;
    }
    int gap=abs(lengA-lengB);
    //先假设A长,后面的if用来预防假设不成立的情况,也可以用三目
    // struct ListNode *longlist=headA;
    // struct ListNode *shortlist=headB;
    // if(lengAlengB?headA:headB;
    struct ListNode *shortlist=lengA>lengB?headB:headA;
    while(gap--)
    {
        longlist=longlist->next;
    }
    while((shortlist!=longlist))
    {
        shortlist=shortlist->next;
        longlist=longlist->next;
    }
    return longlist;

}


链表的回文结构

链表的回文结构_牛客题霸_牛客网 (nowcoder.com)

struct ListNode * reverse(struct ListNode *head)
{
    struct ListNode *n1,*n2,*n3;
    n1=NULL;
    n2=head;
    n3=head->next;
    while(n2)
    {
        n2->next=n1;

        n1=n2;
        n2=n3;
        n3=n3->next;
    }
    return n1;//返回的是反转的头结点的地址,或者说指向头结点的指针
}
struct ListNode *findmid(struct ListNode *head)
{
    struct ListNode *fast=head,*slow=head;
    while(fast&&fast->next)
    {
        fast=fast->next->next;
        slow=slow->next;
    }
    return slow;//返回的是中间节点的地址/指向中间节点的指针
}
class PalindromeList {
public:
    bool chkPalindrome(ListNode* A) {
        struct ListNode *mid=findmid(A);
         struct ListNode *reversehead=reverse(mid);
         //把反转的头地址赋给reversehead
         while(A&&reversehead)
         {
             if(A->val!=reversehead->val)
             {
                 return false;
             }
             else
             {
                 A=A->next;
                 reversehead=reversehead->next;
             }
         }
         return true;
        //如果前面一次没有发现不相等那么说明全部相等

    }
};

链表分割_牛客题霸_牛客网 (nowcoder.com)

链表分割

        //尾插建立头结点不用考虑第一个
        struct ListNode*lesshead=(struct ListNode*)malloc(sizeof(struct ListNode));
        struct ListNode*greaterhead=(struct ListNode*)malloc(sizeof(struct ListNode));
        struct ListNode*lesstail=lesshead;
        struct ListNode*greatertail=greaterhead;
        struct ListNode*tail=pHead;
        while(tail)
        {
            if(tail->valnext=tail;
                lesstail=tail;
                tail=tail->next;
            }
            else
            {
                greatertail->next=tail;
                greatertail=tail;
                tail=tail->next;
            }

        }
        greatertail->next=NULL;//特殊情况处理,防止出现环死循环
        lesstail->next=greaterhead->next;
        struct ListNode*newhead=lesshead->next;

        free(lesshead);
        lesshead=NULL;
        free(greaterhead);
        greaterhead=NULL;


        return newhead;


链表中倒数第k个结点_牛客题霸_牛客网 (nowcoder.com)

链表中倒数第k个结点


    struct ListNode*fast,*slow;
    slow=fast=pListHead;
    if(pListHead==NULL)
    {
        return NULL;
    }
    while(k)
    
    {   if(fast==NULL)
        {
            return NULL;
        }
        fast=fast->next;
        k--;
    }
    while(fast)
    {
        fast=fast->next;
        slow=slow->next;
    }
    return slow;
这道题要考虑K大于链表长度的时候返回空

其实碰见head->next之类的
就要考虑head为空的情况

你可能感兴趣的:(数据结构,数据结构,链表,算法)