一些特殊的未知案件中的段错误,让我疯狂

时间:2015-12-27 12:44:49

标签: c++ debugging segmentation-fault treap

我已经调试了一整天,我真的完全迷失了。救命!我在Visual Studio中本地测试了大量案例。它工作正常。但是在我们学校的在线评判系统中,有几种情况报告RE(exitcode 6),这意味着一个段故障问题。我真的不知道在这些情况下发生了什么事情,所有随机案例都在当地完美运作。我检查了可能导致段故障的可能问题列表。我只是无法解决,所以请帮忙。它真的让我疯狂。

注意: 这是一个好消息。数据结构中有更多的代码,但其余的工作正常,所以我试图拉出所有相关的代码。我确定treapNode* treap::deleteNode(valueType value)函数会触发段故障问题。如果您发现任何遗漏,请告诉我。

我很遗憾看起来这么久......对我的编码有什么建议吗?我真的很欣赏这个!

-------------------更新----------------------

好的,我会把所有代码放在这里,以方便你。顺便说一句,我无法访问类似UNIX的平台...

-------------------更新输入格式----------------

一个例子:

5         //the total number of the following operations
0 1 2     //this operation '0' means inserting '1' and '2' seperately
0 2 3     //while this means inserting '2' in x, '3' in y;
1 2 5     //skip operation '1'
2 0 1     //this operation '2' means delete the smallest number in x, and second small number in y
0 4 1

oj承诺不插入已存在的号码而不删除不存在的等级。

#include <cstdio>
#include <ctime>
#include <cstdlib>
using namespace std;

typedef unsigned long long valueType;

struct treapNode
{
    valueType value;
    int prior;
    int lChildNum;
    int rChildNum;
    treapNode* lChild;
    treapNode* rChild;
    treapNode* parent;
    treapNode(valueType value, int randPrior)
    :value(value), prior(randPrior), lChildNum(0), rChildNum(0), lChild(NULL), rChild(NULL), parent(NULL) {}
};

class treap
{
public:
    treap(valueType value);
    treapNode* searchRank(treapNode* baseNode, valueType rank);
    treapNode* insertNode(valueType value);
    void deleteRank(valueType rank);
    void printTreap(treapNode* tempRoot);
    treapNode* root;
private:
    treapNode* searchValue(valueType value);
    treapNode* lRotate(treapNode* node);
    treapNode* rRotate(treapNode* node);
};

treap::treap(valueType value)
{
    srand(time(0));
    root = new treapNode(value, rand());
}

treapNode* treap::searchRank(treapNode* baseNode, valueType rank)
{
    baseNode = root;
    int delta;
    while (1)
    {
        delta = rank-baseNode->lChildNum-1;
        if (delta==0) break;
        if (delta>0) 
        {
            baseNode=baseNode->rChild;
            rank=delta;
        }
        else baseNode=baseNode->lChild;
    }

    return baseNode;
    // int delta=rank-baseNode->lChildNum-1;
    // if (delta==0) return baseNode;
    // if (delta>0)
    // {
    //     //baseNode must have a rChild
    //     return searchRank(baseNode->rChild, delta);
    // }
    // else
    // {
    //     //baseNode must have a lChild
    //     return searchRank(baseNode->lChild, rank);
    // }
}

treapNode* treap::searchValue(valueType value)
{
    treapNode* travNode = root;
    while (1)
    {
        if (value>travNode->value)
        {
            if (travNode->rChild==NULL) break;
            travNode=travNode->rChild;
        }
        if (value<travNode->value)
        {
            if (travNode->lChild==NULL) break;
            travNode=travNode->lChild;
        }
    }

    return travNode;
}

void treap::deleteRank(valueType rank)
{
    treapNode* deleteRankPointer = searchRank(root, rank);
    treapNode* tempNodePointer=deleteRankPointer;
    while(1)
    {
        if (tempNodePointer->lChild!=NULL || tempNodePointer->rChild!=NULL)
        {
            if (tempNodePointer->lChild!=NULL && (tempNodePointer->rChild==NULL || tempNodePointer->lChild->prior>tempNodePointer->rChild->prior)) rRotate(tempNodePointer);
            else lRotate(tempNodePointer);
        }
        else
        {
            if (tempNodePointer->parent->value>tempNodePointer->value)
            {
                tempNodePointer=tempNodePointer->parent;
                tempNodePointer->lChild=NULL;
                tempNodePointer->lChildNum=0;
                deleteRankPointer->parent=NULL;
                delete deleteRankPointer;
            }
            else
            {
                tempNodePointer=tempNodePointer->parent;
                tempNodePointer->rChild=NULL;
                tempNodePointer->rChildNum=0;
                deleteRankPointer->parent=NULL;
                delete deleteRankPointer;
            }
            break;
        }
    }
    treapNode* travNode=tempNodePointer;
    while (travNode!=root)
    {
        if (travNode->parent->value>travNode->value) travNode->parent->lChildNum--;
        else travNode->parent->rChildNum--;
        travNode=travNode->parent;
    }
}

treapNode* treap::insertNode(valueType value)
{
    treapNode* tempNodePointer = searchValue(value);
    if (tempNodePointer->value>value) 
    {
        //tempNodePointer->lChildNum++;
        tempNodePointer->lChild=new treapNode(value, rand());
        tempNodePointer->lChild->parent=tempNodePointer;
        tempNodePointer=tempNodePointer->lChild;
    }
    else 
    {
        //tempNodePointer->rChildNum++;
        tempNodePointer->rChild=new treapNode(value, rand());
        tempNodePointer->rChild->parent=tempNodePointer;
        tempNodePointer=tempNodePointer->rChild;
    }
    treapNode* travNode = tempNodePointer;
    //update by prior first
    while (travNode!=root)
    {
        if (travNode->prior<=travNode->parent->prior) break;
        if (travNode->parent->value>travNode->value) rRotate(travNode->parent);
        else lRotate(travNode->parent);
    }
    //update the childNum of upper nodes
    while (travNode!=root)
    {
        if (travNode->parent->value>travNode->value) travNode->parent->lChildNum++;
        else travNode->parent->rChildNum++;
        travNode=travNode->parent;
    }

    return tempNodePointer;
}

treapNode* treap::lRotate(treapNode* node)
{
    //node has a rChild

    if (node!=root)
    {
        //node has a parent
        if (node->parent->value>node->value) node->parent->lChild=node->rChild;
        else node->parent->rChild=node->rChild;
        node->rChild->parent=node->parent;
    }
    else
    {
        root=root->rChild;
        root->parent=NULL;
        //no need to update childNum
    }
    treapNode* tempNodePointer = node->rChild;
    if (node->rChild->lChild!=NULL)
    {
        node->rChild=node->rChild->lChild;
        node->rChildNum=tempNodePointer->lChildNum;
        node->rChild->parent=node;
    }
    else 
    {
        node->rChild=NULL;
        node->rChildNum=0;
    }
    tempNodePointer->lChild=node;
    node->parent=tempNodePointer;
    tempNodePointer->lChildNum=node->lChildNum+node->rChildNum+1;

    return tempNodePointer;
}

treapNode* treap::rRotate(treapNode* node)
{
    //node has a lChild

    if (node!=root)
    {
        //node has a parent
        if (node->parent->value>node->value) node->parent->lChild=node->lChild;
        else node->parent->rChild=node->lChild;
        node->lChild->parent=node->parent;
    }
    else
    {
        root=root->lChild;
        root->parent=NULL;
        //no need to update childNum
    }
    treapNode* tempNodePointer = node->lChild;
    if (node->lChild->rChild!=NULL)
    {
        node->lChild=node->lChild->rChild;
        node->lChildNum=tempNodePointer->rChildNum;
        node->lChild->parent=node;
    }
    else 
    {
        node->lChild=NULL;
        node->lChildNum=0;
    }
    tempNodePointer->rChild=node;
    node->parent=tempNodePointer;
    tempNodePointer->rChildNum=node->lChildNum+node->rChildNum+1;

    return tempNodePointer;
}

void treap::printTreap(treapNode* tempRoot)
{
    if (tempRoot->lChild!=NULL) printTreap(tempRoot->lChild);
    printf("%lld: %d; lN: %d; rN: %d; lC: %lld; rC: %lld\n", tempRoot->value, tempRoot->prior, tempRoot->lChildNum, tempRoot->rChildNum, tempRoot->lChild==NULL?0:tempRoot->lChild->value, tempRoot->rChild==NULL?0:tempRoot->rChild->value);
    if (tempRoot->rChild!=NULL) printTreap(tempRoot->rChild);
}

int main()
{
    int n;
    scanf("%d", &n);

    int op;
    valueType inputX, inputY;
    int result=0;

    scanf("%d %lld %lld", &op, &inputX, &inputY);

    treap* xTreap=new treap(inputX);
    treap* yTreap=new treap(inputY);

    int Count=1;
    for (int i=1; i<n; i++) 
    {
        scanf("%d %lld %lld", &op, &inputX, &inputY);
        switch (op)
        {
            case 0:
                xTreap->insertNode(inputX);
                yTreap->insertNode(inputY);
                Count++;
                break;
            case 1:
                break;
            case 2:
                xTreap->deleteRank(inputX+1);
                yTreap->deleteRank(inputY+1);
                Count--;
                break;
            default:
                break;
        }
    }

    return 0;
}

0 个答案:

没有答案