C++二叉搜索树比较节点的数据并删除重复项

C++ Binary search tree compare data of nodes and remove duplicates

本文关键字:删除 数据 搜索树 比较 节点 C++      更新时间:2023-10-16

我在 c++ 中创建了一个二叉搜索树,并加载了两种类型的数据,字符串和整数。 我正在阅读一个文本文件,并按字母顺序加载树,其中包含我正在拉动的单词,以及找到单词的行号。 我能够很好地打印单词和数字。 我现在要做的是检查一个单词是否已经被打印出来,如果有,那么我只会打印出找到该单词的行号。 我考虑这样做的方式是在遍历和打印树时比较以前的数据。 这是我的打印功能。

void inOrderPrint(Node *rootPtr ) {
    if ( rootPtr != NULL ) {
        for (int i =0; rootPtr->data[i]; i++){
            while(ispunct(rootPtr->data[i]))
                rootPtr->data.erase(i,1);
                }
        rootPtr->data = rootPtr->data.substr(0,10);
        inOrderPrint( rootPtr->left );
        cout << (rootPtr->data)<<rootPtr->lineNum <<endl;
        inOrderPrint( rootPtr->right );
    }
}

这就是我在想的:

if (rootPtr->data == previous rootPtr->data)
    cout<<setw(10)<<theCurrentNode lineNum;
else
    do normal printing

我认为,如果这个函数在第一个节点上运行,并将其与不存在的前一个节点进行比较,它会自动尝试将其与 NULL 进行比较,if 语句将返回 false,然后它将继续移动到其他节点。

关于如何使用实际的c ++语法执行此操作的任何建议? 还是有人看到我的逻辑有缺陷?

提前感谢!

这个答案将描述如何使程序打印唯一条目和文件中第一次出现的行号。如果有重复出现,它将为每个重复出现仅打印第一个匹配项的行号。方法是确保树中没有重复的节点,并计算冗余发生次数。

为此,我们可以修改节点结构,如下所示:

struct Node{
    string data;
    int lineNum;
    int count =1;
    Node* left;
    Node* right;
};

可以编辑函数 Insert 以计算重复项,如下所示:

Node* Insert(Node* rootPtr,string data,int lineNum){
if(rootPtr == NULL){
    rootPtr = GetNewNode(data,lineNum);
    for (int i =0; rootPtr->data[i]; i++){
        while(ispunct(rootPtr->data[i]))
            rootPtr->data.erase(i,1);
            }
    rootPtr->data = rootPtr->data.substr(0,10);
    return rootPtr;
}
else if(data< rootPtr->data){
    rootPtr->left = Insert(rootPtr->left,data,lineNum);
    for (int i =0; rootPtr->data[i]; i++){
        while(ispunct(rootPtr->data[i]))
            rootPtr->data.erase(i,1);
            }
    rootPtr->data = rootPtr->data.substr(0,10);
}
else if(data > rootPtr->data) {
    rootPtr->right = Insert(rootPtr->right,data,lineNum);
    for (int i =0; rootPtr->data[i]; i++){
        while(ispunct(rootPtr->data[i]))
            rootPtr->data.erase(i,1);
            }
    rootPtr->data = rootPtr->data.substr(0,10);
}
else if(data == rootPtr->data)
    ++rootPtr->count;
return rootPtr;
}

最后可以修改打印功能:

void inOrderPrint(Node *rootPtr ) {
//ofstream outputFile;
//outputFile.open("Output.txt");
if ( rootPtr != NULL ) {
    inOrderPrint( rootPtr->left );
    cout << (rootPtr->data)<<" " << rootPtr->lineNum <<endl;
    int j =rootPtr->count;
    while( --j )
    cout << rootPtr->lineNum <<endl;
    //outputFile << (rootPtr->data)<<rootPtr->lineNum <<endl;
    inOrderPrint( rootPtr->right );
}
}

现在这应该更接近您想要的。将文本处理与节点处理分开也是一个好主意。(这个答案有点假设你会照顾好这一点。否则,如果预处理的文本与处理后的文本不匹配,将创建重复节点。

祝你好运!