zoukankan      html  css  js  c++  java
  • 链表

    • 实现单链表、循环链表、双向链表,支持增删操作
    • 实现单链表反转
    • 实现两个有序的链表合并为一个有序链表
    • 实现求链表的中间结点

    实现单链表、循环链表、双向链表,支持增删

    循环链表的操作和单链表基本一致,差别仅在于算法中的循环条件不是L或L->为空,而是它们是否等于头指针,因为当循环到头指针,说明链表已经完整遍历一次,下面给出代码:

    实现单链表反转

    #include<iostream>
    #include<cstdlib>
    using namespace std;

    class list{
        public:
            int data;
            class list *next;
    };
    typedef class list node;
    typedef node *link;

    link FindNode(link head,int position_data){
        link phead;
        phead = head;
        while(phead != NULL){
            if(phead->data == position_data)return phead;
            phead = phead->next;
        }
        return phead;
    }

    link InsertNode(link head,int position_data,int data){
        link phead = new node;
        phead = FindNode(head,position_data);
        link insertnode = new node;
        if(!insertnode) return NULL;
        insertnode->data = data;
        insertnode->next = NULL;
        if(phead == NULL){  //插入第一个节点
            insertnode->next = head;
            return insertnode;
        }
        else if(phead->next == NULL) phead->next = insertnode;  //插入最后一个节点
        else{  //插入中间节点
            insertnode->next = phead->next;
            phead->next = insertnode;
        }
        return head;
    }

    link DeleteNode(link head,int position_data){
        link top = head;  //保留头指针
        link phead = FindNode(head,position_data);
        if(head == phead){  //删除头结点
            head = head->next;
            delete phead;
        }
        else{
            while(top->next != phead) top = top->next;
            if(phead->next == NULL){  //删除尾结点
                top->next = NULL;
                delete phead;
            }
            else{
                top->next = phead->next;
                delete phead;
            }
        }
        return head;
    }

    link InvertList(link head){
        link pre,phead,temp;
        phead = head;  //将phead指向链表头,做游标使用
        pre = NULL;  //pre为头指针之前的节点
        while(phead != NULL){
            temp = pre;
            pre = phead;
            phead = phead->next;
            pre->next = temp;  //pre接到之前的节点
        }
        return pre;
    }

    link CreateList(int a[],int n){
        link head,phead,newnode;
        phead = new node;
        if(!phead) return NULL;
        phead->data = a[0];
        head = phead;
        for(int i = 1;i<n;i++){
            newnode = new node;
            newnode->data = a[i];
            newnode->next = NULL;
            phead->next = newnode;
            phead = phead->next;
        }
        return head;
    }

     void PrintList(link head){
        link phead = new node;
        phead = head;
        cout<<"链表元素如下: "<<endl;
        while(phead!=NULL){
            cout<<phead->data<<"->";
            head = phead;
            phead = phead->next;  //phead按序往后遍历整个链表
            if(!phead) cout<<"NULL"<<endl;
        }
    }

    int main(){
        int position_data,data;
        link head,phead;
        int n;
        cout<<"请输入初始链表元素个数: "<<endl;
        cin>>n;
        int a[n];
        cout<<"请依次输入链表元素: ";
        for(int i = 0;i<n;i++) cin>>a[i];
        head = CreateList(a,n);
        PrintList(head);
        cout<<"请输入预插入位置之前的元素和要插入的元素(例:5 8): ";
        cin>>position_data>>data;
        head = InsertNode(head,position_data,data);
        cout<<"插入之后的";
        PrintList(head);
        cout<<"请输入想删除的链表元素: ";
        cin>>position_data;
        head = DeleteNode(head,position_data);
        cout<<"删除之后的";
        PrintList(head);
        cout<<"反转之后的";
        head = InvertList(head);
        PrintList(head);
        return 0;
    }


    ————————————————
    版权声明:本文为CSDN博主「学习要有深度」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_36472818/article/details/96379507

    实现两个有序的链表合并为一个有序链表

    1. // 链表类:
    2. struct ListNode{
    3. int val;
    4. ListNode *next;
    5. ListNode (int x): val(x), next(NULL) {}
    6. };

    // 合并两个有序链表:
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2)
    {
        if (l1 == NULL)
            return l2;
        if (l2 == NULL)
            return l1;
        ListNode *pre = new ListNode(0);
        ListNode *head = pre;
        while (l1 != NULL && l2 !=NULL)
        {
            if(l1->val > l2->val)
            {
                head->next = l2;
                l2 = l2->next;            
            }
            else
            {
                head->next = l1;
                l1 = l1->next;
            }
            head = head->next;
        }
        if (l1 == NULL)
        {
            head->next = l2;
        }
        if (l2 == NULL)
        {
            head->next = l1;
        }
        return pre->next;
    }

    ListNode* mergeTwoLists(ListNode* p1, ListNode* p2)
    {
        if(p1 == NULL)
            return p2;
        else if(p2 == NULL)
            return p1;
     
        ListNode* pMergedHead = NULL;
        if(p1->val < p2->val)
        {
            pMergedHead = p1;
            pMergedHead->next = mergeTwoLists(p1->next, p2);
        }
        else
        {
            pMergedHead = p2;
            pMergedHead->next = mergeTwoLists(p1, p2->next);
        }
     
        return pMergedHead;
    }

    ListNode* mergeTwoLists(ListNode* p1, ListNode* p2)
    {
        if(p1 == NULL)
            return p2;
        else if(p2 == NULL)
            return p1;
     
        ListNode* pMergedHead = NULL;
        if(p1->val < p2->val)
        {
            pMergedHead = p1;
            pMergedHead->next = mergeTwoLists(p1->next, p2);
        }
        else
        {
            pMergedHead = p2;
            pMergedHead->next = mergeTwoLists(p1, p2->next);
        }
     
        return pMergedHead;

    }

    int main()
    {
        ListNode n1(1), n2(3), n3(5), n4(7), n5(9);
        n1.next = &n2;
        n2.next = &n3;
        n3.next = &n4;
        n4.next = &n5;
        ListNode m1(2), m2(4), m3(6), m4(8), m5(10);
        m1.next = &m2;
        m2.next = &m3;
        m3.next = &m4;
        m4.next = &m5;
        ListNode *pMergedHead = new ListNode(0);
        pMergedHead = mergeTwoLists(&n1, &m1)
        while (pMergedHead != NULL)
        {
            cout << pMergedHead ->val << endl;
            pMergedHead = pMergedHead ->next;
        }
    }

    实现求链表的中间结点

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* middleNode(ListNode* head) {
            if(head == nullptr) return head;
            int cnt = 0;
            ListNode* p = head->next;
            while(p != nullptr)
            {
                cnt++;
                p = p->next;
            }
            if(cnt % 2 == 0)
            {
                cnt = (cnt + 1) /2;
            }
            else
            {
                cnt = cnt / 2 + 1;
            }
            ListNode* q = head;
            while(cnt != 0)
            {
                q = q->next;
                cnt--;
            }
            return q;
        }
    };

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* middleNode(ListNode* head) {
           if(head == nullptr) return head;
           ListNode* p = head;
           ListNode* q = head;
           while(q != nullptr && q->next != nullptr)
           {
               p = p->next;
               q = q->next->next;
           }
           return p;

        }
    };

    与链表中环的检测一样,这题同样可以使用快慢指针来解决。

    定义两个指针fast和slow。slow一次遍历一个节点,fast一次遍历两个节点,由于fast的速度是slow的两倍,所以当fast遍历完链表时,slow所处的节点就是链表的中间节点。

     public static ListNode middleNode(ListNode head) {
            if (head == null || head.next == null) {
                return head;
            }

            ListNode slow = head;
            ListNode fast = head.next;

            while (fast != null && fast.next != null) {
                slow = slow.next;
                fast = fast.next.next;
            }

            
            return fast == null ? slow : slow.next;
        }
        
    class Solution:    
        def hasCycle(self, head):        
            slow = fast = head
            while fast and fast.next:
                slow = slow.next
                fast = fast.next.next
            return slow


  • 相关阅读:
    .Net vs Java?
    使用HyperV安装Linux系统
    C#调用Lua
    KubernetesService介绍服务发现
    缓存雪崩、缓存击穿和缓存穿透
    10 个开源项目
    minikube cncf.io
    Parallel的使用
    通过Rancher Desktop在桌面上运行K8s
    2021 .NET 开发者峰会顺利在网上落幕,线上直播回看汇总
  • 原文地址:https://www.cnblogs.com/hrnn/p/13334427.html
Copyright © 2011-2022 走看看