• 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。


    删除结点的操作我们经常碰到,比如一个链表A->B->C->D->E->F->G。如果我们要删除结点E,那么我们只需要让结点D的指针指向结点F即可,但是我们现在只给出链表头结点的指针以及结点E的指针,而又是单项链表,不能在O(1)时间内得到被删除结点前面的那一个结点的指针,所以我们原先的方法是不能在O(1)时间内删除结点E的。

    那么既然我们不能获得被删除结点的前一个结点的指针,我们就需要转变思路来考虑是否能够用过被删除结点后一个结点的指针来解决方法。因此被删除结点E的后一个结点指针是很容易得到的,也就是E->m_pNext。

    那么我们可能会想到如下方法:获得F的指针,将F的数据赋值给E,然后让E指向F的下一个结点。这里虽然删除的是结点F,但是相当于删除的是结点E。并且是O(1)时间复杂度。下面给出代码实例:

    #include<iostream>
    #include<stdlib.h>
    #include<stack>
    using namespace std;
    
    //链表结构
    struct ListNode
    {
        int m_nValue;
        ListNode* m_pNext;
    };
    
    //创建一个链表结点
    ListNode* CreateListNode(int value)
    {
        ListNode *pNode=new ListNode();
        pNode->m_nValue=value;
        pNode->m_pNext=NULL;
        return pNode;
    
    }
    
    
    //遍历链表中的所有结点
    void PrintList(ListNode* pHead)
    {
        ListNode *pNode=pHead;
        while(pNode!=NULL)
        {
            cout<<pNode->m_nValue<<" ";
            pNode=pNode->m_pNext;
        }
        cout<<endl;
    }
    
    void ConnectListNode(ListNode* pCurrent,ListNode* pNext)//连接两个结点
    {
        if(pCurrent==NULL)
        {
            cout<<"前一个结点不能为空"<<endl;
            exit(1);
        }
        else
        {
            pCurrent->m_pNext=pNext;
        }
    }
    
    void DeleteNode(ListNode** pListHead,ListNode* pToBeDeleted)
    {
        if(pToBeDeleted->m_pNext!=NULL)//如果要删除结点后面还有结点
        {
            ListNode* pNext=pToBeDeleted->m_pNext;
            pToBeDeleted->m_nValue=pNext->m_nValue;
            pToBeDeleted->m_pNext=pNext->m_pNext;
            delete pNext;
            pNext=NULL;
        }
        else if(*pListHead==pToBeDeleted)//如果链表只有一个结点
        {
            delete pToBeDeleted;
            pToBeDeleted=NULL;
            *pListHead=NULL;
        }
        else//如果链表有多个结点,且删除最后一个结点,那么只能遍历链表
        {
            ListNode *pNode=*pListHead;
            while(pNode->m_pNext!=pToBeDeleted)
                pNode=pNode->m_pNext;
            pNode->m_pNext=NULL;
            delete pToBeDeleted;
            pToBeDeleted=NULL;
        }
    }
    
    void main()
    {
        //创建结点
        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);//创建一个结点
        //连接结点
        ConnectListNode(pNode1,pNode2);//连接两个结点
        ConnectListNode(pNode2,pNode3);//连接两个结点
        ConnectListNode(pNode3,pNode4);//连接两个结点
        ConnectListNode(pNode4,pNode5);//连接两个结点
        ConnectListNode(pNode5,pNode6);//连接两个结点
        ConnectListNode(pNode6,pNode7);//连接两个结点
        //打印链表
        PrintList(pNode1);//打印
        //删除结点
        DeleteNode(&pNode1,pNode3);
        //打印链表
        PrintList(pNode1);//打印
    
        system("pause");
    
    }


     

  • 相关阅读:
    程序人生2008年(49)
    多种方式实现字符串/无符号数反向输出_栈_递归_头尾指针
    Ebusiness suite system service management ( EBS服务管理)
    文件系统FatFsR0.09a翻译(三):ff.h
    cocurrent request,program,process 并发请求,程序,进程的概念
    Laravel 5.* 执行seeder命令出现错误的解决方法
    Laravel修改配置后一定要清理缓存 "php artisan config:clear"!
    laravel构造函数和中间件执行顺序问题
    Laravel5.3使用学习笔记中间件
    laravel 是怎么做到运行 composer dumpautoload 不清空 classmap 映射关系的呢?
  • 原文地址:https://www.cnblogs.com/byfei/p/3112174.html
Copyright © 2020-2023  润新知