删除链接列表中的特定节点

时间:2018-09-19 10:33:04

标签: c++ linked-list

我有这样的链接列表

struct product {
string ID;
double quantity;
product* next = NULL;
};

我想删除数量少于一个数字的所有产品。 如果删除了至少一种产品,则此函数返回true,否则返回false。这是我的代码

bool deleteProducts(product*& pHead, double quantity) {
    static int flag = 0;
    product* pTemp = pHead;
    product* prev = pHead;
    if (pTemp != NULL && pTemp->quantity <= quantity) pHead = pTemp->next;
    while (pTemp != NULL && pTemp->quantity > quantity) {
        prev = pTemp;
        pTemp = pTemp->next;
    }
    if (pTemp == NULL) return flag;
    flag = 1;
    prev->next = pTemp->next;
    deleteProducts(prev->next, quantity);
}

但是当我有一个这样的列表(仅数量)时:

7 -> 7.5 -> 2 -> 5 -> 6

然后我以数量= 10运行该函数,它返回:

7.5 -> 5

这不是事实,任何人都可以为我解释。预先感谢!

2 个答案:

答案 0 :(得分:1)

您的方法有几个问题。

  1. 您正在使用静态flag。 (请参阅其他评论以了解它为什么不好。)
  2. 您正在使用递归。 由于您使用的是静态标志,因此它会破坏递归。
  3. 您可以在迭代元素时删除它,那么运行时将是O(n)。
  4. 您可以使用双向链表来避免在循环中使用pPrev

这是我想出的正确解决方案。

#include <iostream>
#include <string>

using namespace std;

typedef struct product {
    string ID;
    double quantity;
    product* next = NULL;
} product;

product* deleteProducts(product*& pHead, double quantity) {
    product* pTemp = pHead;
    product* pPrev = pHead;

    while (pTemp != NULL) {
        if ( pTemp->quantity > quantity ){
            if ( pTemp == pHead ){
                cout << "Deleteing Current Head " <<  pTemp->quantity << endl;
                product* pTmp = pHead;
                pTemp = pTemp->next;
                pHead = pPrev = pTemp;
                delete pTmp;
            }
            else{
                cout << "Deleteing Node" <<  pTemp->quantity << endl;
                product* pNext = pTemp->next;
                delete pTemp;
                pTemp = pNext;
                pPrev->next = pTemp;
            }
        }
        else{        
            pPrev = pTemp;
            pTemp = pTemp->next;
        }
    }

    return pHead;
}

bool printProducts(product*& pHead) {
    product* pTemp = pHead;

    while (pTemp != NULL) {
        cout << pTemp->quantity << " ";
        pTemp = pTemp->next;
    }

    cout << endl;
}

int main()
{
   product* p1 = new product{"1", 7};
   product* p2 = new product{"2", 7.5};
   product* p3 = new product{"3", 2};
   product* p4 = new product{"4", 5};
   product* p5 = new product{"5", 6};

   p1->next = p2;
   p2->next = p3;
   p3->next = p4;
   p4->next = p5;

   if ( deleteProducts(p1, 10) ){
       cout << "Done" << endl;
   }

   printProducts(p1);

   return 0;
}

答案 1 :(得分:0)

您的启动状态短路列表到pHead上,将本地prev设置为pHead的地址。为什么不使用pHead ->prevnullptr

从双向链表中删除元素是具有时间兼容性O(n)运算的运算。您必须遍历列表并折叠符合条件的记录。