数据结构-链表

来源:互联网 发布:淘宝如何投诉卖家店铺 编辑:程序博客网 时间:2024/05/18 20:32

链表

  • 链表和数组均属于线性数据结构
  • 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 0