龙空技术网

链表专题练习

小羊的Debug 59

前言:

此时朋友们对“头指针和头结点指针”大概比较关怀,姐妹们都想要学习一些“头指针和头结点指针”的相关知识。那么小编同时在网上汇集了一些对于“头指针和头结点指针””的相关知识,希望你们能喜欢,我们一起来学习一下吧!

在O(1)时间删除链表结点

需要考虑的有

1)删除的结点位于链表尾部

2)链表只有一个结点(删除的是头结点也是尾结点)

常规思维

直接删除这个结点本身

创新思维

可以把下一个结点的内容复制出来覆盖被删除的结点 然后把下一个结点删除

// 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该// 结点。#include <cstdio>#include "..\Utilities\List.h"void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted){    if(!pListHead || !pToBeDeleted)        return;    // 要删除的结点不是尾结点    if(pToBeDeleted->m_pNext != nullptr)    {        ListNode* pNext = pToBeDeleted->m_pNext;        pToBeDeleted->m_nValue = pNext->m_nValue;        pToBeDeleted->m_pNext = pNext->m_pNext;         delete pNext;        pNext = nullptr;    }    // 链表只有一个结点,删除头结点(也是尾结点)    else if(*pListHead == pToBeDeleted)    {        delete pToBeDeleted;        pToBeDeleted = nullptr;        *pListHead = nullptr;    }    // 链表中有多个结点,删除尾结点    else    {        ListNode* pNode = *pListHead;        while(pNode->m_pNext != pToBeDeleted)        {            pNode = pNode->m_pNext;                    }         pNode->m_pNext = nullptr;        delete pToBeDeleted;        pToBeDeleted = nullptr;    }}// ====================测试代码====================void Test(ListNode* pListHead, ListNode* pNode){    printf("The original list is: \n");    PrintList(pListHead);    printf("The node to be deleted is: \n");    PrintListNode(pNode);    DeleteNode(&pListHead, pNode);        printf("The result list is: \n");    PrintList(pListHead);}// 链表中有多个结点,删除中间的结点void Test1(){    ListNode* pNode1 = CreateListNode(1);    ListNode* pNode2 = CreateListNode(2);    ListNode* pNode3 = CreateListNode(3);    ListNode* pNode4 = CreateListNode(4);    ListNode* pNode5 = CreateListNode(5);    ConnectListNodes(pNode1, pNode2);    ConnectListNodes(pNode2, pNode3);    ConnectListNodes(pNode3, pNode4);    ConnectListNodes(pNode4, pNode5);    Test(pNode1, pNode3);    DestroyList(pNode1);}// 链表中有多个结点,删除尾结点void Test2(){    ListNode* pNode1 = CreateListNode(1);    ListNode* pNode2 = CreateListNode(2);    ListNode* pNode3 = CreateListNode(3);    ListNode* pNode4 = CreateListNode(4);    ListNode* pNode5 = CreateListNode(5);    ConnectListNodes(pNode1, pNode2);    ConnectListNodes(pNode2, pNode3);    ConnectListNodes(pNode3, pNode4);    ConnectListNodes(pNode4, pNode5);    Test(pNode1, pNode5);    DestroyList(pNode1);}// 链表中有多个结点,删除头结点void Test3(){    ListNode* pNode1 = CreateListNode(1);    ListNode* pNode2 = CreateListNode(2);    ListNode* pNode3 = CreateListNode(3);    ListNode* pNode4 = CreateListNode(4);    ListNode* pNode5 = CreateListNode(5);    ConnectListNodes(pNode1, pNode2);    ConnectListNodes(pNode2, pNode3);    ConnectListNodes(pNode3, pNode4);    ConnectListNodes(pNode4, pNode5);    Test(pNode1, pNode1);    DestroyList(pNode1);}// 链表中只有一个结点,删除头结点void Test4(){    ListNode* pNode1 = CreateListNode(1);    Test(pNode1, pNode1);}// 链表为空void Test5(){    Test(nullptr, nullptr);}int main(int argc, char* argv[]){    Test1();    Test2();    Test3();    Test4();    Test5();    return 0;}

删除重复结点

思路:确定删除函数的参数,这个函数需要输入待删除链表的头结点.头结点可能与后面的结点重复.头结点也有可能被删除

需要考虑的

1)只有几个结点是重复的

2)没有重复的

3)除了一个结点之外其他所有结点的值都相同

4)所有结点的值都相同

5)所有结点都成对出现

6)除了两个结点之外其他结点都成对出现

7)链表中只有两个不重复的结点

8)空链表

// 面试题18(二):删除链表中重复的结点// 题目:在一个排序的链表中,如何删除重复的结点?例如,在图3.4(a)中重复// 结点被删除之后,链表如图3.4(b)所示。#include <cstdio>#include "../Utilities/list.h"void DeleteDuplication(ListNode** pHead){    if(pHead == nullptr || *pHead == nullptr)        return;    ListNode* pPreNode = nullptr;    ListNode* pNode = *pHead;    while(pNode != nullptr)    {        ListNode *pNext = pNode->m_pNext;        bool needDelete = false;        if(pNext != nullptr && pNext->m_nValue == pNode->m_nValue)            needDelete = true;        if(!needDelete)        {            pPreNode = pNode;            pNode = pNode->m_pNext;        }        else        {            int value = pNode->m_nValue;            ListNode* pToBeDel = pNode;            while(pToBeDel != nullptr && pToBeDel->m_nValue == value)            {                pNext = pToBeDel->m_pNext;                delete pToBeDel;                pToBeDel = nullptr;                pToBeDel = pNext;            }            if(pPreNode == nullptr)                *pHead = pNext;            else                pPreNode->m_pNext = pNext;            pNode = pNext;        }    }}// ====================测试代码====================void Test(char* testName, ListNode** pHead, int* expectedValues, int expectedLength){    if(testName != nullptr)        printf("%s begins: ", testName);    DeleteDuplication(pHead);    int index = 0;    ListNode* pNode = *pHead;    while(pNode != nullptr && index < expectedLength)    {        if(pNode->m_nValue != expectedValues[index])            break;        pNode = pNode->m_pNext;        index++;    }    if(pNode == nullptr && index == expectedLength)        printf("Passed.\n");    else        printf("FAILED.\n");}// 某些结点是重复的void Test1(){    ListNode* pNode1 = CreateListNode(1);    ListNode* pNode2 = CreateListNode(2);    ListNode* pNode3 = CreateListNode(3);    ListNode* pNode4 = CreateListNode(3);    ListNode* pNode5 = CreateListNode(4);    ListNode* pNode6 = CreateListNode(4);    ListNode* pNode7 = CreateListNode(5);    ConnectListNodes(pNode1, pNode2);    ConnectListNodes(pNode2, pNode3);    ConnectListNodes(pNode3, pNode4);    ConnectListNodes(pNode4, pNode5);    ConnectListNodes(pNode5, pNode6);    ConnectListNodes(pNode6, pNode7);    ListNode* pHead = pNode1;    int expectedValues[] = { 1, 2, 5 };    Test("Test1", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));    DestroyList(pHead);}// 没有重复的结点void Test2(){    ListNode* pNode1 = CreateListNode(1);    ListNode* pNode2 = CreateListNode(2);    ListNode* pNode3 = CreateListNode(3);    ListNode* pNode4 = CreateListNode(4);    ListNode* pNode5 = CreateListNode(5);    ListNode* pNode6 = CreateListNode(6);    ListNode* pNode7 = CreateListNode(7);    ConnectListNodes(pNode1, pNode2);    ConnectListNodes(pNode2, pNode3);    ConnectListNodes(pNode3, pNode4);    ConnectListNodes(pNode4, pNode5);    ConnectListNodes(pNode5, pNode6);    ConnectListNodes(pNode6, pNode7);    ListNode* pHead = pNode1;    int expectedValues[] = { 1, 2, 3, 4, 5, 6, 7 };    Test("Test2", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));    DestroyList(pHead);}// 除了一个结点之外其他所有结点的值都相同void Test3(){    ListNode* pNode1 = CreateListNode(1);    ListNode* pNode2 = CreateListNode(1);    ListNode* pNode3 = CreateListNode(1);    ListNode* pNode4 = CreateListNode(1);    ListNode* pNode5 = CreateListNode(1);    ListNode* pNode6 = CreateListNode(1);    ListNode* pNode7 = CreateListNode(2);    ConnectListNodes(pNode1, pNode2);    ConnectListNodes(pNode2, pNode3);    ConnectListNodes(pNode3, pNode4);    ConnectListNodes(pNode4, pNode5);    ConnectListNodes(pNode5, pNode6);    ConnectListNodes(pNode6, pNode7);    ListNode* pHead = pNode1;    int expectedValues[] = { 2 };    Test("Test3", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));    DestroyList(pHead);}// 所有结点的值都相同void Test4(){    ListNode* pNode1 = CreateListNode(1);    ListNode* pNode2 = CreateListNode(1);    ListNode* pNode3 = CreateListNode(1);    ListNode* pNode4 = CreateListNode(1);    ListNode* pNode5 = CreateListNode(1);    ListNode* pNode6 = CreateListNode(1);    ListNode* pNode7 = CreateListNode(1);    ConnectListNodes(pNode1, pNode2);    ConnectListNodes(pNode2, pNode3);    ConnectListNodes(pNode3, pNode4);    ConnectListNodes(pNode4, pNode5);    ConnectListNodes(pNode5, pNode6);    ConnectListNodes(pNode6, pNode7);    ListNode* pHead = pNode1;    Test("Test4", &pHead, nullptr, 0);    DestroyList(pHead);}// 所有结点都成对出现void Test5(){    ListNode* pNode1 = CreateListNode(1);    ListNode* pNode2 = CreateListNode(1);    ListNode* pNode3 = CreateListNode(2);    ListNode* pNode4 = CreateListNode(2);    ListNode* pNode5 = CreateListNode(3);    ListNode* pNode6 = CreateListNode(3);    ListNode* pNode7 = CreateListNode(4);    ListNode* pNode8 = CreateListNode(4);    ConnectListNodes(pNode1, pNode2);    ConnectListNodes(pNode2, pNode3);    ConnectListNodes(pNode3, pNode4);    ConnectListNodes(pNode4, pNode5);    ConnectListNodes(pNode5, pNode6);    ConnectListNodes(pNode6, pNode7);    ConnectListNodes(pNode7, pNode8);    ListNode* pHead = pNode1;    Test("Test5", &pHead, nullptr, 0);    DestroyList(pHead);}// 除了两个结点之外其他结点都成对出现void Test6(){    ListNode* pNode1 = CreateListNode(1);    ListNode* pNode2 = CreateListNode(1);    ListNode* pNode3 = CreateListNode(2);    ListNode* pNode4 = CreateListNode(3);    ListNode* pNode5 = CreateListNode(3);    ListNode* pNode6 = CreateListNode(4);    ListNode* pNode7 = CreateListNode(5);    ListNode* pNode8 = CreateListNode(5);    ConnectListNodes(pNode1, pNode2);    ConnectListNodes(pNode2, pNode3);    ConnectListNodes(pNode3, pNode4);    ConnectListNodes(pNode4, pNode5);    ConnectListNodes(pNode5, pNode6);    ConnectListNodes(pNode6, pNode7);    ConnectListNodes(pNode7, pNode8);    ListNode* pHead = pNode1;    int expectedValues[] = { 2, 4 };    Test("Test6", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));    DestroyList(pHead);}// 链表中只有两个不重复的结点void Test7(){    ListNode* pNode1 = CreateListNode(1);    ListNode* pNode2 = CreateListNode(2);    ConnectListNodes(pNode1, pNode2);    ListNode* pHead = pNode1;    int expectedValues[] = { 1, 2 };    Test("Test7", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));    DestroyList(pHead);}// 结点中只有一个结点void Test8(){    ListNode* pNode1 = CreateListNode(1);    ConnectListNodes(pNode1, nullptr);    ListNode* pHead = pNode1;    int expectedValues[] = { 1 };    Test("Test8", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));    DestroyList(pHead);}// 结点中只有两个重复的结点void Test9(){    ListNode* pNode1 = CreateListNode(1);    ListNode* pNode2 = CreateListNode(1);    ConnectListNodes(pNode1, pNode2);    ListNode* pHead = pNode1;    Test("Test9", &pHead, nullptr, 0);    DestroyList(pHead);}// 空链表void Test10(){    ListNode* pHead = nullptr;    Test("Test10", &pHead, nullptr, 0);}int main(int argc, char* argv[]){    Test1();    Test2();    Test3();    Test4();    Test5();    Test6();    Test7();    Test8();    Test9();    Test10();    return 0;}

标签: #头指针和头结点指针