【问题标题】:Deleting specific node(s) from Singly Linked Circular List从单链循环列表中删除特定节点
【发布时间】:2014-09-14 22:59:00
【问题描述】:

我一直在研究如何从文本文件中删除所有“A”节点,“AHHHHHAAAAHHAAHAHHAHAHAAHAAHHA”我已经能够编写删除节点函数,但它只专注于删除头,但我希望这个函数是能够读取文件并删除所有“A”并仅打印所有 H。这是我的删除节点功能

struct Node
{
    char data;
    Node* pPrev;
    Node* pNext;
};    

void deleteNode(Node * android)
{
   Node * pTemp = android->pNext;
   android->data = pTemp->data;
   android->pNext = pTemp->pNext;
   free(pTemp);
}

这是我在这里找到的另一个删除节点功能,我尝试修改,我认为它不会起作用。

void deleteNode2(Node * android)
{
   Node * pNext;
   Node * pHead;
   Node * pTail;
   Node * pTemp = android->pNext;

   if(android->pNext == 'A')
   {
       pTemp = pNext;

       if(pHead = pTail)
       {
           pHead = pTail = NULL;
       }
       else
       {
           pHead = pHead->pNext;
       }
   } 
   free(pTemp);
}

在 int main() 中

while( fscanf(pInFile, "%c", &c) != EOF)
    {
        appendNode( pTail, c);

        // display the list
        displayList( pTail->pNext);

    };

    cout << endl;
    cout << "'A' got removed from the List." << endl << endl;

    deleteNode2(pTail->pNext);
    displayList(pTail->pNext);

【问题讨论】:

    标签: c++ linked-list singly-linked-list


    【解决方案1】:

    if(android-&gt;pNext == 'A') 行会给你一个编译错误:pNext 是一个Node*,你要比较数据。将其替换为if (android-&gt;pNext.data == 'A')

    另一个问题是您在 if 条件表达式中进行赋值,而不是比较:if(pHead = pTail) 不会比较指针,而是将 pHead 分配给 pTail 并评估为 true(如输入 if 语句) 如果pTail 不为空。只需使用 == 运算符解决此问题。

    然而,您的代码中还有更多问题。如果只剩下一个元素,deleteNode 将不起作用。并且程序中没有任何内容会遍历列表以找到您要删除的所有节点。

    假设你将这个 sn-p 放在你的 main 函数中,你应该尝试这样的事情:

    Node* deleteNode(Node* android)
    {
       if (android->next == android) { // only one element
           free(android);
           return NULL;
       } else {
           Node * pTemp = android->pNext;
           android->data = pTemp->data;
           android->pNext = pTemp->pNext;
           free(pTemp);
           return android;
       }
    }
    
    size_t listSize(const Node* pNode) {
        if (!pNode) return 0;
        const Node* pStart = pNode;
        size_t n = 0;
        do {
            pNode = pNode->pNext;
            n++;
        } while (pNode != pStart);
        return n;
    }
    
    Node * pTemp = pTail;
    size_t len = listSize(pTail);
    for (unsigned int i = 0 ; i < len ; i++) {
       if (pTemp.data == 'A') {
           pTemp = deleteNode(pTemp);
       } else {
           pTemp = pTemp->next;
       }
    }
    

    这是一个比看起来更艰巨的挑战,因为我们正在处理一个循环列表。知道何时停止循环是一个问题。在这种情况下,我只是在程序开始删除它们之前计算了节点的数量。第一次遍历是安全的,因为它不会修改列表。我已经对此进行了重大更改,但如果有人发现有问题,我会很高兴知道。

    只是为了完成答案:循环链表可能是一个要求,但如果您只是阻止程序附加“A”字符,则可以使事情大大变得更容易。同样,这取决于您的最终目标是什么以及您的要求是什么。

    【讨论】:

    • 谢谢!但它只删除了 2 或 3 个“A”?有什么提示吗? @E_net4
    • 嗯,我的直觉是需要修改循环条件。在遍历结束时,起始节点甚至可能不存在。我会尽快解决这个问题。
    • 我从你那里学到了很多。非常感谢您抽出宝贵时间为我提供快速教程和编写代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多