1

对于我的班级,我被要求编写一个红黑树程序,该程序读取现有树然后执行插入。我已经让它在树中正确读取,前几个插入正确重组,但是在大约第二个或第三个输入之后,树的顺序与教授不匹配。我已经梳理了我的代码一千次,并与来自各地的伪代码和 C++ 实现进行了比较。我根本找不到错误。

我会很感激我能在这里得到的任何帮助。我没有要求任何人为我做作业,我已经完成了所有工作,我只是得到了一个稍微不同的输出。我已经包含了测试用例输入、教授输出和我自己的输出。我还包括了所有代码。

测试用例输入文件

8
1 11
0 2
1 1
1 7
0 5
0 8
1 14
0 15
7
4
9
300
19
321
500
18

第一行是现有树中的元素数。0 为红色 1 为黑色。树之后有一个整数(在本例中为 7),表示要插入多少个元素。

教授的输出

1 7
0 2
1 1
1 5
0 4
0 11
1 8
1 14
0 15

1 7
0 2
1 1
1 5
0 4
0 11
1 8
0 9
1 14
0 15

1 7
0 2
1 1
1 5
0 4
0 11
1 8
0 9
1 15
0 14
0 300

1 7
1 2
1 1
1 5
0 4
1 11
1 8
0 9
0 15
1 14
1 300
0 19

1 7
1 2
1 1
1 5
0 4
1 11
1 8
0 9
0 15
1 14
1 300
0 19
0 321

1 7
1 2
1 1
1 5
0 4
1 15
0 11
1 8
0 9
1 14
0 300
1 19
1 321
0 500

1 7
1 2
1 1
1 5
0 4
1 15
0 11
1 8
0 9
1 14
0 300
1 19
0 18
1 321
0 500

我的输出

1 7
0 2
1 1
1 5
0 4
0 11
1 8
1 14
0 15


1 7
0 2
1 1
1 5
0 4
0 11
1 8
0 9
1 14
0 15


1 7
1 2
1 1
1 5
0 4
1 11
1 8
0 9
0 14
1 15
0 300


1 7
1 2
1 1
1 5
0 4
1 11
1 8
0 9
0 14
1 19
0 15
0 300


1 7
1 2
1 1
1 5
0 4
1 14
0 11
1 8
0 9
0 19
1 15
1 300
0 321


1 7
1 2
1 1
1 5
0 4
1 14
0 11
1 8
0 9
0 19
1 15
1 321
0 300
0 500


1 7
1 2
1 1
1 5
0 4
1 14
0 11
1 8
0 9
0 19
1 15
0 18
1 321
0 300
0 500

生成文件

run: main.o RBnode.o RBnode.h RBTree.o RBTree.h
    g++ -g3 -ggdb -O0 main.o RBnode.o RBTree.o -o RBtree

main.o: main.cpp
    g++ -c main.cpp

clean:
    rm -f RBtree *.o core core.*

tidy: clean
    rm -f *.*~ *~

RBTree.cpp

#include <fstream>
#include<iostream>
#include<cstdio>
#include"RBTree.h"
#include<cstdlib>

// Set up tree
RBtree::RBtree(){


        nil = new RBnode();
        root = nil;

}

RBtree::~RBtree(){

}

// Writes pre-order tree starting at root node to file FD
void RBtree::RBwrite(RBnode* tempRoot, FILE * fd){

        if(tempRoot != nil){

    fprintf(fd,"%d %d\n", tempRoot->colorData, tempRoot->data);

    RBwrite(tempRoot->lchild,fd);
        RBwrite(tempRoot->rchild,fd);

        }

}


// Returns root node of tree
RBnode* RBtree::getRoot(){

        return root;
}

// Insertion for a new node
RBnode* RBtree::RBinsert(int data){

        RBnode* x;
        RBnode* y;

        RBnode* z = new RBnode();
        z->data = data;


        y = this->nil;
        x = this->root;

        while(x != nil)
        {
                y = x;
                if(z->data < x->data)
                        x = x->lchild;
                else
                        x = x->rchild;
        }

        z->parent = y;
        if(y == nil)
            {    root = z;}
                //Empty Tree
        else if(z->data < y->data)
           {     y->lchild = z;}
        else
               { y->rchild = z;}
        z->lchild = nil;
        z->rchild = nil;
        z->changeColor(0);

 return z;

}





// Insertion of existing value from an existing tree
RBnode* RBtree::RBinsert(int color, int data){

        RBnode* z = new RBnode();
        z->changeColor(color);
        z->changeData(data);

        RBnode* x = root;
        RBnode* y = nil;
    while(x != nil)
    {
        y = x;
        if(z->data < x->data)
            x = x->lchild;
        else
            x = x->rchild;
    }
    z->parent = y;
    if(y == nil)
        root = z; //empty as Fword
    else if(z->data < y->data)
       { y->lchild = z;}
    else
       { y->rchild = z;}
    z->lchild = nil;
    z->rchild = nil;

return z;
}


// Fixup function. Based off algorithm from CLRS 
void RBtree::RBinstertFixup(RBnode* z){

        RBnode* y;

while(z->parent->colorData == 0 && z->parent != nil) {

        if(z->parent == z->parent->parent->lchild)
        {
                y = z->parent->parent->rchild;
                if(y->colorData == 0)
                {
                        z->parent->changeColor(1);
                        y->changeColor(1);
                        z->parent->parent->changeColor(0);
                        z = z->parent->parent;
                }
                else
                {
                        if(z == z->parent->rchild)
                        {
                                z = z->parent;
                                Lrotate(z);
                        }
                z->parent->changeColor(1);
                z->parent->parent->changeColor(0);
                Rrotate(z->parent->parent);
                }
        }
        else
        {
                y = z->parent->parent->lchild;
                if(y->colorData == 0)
                {
                        z->parent->changeColor(1);
                        y->changeColor(1);
                        z->parent->parent->changeColor(0);
                        z = z->parent->parent;
                }
                 else
                {
                        if(z == z->parent->lchild)
                        {
                                z = z->parent;
                                Rrotate(z);
                        }
                z->parent->changeColor(1);
                z->parent->parent->changeColor(0);
                Lrotate(z->parent->parent);
                }
        }
}
    root->changeColor(1);
}


// Left rotate
void RBtree::Lrotate(RBnode* x) {

        RBnode* y;

        y = x->rchild;
        x->rchild = y->lchild;
        if(y->lchild != nil)
                y->lchild->parent = x;
        y->parent = x->parent;
        if(x->parent == nil)
                root = y;
        else if(x == x->parent->lchild)
                x->parent->lchild = y;
        else
                x->parent->rchild = y;

        y->lchild = x;
        x->parent = y;
}


// right rotate
void RBtree::Rrotate(RBnode* x) {

        RBnode* y;

        y = x->lchild;
        x->lchild = y->rchild;
        if(y->rchild != nil)
                y->rchild->parent = x;
         y->parent = x->parent;
        if(x->parent == nil)
                root = y;
        else if(x == x->parent->lchild)
                x->parent->lchild = y;
        else
                x->parent->rchild = y;

            y->rchild = x;
            x->parent = y;

} 

RBnode.cpp

#include<iostream>
#include"RBnode.h"
#include<cstdlib>

using namespace std;

RBnode::RBnode(){

        int colorData = 1 ;
        parent = NULL;
        lchild = NULL;
        rchild = NULL;
        data = -1;

}
RBnode::~RBnode(){

}
// Assign a color to a node
void RBnode::changeColor(int color){
    this->colorData = color;


}
// Assign data to a node
void RBnode::changeData( int data ){
    this->data = data;
}

RBnode.h

#ifndef RBNODE_H_
#define RBNODE_H_

#include<iostream>
// create reb black node structure
class RBnode{
public:
    RBnode();
    ~RBnode();
    RBnode * parent;
    RBnode * lchild;
    RBnode * rchild;
    int colorData;
        int data;

    void changeColor(int color);
    void changeData(int data);
};



#endif 

RBTree.h

#ifndef RBTREE_H_
#define RBTREE_H_
#include<string>
#include <list>
#include<iostream>
#include"RBnode.h"

using std::string;
using std::ifstream;
using namespace std;
// prototype functions
class RBtree{
public:
    RBtree();
    ~RBtree();
    void RBwrite(RBnode* tempRoot, FILE * fd);  
    RBnode* RBinsert(int);
    RBnode* RBinsert(int color, int data);
    void RBinstertFixup(RBnode*);
    void Lrotate(RBnode* x);
    void Rrotate(RBnode* x);
    RBnode* getRoot();

private:
    RBnode* nil;
    RBnode* root;   
};

#endif 

主文件

#include "RBTree.h"
#include "RBnode.h"
#include <stdint.h>
#include <string>
#include <iostream>
#include <fstream>

using namespace std;

size_t n;
uint32_t data;
RBtree* RB;
bool tree = false;





int main(int argc, char * argv[]){
//declare file pointer
FILE * fs;
FILE * fd;

// init vars here
int n,c;
RBtree* RB = new RBtree();


if (argc < 2){
    printf("ERROR: include the name of the input file as an argument\n");
    return 0;
    }

printf("Attempting to open file %s\n", argv[1]);
char *input = argv[1];
std::ifstream inputfile;
inputfile.open(input);
if(inputfile.fail())  // Error check for file
    {
    std::cout << "The file could not be opened!\n";
    return 0;
    }else{ printf("\nFile opened succesfully!");}
    //begin aquistion of data

fs = fopen(input,"r");
fd = fopen("output.txt","w");
fscanf(fs,"%d",&n);
int color, val;
// Insert existing N number of elements
for(int i = 0; i < n; i++){

    fscanf(fs,"%d %d", &color, &val);

    RB->RBinsert(color, val);

    }

// Insert C number of elements.
fscanf(fs,"%d", &c);
int temp;
for(int i = 0; i < c; i++){

    fscanf(fs,"%d",&temp);
    if(temp != 0){
    RB->RBinstertFixup(RB->RBinsert(temp));
    RB->RBwrite(RB->getRoot(),fd);
    fprintf(fd,"\n\n");
    }


    }

// close files and print status to console
fclose(fd);
fclose(fs);
printf("\nProgram finished!");
return 0;

}
4

0 回答 0