C++和数据结构

单向链表相关算法题(C++)

2019-11-08  本文已影响0人  眷卿三世

根据上一篇链表创造个管理对链表的理解(https://www.jianshu.com/p/d1fdc35e7546),从而延伸出的相关算法:

1.打印两个有序链表的公共部分

/**
     * 打印两个有序链表的公共部分
     * @param head1
     * @param head2
     *
     * 思路:
     * 1:判断head1的值是否小于head2的值,则head1往下移动,否则head2往下移动。
     * 2:如果head1的值和head2的值相等,则打印这个值,然后head1与和head2都往下移动。
     * 3:如果其中一个头结点指针为null,则结束打印。
     *
     */
    void printCommonPart(IntSLLNode* head1, IntSLLNode* head2) {

        if (head1 == 0 && head2 == 0) {
            return;
        }

        while (head1 != 0 && head2 != 0) {
            if (head1->info < head2->info) {
                head1 = head1->next;
            } else if (head2->info < head1->info) {
                head2 = head2->next;
            } else {
                std::cout<<"公共部分值为:"<<head1->info<<std::endl;
                head1 = head1->next;
                head2 = head2->next;
            }
        }
    }

2、删除单链表中倒数第k个节点

/**
     * 删除单链表中倒数第k个节点
     * @param head
     * @param lastKth
     * @return
     *
     * 思路:
     * 1:k>0说明,k值超出链表范围
     * 2:k == 0说明,刚好是链表的头结点。
     * 3:k < 0说明,k - n刚好得到要删除节点的前一个节点的位置。
     *
     * 注意:因为得到负数lastKth是要删除节点的前一个,所以要先++,然后在移动指针,要不节点位置会计算错误。
     */
    IntSLLNode* removeLastKthNode(IntSLLNode* head, int lastKth) {
        if (head == 0 && lastKth < 1) {
            return head;
        }
        IntSLLNode *cur = head;
        while (cur != 0) {
            lastKth--;
            cur = cur->next;
        }

        if (lastKth == 0) {
            head = head->next;
        }

        if (lastKth < 0) {
            cur = head;
            while (++lastKth != 0) {
                cur = cur->next;
            }
            cur->next= cur->next->next;
        }
        return head;
    }

3、删除链表的中间节点

/**
     * 删除链表的中间节点
     * @param head
     * @return
     *
     * 思路:
     * 规律:链表长度每增加2,要删除的节点才往后移动一个节点。
     */
    IntSLLNode* removeMidNode(IntSLLNode* head) {
        if (head == 0 || head->next == 0) {
            return head;
        }

        if (head->next->next == 0) {
            return head->next;
        }

        IntSLLNode* pre;
        IntSLLNode* cur = head->next->next;
        while (cur->next != 0 && cur->next->next != 0) {
            pre = pre->next;
            cur = cur->next->next;
        }
        pre->next = pre->next->next;

        return head;
    }

4、单向链表反转

/**
     * 单向链表反转
     * @param head
     * @return
     * 思路:
     * 定义两个节点指针,一个指针的作用是用来操作next节点,一个指针是用来保存当前节点,使其将next节点的next更新到当前节点。
     */
    IntSLLNode* reverseList(IntSLLNode* head) {
        if (head == 0 || head->next == 0) {
            return head;
        }

        IntSLLNode* newHead = 0;
        IntSLLNode* node;
        while (head != 0) {
            node = head;
            head = head->next;

            node->next = newHead;
            newHead = node;
        }

        return head = node;
    }

3、反转部分单向链表

/**
     * 反转部分单向链表
     * @param head
     * @param from
     * @param to
     * @return
     * 
     * 思路:
     * 跟整体单向链表反转思路,一样只不过需要记住前一个的节点,因为前面有剩余的链表。
     */
    IntSLLNode* reverseListPart(IntSLLNode* head, int from , int to) {
        if (head == 0 || head->next == 0)  {
            return head;
        }
        int hStep = 1;
        IntSLLNode* originNode = head;
        IntSLLNode* pre;
        IntSLLNode* newHead = NULL;
        while (hStep != from) {
            head = head->next;
            hStep++;

            if (hStep == from - 1) {
                pre = head;
            }
        }

        IntSLLNode* node;
        IntSLLNode* newTail;
        while (hStep != (to + 1)) {
            if (hStep == from) {
                newTail = head;
            }

            node = head;
            head = head->next;

            node->next = newHead;
            newHead = node;

            hStep++;
        }

        if (head != 0) {
            pre->next = node;
            newTail->next = head;
        }

        return originNode;
    }
上一篇下一篇

猜你喜欢

热点阅读