数据结构初阶 单链表oj 个人随堂笔记

oj

无头单链表删除指定位置的值
方法:将指定位置下一个的值给指定位置,删除指定位置节点。(替换法删除,但是无法删除尾节点)

移除链表元素
给一个链表的头结点head和一个整数val,删除链表中所有满足Node val==val的节点,并返回新的头节点。

方法一:在原链表上删除
方法二:新造newnode,遍历原链表将非val值的节点尾插到newnode

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* removeElements(struct ListNode* head, int val)
{
    struct ListNode* cur=head;
    struct ListNode* prev=NULL;
    while(cur)
    {
        if(cur->val==val)
        {
            if(cur==head)
            {
                head=cur->next;
                free(cur);
                cur=head;
            }
            else
            {
                prev->next=cur->next;
                free(cur);
                cur=prev->next;
            }
        }
        else        
        {
            prev=cur;
            cur=cur->next;
        }
    }
    return head;
}

查找一个链表的中间节点
给一个单链表的头节点head,找出并返回中间节点,若果有两个中间节点,则返回第二个中间节点。
方法 一:先遍历一遍算长度,在遍历一遍到中间节点
方法二:快慢指针,慢指针一次走一个节点,快指针一次走两个节点,快指针到尾结点时,慢指针到中间节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* middleNode(struct ListNode* head)
{
    struct ListNode* fastpoint,*slowpoint;
    fastpoint=head;
    slowpoint=head;
    while(fastpoint&&fastpoint->next)
    {
        fastpoint=fastpoint->next->next;
        slowpoint=slowpoint->next;     
    }
    return slowpoint;
}

反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* reverseList(struct ListNode* head)
{
    struct ListNode*point1,*point2,*point3;
     point1=NULL;
     point2=head;

    if(point2)
    {
        point3=point2->next;
    }
    while(point2)
    {
        point2->next=point1;
        point1=point2;
        point2=point3;
        if(point3)
        {
             point3=point3->next;
        }
    }
    return point1;
}

链表中倒数第k个节点
给一个带你链表的头节点,找出并返回倒数第k个节点
方法一:快慢指针,快指针先走k步,快慢指针在一起走知道快指针到NULL

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

/**
 * 
 * @param pListHead ListNode类 
 * @param k int整型 
 * @return ListNode类
 */
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
    // write code here
    struct ListNode* fast=pListHead,*slow=pListHead;
    while(k--)
    {   
        if(fast==NULL)
            return NULL;
        fast=fast->next;
    }
    while(fast)
    {
        fast=fast->next;
        slow=slow->next;
    }
    return slow;
}

合并两个有序链表
将两个升序链表合并为一个新 的升序链表订单回,新链表是通过拼接给定的两个链表的所有节点组成的

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    struct ListNode* newhead=NULL,*tail=NULL;
    if(list1==NULL)
        return list2;
    if(list2==NULL)
        return list1;
    while(list1 && list2)
    {
        if(list1->val<list2->val)
            {
                if(tail==NULL)
                {
                    newhead=list1;
                    tail=newhead;
                }                    
                else
                {
                    tail->next=list1;
                    tail=tail->next;
                }
                list1=list1->next;
            }
        else
            {
                if(tail==NULL)
                {
                    newhead=list2;
                    tail=newhead;
                }                    
                else
                  {
                     tail->next=list2;
                    tail=tail->next;

                  }
                list2=list2->next;
            }
    }
    if(list1)
        tail->next=list1;
    if(list2)
        tail->next=list2;
    return newhead;
}

相交链表
给出两个单链表的头节点

1:先遍历计算A与B的长度并判断是否相交
2:长的链表下走差距步

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode *cura=headA,*curb=headB;
    int lena=0,lenb=0;
    while(cura->next)
    {
        lena++;
        cura=cura->next;
    }
    while(curb->next)
    {
        lenb++;
        curb=curb->next;
    }
    if(cura!=curb)
    {
        return NULL;
    }
    struct ListNode * longlist=headA;
    struct ListNode * shortlist=headB;
    if(lena<lenb)
    {
        longlist=headB;
        shortlist=headA;
    }
    int gap=abs(lena-lenb);
    while(gap--)
    {
        longlist=longlist->next;
    }
    while(longlist!=shortlist)
    {
        longlist=longlist->next;
        shortlist=shortlist->next;
    }
    return longlist ;
}

复杂度O(N)

链表分割
现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
#include <cstddef>
#include <cstdlib>
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        struct ListNode* biglist,*btail,*smalllist,*stail;
        biglist=btail=( struct ListNode*)malloc(sizeof( struct ListNode*));
        smalllist=stail=( struct ListNode*)malloc(sizeof( struct ListNode*));
         ListNode* cur=pHead;
        while(cur)
        {
            if(cur->val<x)
        {
            
  
            stail->next=cur;
            stail=stail->next;


        }
        else 
        {

        
            btail->next=cur;
            btail=btail->next;


        
        }
            cur=cur->next; 

        }
        stail->next=biglist->next;

        btail->next=NULL;

        struct ListNode *head =smalllist->next;

        free(smalllist);
        free(biglist);

        return head;

    }
};

判断回文链表
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。

给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。

测试样例:

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

struct ListNode* reverseList(struct ListNode* head)
{
    struct ListNode*point1,*point2,*point3;
     point1=NULL;
     point2=head;

    if(point2)
    {
        point3=point2->next;
    }
    while(point2)
    {
        point2->next=point1;
        point1=point2;
        point2=point3;
        if(point3)
        {
             point3=point3->next;
        }
    }
    return point1;
}
struct ListNode* middleNode(struct ListNode* head)
{
    struct ListNode* fastpoint,*slowpoint;
    fastpoint=head;
    slowpoint=head;
    while(fastpoint&&fastpoint->next)
    {
        fastpoint=fastpoint->next->next;
        slowpoint=slowpoint->next;     
    }
    return slowpoint;
}
public:
    bool chkPalindrome(ListNode* A) {
         struct ListNode* cur=A;
      struct ListNode* ret=reverseList(middleNode(A));
      while(cur&&ret)
      {
        if(cur->val!=ret->val)
        {
        return false;
        }
        cur=cur->next;
        ret=ret->next;
      }
      return true;
    }
};

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode *cura=headA,*curb=headB;
    int lena=0,lenb=0;
    while(cura->next)
    {
        lena++;
        cura=cura->next;
    }
    while(curb->next)
    {
        lenb++;
        curb=curb->next;
    }
    if(cura!=curb)
    {
        return NULL;
    }
    struct ListNode * longlist=headA;
    struct ListNode * shortlist=headB;
    if(lena<lenb)
    {
        longlist=headB;
        shortlist=headA;
    }
    int gap=abs(lena-lenb);
    while(gap--)
    {
        longlist=longlist->next;
    }
    while(longlist!=shortlist)
    {
        longlist=longlist->next;
        shortlist=shortlist->next;
    }
    return longlist ;
}

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) {
    struct ListNode * slowpoint=head,*fastpoint=head;
    while(fastpoint&&fastpoint->next)
    {
        slowpoint=slowpoint->next;
        fastpoint=fastpoint->next->next;
        if(slowpoint==fastpoint)
            return true;
    }
    return false;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值