数据结构-链表

14 篇文章 0 订阅
9 篇文章 0 订阅

链表

  • 链表和数组均属于线性数据结构
  • STL
    • List(双端链表)
    • forward_list(单链表)
    • vector(动态数组)
/**
struct ListNode{
    int val;
    ListNode *next;
    ListNode(int x):val(x),next=NULL{}
}; 
**/

基本操作

删除结点

删除除去尾结点以外的指定结点
void DeleteNode(ListNode* node){
    node->val=node->next->val;
    node->next=node->next->next;
}
删除具有相同元素的结点,返回删除后的链表
ListNode *deleteNodes(ListNode *head, int val){
    ListNode *newh=new ListNode(0);
    newh->next=head;
    ListNode *newL=newh;
    while(newh && newh->next){
        if(newh->next->val==x)
        newh=newh->next->next;
        else newh=newh->next;
    }
    return newL->next;
}
删除链表中的倒数第N个结点
ListNode *removeNthNode(ListNode *head, int N){
    ListNode *fast=head;
    ListNode *slow=head;
    while(N--)
        fast=fast->next;
    //删除结点为头结点情况
    if (fast==NULL) return head->next;
    while(fast->next){
        slow=slow->next;
        fast=fast->next;
    }
    slow->next=slow->next->next;
    return head;
}
删除排序链表的重复元素I
ListNode *removeDuplicate(ListNode *head){
    ListNode *cur=head;
    ListNode *tail=head;
    while(tail){
        if(cur->val!=tail->val){
            cur->next=tail;
            cur=cur->next;
            tail=cur;
        }
        else{
            tail=tail->next;
            cur->next=NULL;
        }
    }
    return head;
}
删除排序链表中的重复元素II
ListNode *removeDuplicateII(ListNode *head){
    ListNode *new_head=NULL;
    ListNode *tail=NULL,pre=NULL,*curr=head;
    while(curr){
        ListNode *next=curr->next;
        if((!pre || pre->val!=curr->val) &&
           (!next|| next->val!=cur->val){
             if(!new_head) new_head=tail=curr;
             else {
                tail->next=curr;
                tail=curr;
             }
             tail->next=NULL;
         }
         pre=curr;
         curr=next;
    }
    return new_head;
}

翻转链表

翻转单链表-迭代
ListNode *reverseList(ListNode* head){
        ListNode* node=new ListNode(0);
        node->next=head;
        ListNode *curr=head;
        if(head!=NULL) {
            ListNode* next=curr->next;
            while(next){
                curr->next=next->next;
                next->next=node->next;
                node->next=next;
                next=curr->next;
            }
        }
        return node->next;
}
翻转链表-递归
ListNode *reverseList(ListNode *head){
    if(!head || !head->next) return head;
    ListNode *root=reverseList(head->next);
    head->next->next=head;
    head->next=NULL;
    return root;
}
翻转链表II
ListNode *reverseListII(ListNode *head, int m, int n){
    int k=n-m;
    ListNode *node=new ListNode(0);
    node->next=head;
    ListNode *pre=node;

    while(--m) pre=pre->next;
    ListNode *cur=pre->next;
    ListNode *move=NULL;

    while(k--){
        move=cur->next;
        cur->next=move->next;
        move->next=pre->next;
        pre->next=tmp;
    }
    return node->next;
}
旋转链表
ListNode *rotatList(ListNode *head, int k){
    int len=length(head);
    if(len<=1 || k%len==0) return head;
    k=len-k%len;
    ListNode *fast=head;
    while(--k) fast=fast->next;

    ListNode *nhead=fast->next;
    fast->next=NULL;
    fast=nhead;
    while(fast->next) fast=fast->next;
    fast->next=head;
    return nhead;
}

链表排序

插入排序算法排序链表
ListNode *insertionSortList(ListNode *head){
    if(!head || !head->next) return head;
    ListNode *node=new ListNode(0);
    node->next=head;
    ListNode *pre=node;
    ListNode *cur=head;
    while(cur){
        if(cur->next && cur->next->val <cur->val){
            while(pre->next && pre->next->val<cur->next->val) 
            pre=pre->next;
            ListNode *tmp=pre->next;
            pre->next=cur->next;
            cur->next=cur->next->next;
            pre->next->next=tmp;
            pre=node;
        }
        else cur=cur->next;
    }
    return node->next;
} 
归并排序单链表
ListNode *sortList(ListNode *head){
    int len=length(head);
    if(len<=1) return head;
    ListNode dummy(0);
    dummy.next=head;

    ListNode *left,*right,*tail,*cur;
    for(int step=1;step<len;step<<=1){
        tail=&dummy;
        cur=dummy.next;
        while(cur){
            left=cur;
            right=split(left,step);
            cur=split(right,step);
            tail=merge(left,right,tail);
        }
    }
    return dummy.next;
}
int length(ListNode *head){
    int len=0;
    ListNode *p=head;
    while(p){
        len++;
        p=p->next;
    }
    return len;
}
ListNode *split(ListNode *head,int step){
    for(int i=1;head && i<step;i++)
    head = head->next;
    if(!head) return head;
    ListNode *second=head->next;
    head->next=NULL;
    return second;
}
ListNode *merge(ListNode *left,ListNode *right,ListNode *tail){
    ListNode *cur=tail;
    while(left && right){
        if(left->val < right->val){
            cur->next=left;
            left=left->next;
        }else{
            cur->next=right->next;
            right=right->next;
        }
        cur=cur->next;
    }
    cur->next=left?left:right;
    while(cur) cur=cur->next;
    return cur;
}

带环链表

带环链表I
bool hasCircle(ListNode *head){
    ListNode *p1=head;
    ListNode *p2=head;
    while(p1 && p1->next){
        p1=p1->next->next;
        p2=p2->next;
        if(p1==p2) return true;
    }
    return false;
}
带环链表II
ListNode *detectCycle(ListNode *head){
    ListNode *slow=head;
    ListNode *fast=head;
    ListNode *entry=NULL;
    while(fast && fast->next){
        fast=fast->next->next;
        slow=slow->next;
        if(slow==fast){
            entry=head;
            while(entry!=slow){
                entry=entry->next;
                slow=slow->next;
            }
            break;
        }
    }
    return entry;
}

单链表有关算法

两数之和

ListNode *TwoNum(ListNode *l1,ListNode *l2){
        ListNode *l=new ListNode(0);
        ListNode *head=l;
        int carry =0, val=0;
        while(l1 && l2){
            val=(l1->val+l2->val+carry)%10;
            carry=(l1->val+l2->val+carry)/10;
            l->next=new ListNode(val);
            l1=l1->next;
            l2=l2->next;
            l=l->next;
        }
        while(l1){
            val=(l1->val+carry)%10;
            carry=(l1->val+carry)/10;
            l->next=new ListNode(val);
            l1=l1->next;
            l=l->next;
        }
        while(l2){
            val=(l2->val+carry)%10;
            carry=(l2->val+carry)/10;
            l->next=new ListNode(val);
            l2=l2->next;
            l=l->next;
        }
        if(carry>0) l->next=new ListNode(carry);        
        return head->next;
}

链表结点的操作

合并两个有序链表
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode node(0),*p=&node;
        while(l1 && l2){
            if(l1->val >l2->val){
                p->next=l2;
                l2=l2->next;
            }else{
                p->next=l1;
                l1=l1->next;
            }
            p=p->next;
        }
        if(l1)
        p->next=l1;
        else if(l2)
        p->next=l2;
        return node.next;
    }
链表划分
    ListNode *partition(ListNode *head, int x) {
        ListNode *p=head;
        ListNode *h1=new ListNode(0);
        ListNode *h2=new ListNode(0);
        ListNode *p1=h1;
        ListNode *p2=h2;

        while(p){
            if(p->val < x){
                p1->next=p;
                p1=p1->next;
            }else{
                p2->next=p;
                p2=p2->next;
            }
            p=p->next;
        }
        p2->next=NULL;
        p1->next=h2->next;
        return h1->next;
    }
回文链表
bool isPalindrome(ListNode *head){
            if(!head || !head->next) return true;
    ListNode *fast=head->next;
    ListNode *slow=head;
    while(fast && fast->next){
        slow=slow->next;
        fast=fast->next->next;
    }
    ListNode *last=slow->next;
    while(last && last->next){
        ListNode *tmp=last->next;
        last->next=tmp->next;
        tmp->next=slow->next;
        slow->next=tmp;
    }

    last=slow->next;
    slow->next=NULL;
    ListNode *pre=head;
    while(last && pre){
        if(last->val!=pre->val) return false;
        pre=pre->next;
        last=last->next;
    }
    return true;
}
两两交换链表中的结点
    ListNode* swapPairs(ListNode* head) {
        if (head == NULL || head->next == NULL)
            return head;

        ListNode *dumb = new ListNode(0);
        dumb->next = head;

        ListNode *p1 = dumb;
        ListNode *p2 = p1->next;

        while (p2 != NULL && p2->next != NULL)
        {
            p1->next = p2->next;
            p2->next = p2->next->next;
            p1->next->next = p2;

            p1 = p2;
            p2 = p1->next;
        }

        return dumb->next;
    }
Odd Even Linked List
ListNode* oddEvenList(ListNode* head) {
    if(!head || !head->next) return head;
    ListNode *cur=head->next;
    ListNode *pre=head;
    while(cur && cur->next){
        ListNode *tmp=cur->next;
        cur->next=tmp->next;
        tmp->next=pre->next;
        pre->next=tmp;
        cur=cur->next;
        pre=pre->next;
    }
    return head;
}

两个单链表的交叉点

ListNode *intersection(ListNode *l1, ListNode *l2){
    int len1=length(l1);
    int len2=length(l2);
    ListNode *p1=l1,*p2=l2;
    int len=abs(len1-len2);
    while(len1>len2){
        len--;
        p1=p1->next; 
    }
    while(len1<len2){
        len--;
        p2=p2->next;
    }
    while(p1 && p2){
        if(p1==p2) return l1;
        p1=p1->next;
        p2=p2->next;
    }
    return NULL;
}

重排链表

    void reorderList(ListNode *head) {
        // write your code here
        if(!head || !head->next) return;
        ListNode *p1=head;
        ListNode *p2=head->next;
        while(p2 && p2->next){
            p1=p1->next;
            p2=p2->next->next;
        }

        p2=reverseList(p1->next);
        p1->next=NULL;
        p1=head;

        while(p1 && p2){
            ListNode *temp1=p1->next;
            ListNode *temp2=p2->next;
            p1->next=p2;
            p2->next=temp1;
            p1=temp1;
            p2=temp2;
        }
    }

复制带随机指针的链表

/**
 * Definition for singly-linked list with a random pointer.
 * struct RandomListNode {
 *     int label;
 *     RandomListNode *next, *random;
 *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 * };
 */
RandomListNode *copyRandomList(RandomListNode *head) {

}

Reverse Nodes in k-group

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值