常见链表题

链表遍历


相交链表

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    if (!headA || !headB)
        return nullptr;
    ListNode *pA = headA, *pB = headB;
    while (pA != pB) {
        pA = pA == nullptr ? headB : pA->next;
        pB = pB == nullptr ? headA : pB->next;
    }
    return pA;
}

环形链表

链表形成回路(环),快慢指针

// 判断是否成环
bool hasCycle(ListNode* head) {
    if (!head || !head->next) 
        return false;
    ListNode* slow = head;
    ListNode* fast = head->next;
    while (slow != fast) {
        if (!fast || !fast->next)
            return false;
        slow = slow->next;
        fast = fast->next->next;
    }
    return true;
}


// 输出环的入口节点
ListNode *detectCycle(ListNode *head) {
    ListNode *slow = head, *fast = head;
    while (fast) {
        slow = slow->next;
        if (fast->next == nullptr) {
            return nullptr;
        }
        fast = fast->next->next;
        if (fast == slow) {
            ListNode *ptr = head;
            while (ptr != slow) {
                ptr = ptr->next;
                slow = slow->next;
            }
            return ptr;
        }
    }
    return nullptr;
}

重排链表

将原链表重排至头尾头尾的形式,如图:
在这里插入图片描述

void reorderList(ListNode* head) {
    if (!head) return;
    ListNode* mid = middleNode(head);
    ListNode* l1 = head;
    ListNode* l2 = mid->next;
    mid->next = nullptr;
    l2 = reverseList(l2);
    mergeList(l1, l2);
}
// 获取中点
ListNode* middleNode(ListNode* head) {
    ListNode* slow = head;
    ListNode* fast = head;
    while (fast->next && fast->next->next) {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}
// 翻转链表
ListNode* reverseList(ListNode* head) {
    ListNode* prev = nullptr;
    ListNode* curr = head;
    while (curr) {
        ListNode* nextTemp = curr->next;
        curr->next = prev;
        prev = curr;
        curr = nextTemp;
    }
    return prev;
}
// 合并链表
void mergeList(ListNode* l1, ListNode* l2) {
    ListNode *l1_tmp, *l2_tmp;
    while (l1 && l2) {
        l1_tmp = l1->next;
        l2_tmp = l2->next;
        l1->next = l2;
        l1 = l1_tmp;
        l2->next = l1;
        l2 = l2_tmp;
    }
}

链表排序

插入排序

ListNode* insertionSortList(ListNode* head) {
    if (!head) return nullptr;
    ListNode* dummyHead = new ListNode(0, head);
    ListNode* lastSorted = head;
    ListNode* curr = head->next;
    while (curr) {
        if (lastSorted->val <= curr->val)
            lastSorted = lastSorted->next;
        else {
            ListNode *prev = dummyHead;
            while (prev->next->val <= curr->val)
                prev = prev->next;
            lastSorted->next = curr->next;
            curr->next = prev->next;
            prev->next = curr;
        }
        curr = lastSorted->next;
    }
    return dummyHead->next;
}

归并排序

ListNode* sortList(ListNode* head) {
    if (head == nullptr) {
        return head;
    }
    int length = 0;
    ListNode* node = head;
    while (node != nullptr) {
        length++;
        node = node->next;
    }
    ListNode* dummyHead = new ListNode(0, head);
    for (int subLength = 1; subLength < length; subLength <<= 1) {
        ListNode* prev = dummyHead, *curr = dummyHead->next;
        while (curr != nullptr) {
            ListNode* head1 = curr;
            for (int i = 1; i < subLength && curr->next != nullptr; i++) {
                curr = curr->next;
            }
            ListNode* head2 = curr->next;
            curr->next = nullptr;
            curr = head2;
            for (int i = 1; i < subLength && curr != nullptr && curr->next != nullptr; i++) {
                curr = curr->next;
            }
            ListNode* next = nullptr;
            if (curr != nullptr) {
                next = curr->next;
                curr->next = nullptr;
            }
            ListNode* merged = merge(head1, head2);
            prev->next = merged;
            while (prev->next != nullptr) {
                prev = prev->next;
            }
            curr = next;
        }
    }
    return dummyHead->next;
}

ListNode* merge(ListNode* head1, ListNode* head2) {
    ListNode* dummyHead = new ListNode(0);
    ListNode* temp = dummyHead, *temp1 = head1, *temp2 = head2;
    while (temp1 != nullptr && temp2 != nullptr) {
        if (temp1->val <= temp2->val) {
            temp->next = temp1;
            temp1 = temp1->next;
        } else {
            temp->next = temp2;
            temp2 = temp2->next;
        }
        temp = temp->next;
    }
    if (temp1 != nullptr) {
        temp->next = temp1;
    } else if (temp2 != nullptr) {
        temp->next = temp2;
    }
    return dummyHead->next;
}

递归写法

ListNode* sortList(ListNode* head) {
    if (!head || !head->next) 
    	return head;
    ListNode* head1 = head;
    ListNode* head2 = split(head);
    head1 = sortList(head1);
    head2 = sortList(head2);
    return merge(head1, head2);
}

ListNode* split(ListNode* head) {
    ListNode *slow = head, *fast = head->next;
    while (fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
    }
    ListNode* mid = slow->next;
    slow->next = nullptr;
    return mid;
}

ListNode* merge(ListNode* head1, ListNode* head2) {
    ListNode *dummy = new ListNode(0), *p = dummy;
    while (head1 && head2) {
        if (head1->val < head2->val) {
            p = p->next = head1;
            head1 = head1->next;
        }
        else {
            p = p->next = head2;
            head2 = head2->next;
        }
    }
    if (head1 != nullptr) p->next = head1;
    if (head2 != nullptr) p->next = head2;
    return dummy->next;
}




链表合并


合并两个有序链表

// 递归
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
    if (l1 == nullptr) return l2;
    if (l2 == nullptr)  return l1;
    if (l1->val < l2->val) {
        l1->next = mergeTwoLists(l1->next, l2);
        return l1;
    } 
    else {
        l2->next = mergeTwoLists(l1, l2->next);
        return l2;
    }
}


// 迭代
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
    ListNode* preHead = new ListNode(-1);
    ListNode* prev = preHead;
    while (l1 != nullptr && l2 != nullptr) {
        if (l1->val < l2->val) {
            prev->next = l1;
            l1 = l1->next;
        } 
        else {
            prev->next = l2;
            l2 = l2->next;
        }
        prev = prev->next;
    }
    prev->next = l1 == nullptr ? l2 : l1;
    return preHead->next;
}

合并n个有序链表

struct node{
    ListNode *p;
    int val;
    bool operator<(const node &a) const {
        return a.val < val;
    }
};
ListNode* mergeKLists(vector<ListNode*>& lists) {
    priority_queue<node> Q;
    for (auto &x : lists) {
        if (x) Q.push({x, x->val});
    }
    ListNode *head = nullptr, *now = nullptr;
    while (!Q.empty()) {
        node tmp = Q.top();
        Q.pop();
        if (!head) head = now = tmp.p;
        else {
            now->next = tmp.p;
            now = tmp.p;
        }
        if (!tmp.p->next) 
            continue;
        Q.push({tmp.p->next, tmp.p->next->val});
    }
    return head;
}




链表修改


翻转链表

// 迭代
ListNode* reverseList(ListNode* head) {
    ListNode* prev = nullptr;
    ListNode* curr = head;
    while (curr) {
        ListNode* next = curr->next;
        curr->next = prev;
        prev = curr;
        curr = next;
    }
    return prev;
}

// 递归
ListNode* reverseList(ListNode* head) {
    if (!head || !head->next)
        return head;
    ListNode* newHead = reverseList(head->next);
    head->next->next = head;
    head->next = nullptr;
    return newHead;
}

翻转k个一组链表

void myReverse(ListNode*&head, ListNode*&tail) {
    ListNode* prev = tail->next, *p = head;
    while (prev != tail) {
        ListNode* nex = p->next;
        p->next = prev;
        prev = p;
        p = nex;
    }
}
ListNode* reverseKGroup(ListNode* head, int k) {
    ListNode* hair = new ListNode(0), *pre = hair;
    hair->next = head;
    while (head) {
        ListNode* tail = pre;
        for (int i = 0; i < k; ++i) {
            tail = tail->next;
            if (!tail) 
                return hair->next;
        }
        ListNode* nex = tail->next;
        myReverse(head, tail);
        pre->next = tail;
        head->next = nex;
        pre = head;
        head = pre->next;
    }
    return hair->next;
}

删除链表倒数第k个节点

// 递归
void dfs(ListNode *p, int n, int &x) {
    if (p->next) 
        dfs(p->next, n, x);
    ++x;
    if (x == n+1)
        p->next = p->next->next;
}
ListNode* removeNthFromEnd(ListNode* head, int n) {
    ListNode *h = new ListNode(0, head);
    int x = 0;
    dfs(h, n, x);
    return h->next;
}


// 双指针
ListNode* removeNthFromEnd(ListNode* head, int n) {
    ListNode* dummy = new ListNode(0, head);
    ListNode* first = head;
    ListNode* second = dummy;
    for (int i = 0; i < n; ++i) {
        first = first->next;
    }
    while (first) {
        first = first->next;
        second = second->next;
    }
    second->next = second->next->next;
    ListNode* ans = dummy->next;
    delete dummy;
    return ans;
}

删除链表中重复的元素

在这里插入图片描述
重复的元素仅保留一个就好

ListNode* deleteDuplicates(ListNode* head) {
    if (!head) return nullptr;
    ListNode* cur = head;
    while (cur->next) {
        if (cur->val == cur->next->val)
            cur->next = cur->next->next;
        else cur = cur->next;
    }
    return head;
}

在这里插入图片描述
在这里插入图片描述
重复的元素都不能保留

 ListNode* deleteDuplicates(ListNode* head) {
    if (!head) return nullptr;
    ListNode *ret = new ListNode(-1, head) *now = ret;
    while (now->next && now->next->next) {
        if (now->next->val == now->next->next->val) {
            int num = now->next->val;
            while (now->next && now->next->val == num) 
                now->next = now->next->next;
        }
        else now = now->next;
    }
    return ret->next;
}

两两交换链表中的节点

效果图

// 递归
ListNode* swapPairs(ListNode* head) {
    if (!head) return nullptr;
    if (!head->next) return head;
    ListNode *nxt = head->next;
    head->next = swapPairs(nxt->next);
    nxt->next = head;
    return nxt;
}

// 迭代
ListNode* swapPairs(ListNode* head) {
    ListNode *ret = new ListNode(-1);
    ListNode *p = head, *last = ret;
    while (p && p->next) {
        ListNode *tmp = p->next;
        last->next = tmp;
        p->next = tmp->next;
        tmp->next = p;
        last = p;
        p = p->next;
    }
    if (!ret->next) return head;
    return ret->next;
}

旋转链表-整体右移k步

ListNode* rotateRight(ListNode* head, int k) {
    if (!k || !head) return head;
    ListNode *p = head;
    int len = 1;
    while (p && p->next) {
        p = p->next;
        ++len;
    }
    p->next = head;
    k %= len;
    for (int i = 0; i < len-k-1; ++i) {
        head = head->next;
    }
    p = head->next;
    head->next = nullptr;
    return p;
}
毕业设计,基于SpringBoot+Vue+MySQL开发的公寓报修管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本公寓报修管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此公寓报修管理系统利用当下成熟完善的Spring Boot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的MySQL数据库进行程序开发。公寓报修管理系统有管理员,住户,维修人员。管理员可以管理住户信息和维修人员信息,可以审核维修人员的请假信息,住户可以申请维修,可以对维修结果评价,维修人员负责住户提交的维修信息,也可以请假。公寓报修管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 关键词:公寓报修管理系统;Spring Boot框架;MySQL;自动化;VUE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值