zoukankan      html  css  js  c++  java
  • 题目:给定单向链表的头指针和一个结点指针,定义一个函数在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");
    
    }


     

  • 相关阅读:
    嵌套使用Using Statement造成对象被dispose多次 CA2202
    ASP.NET 4.0: 请求验证模式变化导致ValidateRequest=false失效
    IIS 7.0的集成模式和经典模式
    设计模式之—简单工厂设计模式
    c#总结(一)
    数据库分离附加工具
    深入理解C#之 参数传递 ref out params
    ASP.NET MVC 学习笔记(一)
    C#实现根据IP 查找真实地址
    c# 新特性
  • 原文地址:https://www.cnblogs.com/byfei/p/3112174.html
Copyright © 2011-2022 走看看