数据结构------单链表习题(二)

1. 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成 的。 

struct ListNode {
    int val;
    struct ListNode *next;
};
 //不使用头结点完成单链表的合并
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
    if (l1 == NULL)
        return l2;
    if (l2 == NULL)
        return l1;
    struct ListNode* NewH, *NewT;//指针 新的头和新的尾
    if (l1->val <= l2->val) {
        NewH = NewT = l1;
        l1 = l1->next;
    }
    else {
        NewH = NewT = l2;
        l2 = l2->next;
    }
    while (l1&&l2) {
        if (l1->val <= l2->val) {
            NewT->next = l1;
            l1 = l1->next;
        }
        else {
            NewT->next = l2;
            l2 = l2->next;
        }
        NewT = NewT->next;
    }
    if (l1) {
        NewT->next = l1;
    }
    if (l2) {
        NewT->next = l2;
    }
    return NewH;
}

//创建头结点完成链表的有序合并
struct ListNode {
    int val;
    struct ListNode *next;
};
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
    struct ListNode* NewH, *NewT, *tmp;
    if (l1 == NULL)
        return l2;
    if (l2 == NULL)
        return l1;
    NewH = NewT = (struct ListNode*)malloc(sizeof(struct ListNode));//头结点  不存储数据
    while (l1 &&l2) {
        if (l1->val <= l2->val) {
            NewT->next = l1;
            l1 = l1->next;
        }
        else {
            NewT->next = l2;
            l2 = l2->next;
        }
        NewT = NewT->next;
    }
    if (l1) {
        NewT->next = l1;
    }
    if (l2) {
        NewT->next = l2;
    }
    tmp = NewH;
    NewH = NewH->next;
    free(tmp);
    return NewH;
}

2. 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 。
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        struct ListNode* LH, *LT, *GH, *GT, *cur;
        if (pHead == NULL)
            return NULL;
        LH = LT = (struct ListNode*)malloc(sizeof(struct ListNode));
        GH = GT = (struct ListNode*)malloc(sizeof(struct ListNode));
        cur = pHead;
        while (cur) {
            if (cur->val < x) {
                LT->next = cur;
                LT = LT->next;
            }
            else {
                GT->next = cur;
                GT = GT->next;
            }
            cur = cur->next;
        }
        GT->next = NULL;
        //将两个链表拼接起来
        LT->next = GH->next;
        LT = LH;
        GT = GH;
        LH = LH->next;
        free(LT);
        free(GT);
        return LH;
    }
};

3. 链表的回文结构。

struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
}; 
class PalindromeList {
public:
    bool chkPalindrome(ListNode* A) {
        struct ListNode* slow, *fast, *prev, *cur, *next;
        if (A == NULL || A->next == NULL)
            return true;
        //利用快慢指针,寻找中间位置
        slow = fast = A;
        while (fast && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
        }
        //利用头插完成后半部分翻转
        prev = NULL;
        cur = slow;
        while (cur) {
            next = cur->next;
            //头插
            cur->next = prev;
            prev = cur;
            cur = next;
        }
        cur = prev;
        //比较
        while (A && cur) {
            if (A->val != cur->val) {
                return false;
            }
            A = A->next;
            cur = cur->next;
        }
        return true;
    }
};

 4. 输入两个链表,找出它们的第一个公共结点。 
 Definition for singly-linked list.
 struct ListNode {
     int val;
     struct ListNode *next;
 };
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode* curA, *curB;
    if (headA == NULL || headB == NULL)
        return NULL;
    curA = headA;
    curB = headB;
    int lenA, lenB;
    lenA = lenB = 0;
    while (curA) {
        lenA++;
        curA = curA->next;
    }
    while (curB) {
        lenB++;
        curB = curB->next;
    }
    //求绝对值
    int gap = abs(lenA - lenB);
    //假设lenA大
    curA = headA;
    curB = headB;
    if (lenA < lenB) {
        curA = headB;
        curB = headA;
    }
    while (gap--) {
        curA = curA->next;
    }
    while (curA&&curB) {
        if (curA == curB) {
            return curA;
        }
        curA = curA->next;
        curB = curB->next;
    }
    return NULL;
}

5. 给定一个链表,判断链表中是否有环。  
struct ListNode {
    int val;
    struct ListNode *next;
};
bool hasCycle(struct ListNode *head) {
    struct ListNode* slow, *fast;
    if (head == NULL)
        return false;
    slow = fast = head;
    while (fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
        if (fast == slow)
            return true;
    }
    return false;
}

6. 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 NULL  


struct ListNode {
    int val;
    struct ListNode *next;
    
};
struct ListNode* hasCycle(struct ListNode *head) {
    struct ListNode* slow, *fast;
    if (head == NULL)
        return NULL;
    slow = fast = head;
    while (fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
        if (fast == slow)
            return fast;
    }
    return NULL;
}
struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* cur;
    cur = hasCycle(head);
    if (cur) {
        while (cur->val != head->val) {
            cur = cur->next;
            head = head->next;
        }
        return cur;
    }
    return NULL;
}

struct Node {
    int val;
    struct TreeNode *next;
    struct TreeNode *random;
};
  7. 给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。 要求返回这个链表的深度拷贝。


struct Node* copyRandomList(struct Node* head) {
    struct Node* cur, *copy, *next, *newH;
    if (head == NULL)
        return NULL;
    //拷贝
    cur = head;
    while (cur) {
        next = cur->next;
        copy = (struct Node*) malloc(sizeof(struct Node));
        copy->val = cur->val;

        cur->next = copy;
        copy->next = next;

        cur = next;
    }

    //复制random
    cur = head;
    while (cur) {
        copy = cur->next;
        next = copy->next;
        if (cur->random)
            copy->random = cur->random->next;
        else
            copy->random = NULL;
        cur = next;

    }

    //拆链
    cur = head;
    newH = cur->next;
    while (cur) {
        copy = cur->next;
        next = copy->next;

        if (next)
            copy->next = next->next;
        else
            copy->next = NULL;
        cur = next;
    }
    return newH;
}

发布了42 篇原创文章 · 获赞 0 · 访问量 1441

猜你喜欢

转载自blog.csdn.net/HUAERBUSHI521/article/details/105314665