my delete function is not printing anything - c

I have this code of a red-black tree in which it has the functions mainly of insertion and deletion.
But when trying to perform the deleteNode function, it does not display anything in the output.
being that if I use only the insertion and printing on the screen, the code runs normally.
I believe that the logic is right but I'm doing some manipulation with the struct that is generating the problem.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define BLACK 0
#define RED 1
struct RBNo
{
int data;
int cor;
struct RBNo *esq;
struct RBNo *dir;
struct RBNo *pai;
};
struct RBNo *Novo_no_vermelho(int data, struct RBNo *pai){
struct RBNo *novoNO = (struct RBNo *)malloc(sizeof(struct RBNo));
novoNO->pai = pai;
novoNO->esq = novoNO->dir = NULL;
novoNO->cor = RED;
novoNO->data = data;
return novoNO;
}
struct RBNo *Novo_no_preto(int data){
struct RBNo *RBNo = (struct RBNo *)malloc(sizeof(struct RBNo));
RBNo->pai = RBNo->esq = RBNo->dir = NULL;
RBNo->cor = BLACK;
RBNo->data = data;
return RBNo;
}
int filho_esquerda(struct RBNo *raiz){
struct RBNo *pai = raiz->pai;
return (pai->esq == raiz);
}
struct RBNo *Encontrar_irmao(struct RBNo *raiz){
struct RBNo *pai = raiz->pai;
return (filho_esquerda(raiz) ? pai->dir : pai->esq);
}
void RR(struct RBNo *raiz, int mudar_cor){
struct RBNo *pai = raiz->pai;
raiz->pai = pai->pai;
if (pai->pai != NULL){
if(pai->pai->dir == pai)
pai->pai->dir = raiz;
else
pai->pai->esq = raiz;
}
struct RBNo *dir = raiz->dir;
raiz->dir = pai;
pai->pai = raiz;
pai->esq = dir;
if (dir != NULL)
dir->pai = pai;
if (mudar_cor){
raiz->cor = BLACK;
pai->cor = RED;
}
}
void LL(struct RBNo *raiz, int mudar_cor){
struct RBNo *pai = raiz->pai;
raiz->pai = pai->pai;
if (pai->pai != NULL){
if (pai->pai->dir == pai)
pai->pai->dir = raiz;
else
pai->pai->esq = raiz;
}
struct RBNo *esq = raiz->esq;
raiz->esq = pai;
pai->pai = raiz;
pai->dir = esq;
if (esq != NULL)
esq->pai = pai;
if (mudar_cor){
raiz->cor = BLACK;
pai->cor = RED;
}
}
struct RBNo *Insercao(struct RBNo *pai, struct RBNo *raiz, int data){
if (raiz == NULL){
if (pai != NULL)
return Novo_no_vermelho(data, pai);
return Novo_no_preto(data);
}
int na_esquerda;
if (raiz->data > data){
struct RBNo *esq = Insercao(raiz, raiz->esq, data);
if (esq == raiz->pai)
return esq;
raiz->esq = esq;
na_esquerda = 1;
}
else if (raiz->data < data){
struct RBNo *dir = Insercao(raiz, raiz->dir, data);
if (dir == raiz->pai)
return dir;
raiz->dir = dir;
na_esquerda = 0;
}
else
return raiz;
if (na_esquerda){
if (raiz->cor == RED && raiz->esq->cor == RED){
struct RBNo *sibling = Encontrar_irmao(raiz);
if (!sibling || sibling->cor == BLACK){
if (filho_esquerda(raiz))
RR(raiz, 1);
else{
RR(raiz->esq, 0);
raiz = raiz->pai;
LL(raiz, 1);
}
}
else{
raiz->cor = BLACK;
sibling->cor = BLACK;
if (raiz->pai->pai != NULL)
raiz->pai->cor = RED;
}
}
}
else{
if (raiz->cor == RED && raiz->dir->cor == RED){
struct RBNo *sibling = Encontrar_irmao(raiz);
if (!sibling || sibling->cor == BLACK){
if (!filho_esquerda(raiz))
LL(raiz, 1);
else{
LL(raiz->dir, 0);
raiz = raiz->pai;
RR(raiz, 1);
}
}
else{
raiz->cor = BLACK;
sibling->cor = BLACK;
if (raiz->pai->pai != NULL)
raiz->pai->cor = RED;
}
}
}
return raiz;
}
void deleteFix(struct RBNo* x, struct RBNo* node)
{
struct RBNo* s;
while (x != node && x->cor == 0){
if (x == x->pai->esq){
s = x->pai->dir;
if (s->cor == 1){
s->cor = 0;
x->pai->cor = 1;
LL(x->pai, 1);
s = x->pai->dir;
}
if (s->esq->cor == 0 && s->dir->cor == 0)
{
s->cor = 1;
x = x->pai;
}
else
{
if (s->dir->cor == 0)
{
s->esq->cor = 0;
s->cor = 1;
RR(s, 0);
s = x->pai->dir;
}
s->cor = x->pai->cor;
x->pai->cor = 0;
s->dir->cor = 0;
LL(x->pai, 0);
x = node;
}
}
else
{
s = x->pai->esq;
if (s->cor == 1)
{
s->cor = 0;
x->pai->cor = 1;
RR(x->pai, 0);
s = x->pai->esq;
}
if (s->dir->cor == 0 && s->dir->cor == 0)
{
s->cor = 1;
x = x->pai;
}
else
{
if (s->esq->cor == 0)
{
s->dir->cor = 0;
s->cor = 1;
LL(s, 0);
s = x->pai->esq;
}
s->cor = x->pai->cor;
x->pai->cor = 0;
s->esq->cor = 0;
RR(x->pai, 0);
x = node;
}
}
}
x->cor = 0;
}
struct RBNo* minimum(struct RBNo* node)
{
while (node->esq != NULL)
{
node = node->esq;
}
return node;
}
void rbTransplant(struct RBNo* raiz , struct RBNo* u, struct RBNo* v){
if (u->pai == NULL){
raiz = v;
}
else if (u == u->pai->esq)
{
u->pai->esq = v;
}
else
{
u->pai->dir = v;
}
v->pai = u->pai;
}
void deleteNode(struct RBNo* node){
struct RBNo* z = NULL;
struct RBNo* x;
struct RBNo* y;
while (node != NULL){
z = node;
node = node->esq;
}
y = z;
int y_original_cor = y->cor;
if (z->esq == NULL){
x = z->dir;
rbTransplant(node, z, z->dir);
}
else if (z->dir == NULL){
x = z->esq;
rbTransplant(node, z, z->esq);
}
else{
y = minimum(z->dir);
y_original_cor = y->cor;
x = y->dir;
if (y->pai == z){
x->pai = y;
}
else{
rbTransplant(node, y, y->dir);
y->dir = z->dir;
y->dir->pai = y;
}
rbTransplant(node, z, y);
y->esq = z->esq;
y->esq->pai = y;
y->cor = z->cor;
}
free(z);
if (y_original_cor == 0)
{
deleteFix(x, node);
}
}
void Impressao(struct RBNo *raiz, bool ultimo){
if (raiz != NULL){
printf(" ");
if (raiz->cor == 0)
printf("%d BLACK\n", raiz->data);
else
printf("%d RED\n", raiz->data);
Impressao(raiz->esq, false);
Impressao(raiz->dir, true);
}
}
int main()
{
struct RBNo *raiz = NULL;
raiz = Insercao(NULL, raiz, 41);
raiz = Insercao(NULL, raiz, 17);
raiz = Insercao(NULL, raiz, 34);
raiz = Insercao(NULL, raiz, 43);
deleteNode(raiz);
raiz = Insercao(NULL, raiz, 24);
raiz = Insercao(NULL, raiz, 25);
raiz = Insercao(NULL, raiz, 49);
raiz = Insercao(NULL, raiz, 32);
raiz = Insercao(NULL, raiz, 36);
Impressao(raiz, true);
printf("\n");
return 0;
}
That is, the only thing I need is to find out why the code does not display anything when I use the deleteNode function and what is wrong with it, because I'm almost sure that the logic is right.

Related

reverte height of AVL tree

I'm trying to implement an AVL tree for the first time, and apparently it worked, but I need to change the way of marking the height of the tree, the root node is getting the highest height, but I want to change the root node to have height 0 and go incrementing for the child nodes.
#include <stdio.h>
#include <stdlib.h>
struct NO{
int info;
int altura;
struct NO *esq;
struct NO *dir;
};
typedef struct NO* ArvAVL;
ArvAVL* cria_ArvAVL(){
ArvAVL* raiz = (ArvAVL*) malloc(sizeof(ArvAVL));
if(raiz != NULL)
*raiz = NULL;
return raiz;
}
void libera_NO(struct NO* no){
if(no == NULL)
return;
libera_NO(no->esq);
libera_NO(no->dir);
free(no);
no = NULL;
}
void libera_ArvAVL(ArvAVL* raiz){
if(raiz == NULL)
return;
libera_NO(*raiz);//libera cada nó
free(raiz);//libera a raiz
}
int altura_NO(struct NO* no){
if(no == NULL)
return -1;
else
return no->altura;
}
int fatorBalanceamento_NO(struct NO* no){
return labs(altura_NO(no->esq) - altura_NO(no->dir));
}
int maior(int x, int y){
if(x > y)
return x;
else
return y;
}
void emOrdem_ArvAVL(ArvAVL *raiz){
if(raiz == NULL)
return;
if(*raiz != NULL){
emOrdem_ArvAVL(&((*raiz)->esq));
//printf("%d\n",(*raiz)->info);
printf("%d,%d\n",(*raiz)->info,altura_NO(*raiz));
emOrdem_ArvAVL(&((*raiz)->dir));
}
}
void RotacaoLL(ArvAVL *A){
printf("RotacaoLL\n");
struct NO *B;
B = (*A)->esq;
(*A)->esq = B->dir;
B->dir = *A;
(*A)->altura = maior(altura_NO((*A)->esq),altura_NO((*A)->dir)) + 1;
B->altura = maior(altura_NO(B->esq),(*A)->altura) + 1;
*A = B;
}
void RotacaoRR(ArvAVL *A){
printf("RotacaoRR\n");
struct NO *B;
B = (*A)->dir;
(*A)->dir = B->esq;
B->esq = (*A);
(*A)->altura = maior(altura_NO((*A)->esq),altura_NO((*A)->dir)) + 1;
B->altura = maior(altura_NO(B->dir),(*A)->altura) + 1;
(*A) = B;
}
void RotacaoLR(ArvAVL *A){
RotacaoRR(&(*A)->esq);
RotacaoLL(A);
}
void RotacaoRL(ArvAVL *A){
RotacaoLL(&(*A)->dir);
RotacaoRR(A);
}
int insere_ArvAVL(ArvAVL *raiz, int valor){
int res;
if(*raiz == NULL){
struct NO *novo;
novo = (struct NO*)malloc(sizeof(struct NO));
if(novo == NULL)
return 0;
novo->info = valor;
novo->altura = 0;
novo->esq = NULL;
novo->dir = NULL;
*raiz = novo;
return 1;
}
struct NO *atual = *raiz;
if(valor < atual->info){
if((res = insere_ArvAVL(&(atual->esq), valor)) == 1){
if(fatorBalanceamento_NO(atual) >= 2){
if(valor < (*raiz)->esq->info ){
RotacaoLL(raiz);
}else{
RotacaoLR(raiz);
}
}
}
}else{
if(valor > atual->info){
if((res = insere_ArvAVL(&(atual->dir), valor)) == 1){
if(fatorBalanceamento_NO(atual) >= 2){
if((*raiz)->dir->info < valor){
RotacaoRR(raiz);
}else{
RotacaoRL(raiz);
}
}
}
}else{
printf("Valor duplicado!!\n");
return 0;
}
}
atual->altura = maior(altura_NO(atual->esq),altura_NO(atual->dir)) + 1;
return res;
}
struct NO* procuraMenor(struct NO* atual){
struct NO *no1 = atual;
struct NO *no2 = atual->esq;
while(no2 != NULL){
no1 = no2;
no2 = no2->esq;
}
return no1;
}
int remove_ArvAVL(ArvAVL *raiz, int valor){
if(*raiz == NULL){
printf("valor não existe!!\n");
return 0;
}
int res;
if(valor < (*raiz)->info){
if((res = remove_ArvAVL(&(*raiz)->esq,valor)) == 1){
if(fatorBalanceamento_NO(*raiz) >= 2){
if(altura_NO((*raiz)->dir->esq) >= altura_NO((*raiz)->dir->dir))
RotacaoRR(raiz);
else
RotacaoRL(raiz);
}
}
}
if((*raiz)->info < valor){
if((res = remove_ArvAVL(&(*raiz)->dir, valor)) == 1){
if(fatorBalanceamento_NO(*raiz) >= 2){
if(altura_NO((*raiz)->esq->dir) >= altura_NO((*raiz)->esq->esq) )
RotacaoLL(raiz);
else
RotacaoLR(raiz);
}
}
}
if((*raiz)->info == valor){
if(((*raiz)->esq == NULL || (*raiz)->dir == NULL)){
struct NO *oldNode = (*raiz);
if((*raiz)->esq != NULL)
*raiz = (*raiz)->esq;
else
*raiz = (*raiz)->dir;
free(oldNode);
}else {
struct NO* temp = procuraMenor((*raiz)->dir);
(*raiz)->info = temp->info;
remove_ArvAVL(&(*raiz)->dir, (*raiz)->info);
if(fatorBalanceamento_NO(*raiz) <= -2){
if(altura_NO((*raiz)->esq->dir) >= altura_NO((*raiz)->esq->esq))
RotacaoLL(raiz);
else
RotacaoLR(raiz);
}
}
if (*raiz != NULL)
(*raiz)->altura = maior(altura_NO((*raiz)->esq),altura_NO((*raiz)->dir)) + 1;
return 1;
}
(*raiz)->altura = maior(altura_NO((*raiz)->esq),altura_NO((*raiz)->dir)) + 1;
return res;
}
int main()
{
ArvAVL* avl;
int res,i;
int N = 7, dados[7] = {4,5,1,2,3,7,6};
avl = cria_ArvAVL();
for(i=0;i<N;i++){
res = insere_ArvAVL(avl,dados[i]);
}
printf("\nAVL tree:\n");
emOrdem_ArvAVL(avl);
printf("\n\n");
remove_ArvAVL(avl,6);
printf("\nAVL tree:\n");
emOrdem_ArvAVL(avl);
printf("\n\n");
remove_ArvAVL(avl,7);
printf("\nAVL tree:\n");
emOrdem_ArvAVL(avl);
printf("\n\n");
remove_ArvAVL(avl,4);
printf("\nAVL tree:\n");
emOrdem_ArvAVL(avl);
printf("\n\n");
libera_ArvAVL(avl);
return 0;
}
Current output
1,0
2,1
3,0
4,2
5,0
6,1
7,0
Expected output
1,2
2,1
3,2
4,0
5,2
6,1
7,2
AVL Tree
4
/ \
2 6
/ \ / \
1 3 5 7

I get a pointer with 0xCDCDCDCD problem when printing out data tree, C

I get a pointer with 0xCDCDCDCD when I want to print a tree but no problem when I want to print a queue in the almost same code
I write a queue by a c program and revise it to print as a tree , that queue was successful printed but when I tried to print the tree my visual studio told me there was a 0xCDCDCDCD problem.
this is the previous version that ran well.
#include<stdio.h>
#include<stdlib.h>
typedef struct _node
{
long long value;
//int value
struct _node *next;
}Node;
typedef struct _Queue
{
Node *head;
Node *tail;
}Queue;
Queue* init_queue()
{
Queue *queue=(Queue*)malloc(sizeof(Queue));
queue->head = queue->tail = NULL;
return queue;
}
void enQueue(Queue *pQueue,Node *pNode)
{
if(pQueue->head == NULL)
{//when it's empty
pQueue->head = pNode;
pQueue->tail = pNode;
}
else
{
pQueue->tail->next = pNode;
pQueue->tail = pNode;
}
}
int deQueue(Queue *pQueue)
{
int i;
if(pQueue->head == NULL)
{
return NULL;
}
// Node *deNode;
//Node *tmp;
//Node *deNode;
//deNode= pQueue->head;
Node *deNode= pQueue->head;
//Node *tmp= pQueue->head;
i=deNode->value;
pQueue->head= pQueue->head->next;
//free(deNode);
return i;
}
Node* init_node(int value)
{
Node *new_node = (Node*)malloc(sizeof(Node));
new_node->value=value;
return new_node;
}
//0:empty
int ifEmpty(Queue *pQueue)
{
if(pQueue->head == NULL)
{
printf("empty tree\n");
return 0;
}
printf("queue is not empty\n");
return 1;
}
int main()
{
Queue *queue=init_queue();
int i;
ifEmpty(queue);
printf("insert node to queue\n");
for(i=0; i<7;i++)
{
Node *node = init_node(i);
enQueue(queue,node);
// free(node);
}
// Node *node = init_node(1);
// printf("node->value = %d\n",node->value);
// enQueue(queue,node);
ifEmpty(queue);
for(i=0;i<7;i++)
{
int deNode = deQueue(queue);
//if(!deNode)
//{
//printf("NULL\n");
//}
//else
//{
printf("deNode->value = %d\n",deNode);
//}
}
//int deNode = deQueue(queue);
//free(queue);
// printf("\n after free deNode->value = %d\n",queue->head->value);
ifEmpty(queue);
return 0;
}
I want to change this into a tree format but my visual studio told me there was a 0xCDCDCDCD problem. below are my codecs:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define NUM 6
typedef struct _node
{
int value;
struct _node *left;
struct _node *right;
}TNode,*Tree;
//add a *next in q_node is my purpose
//other wise , we need to add in the Tree node struct
//So, for the sake of doesn't modify the struct of tree
//I design a q_node struct to include it
//we can use define command to make it as a template.
typedef struct _q_node
{
TNode *t_node;
int depth;
int blank; //0: means correspoinding tree node is not NULL(default)
struct _q_node *next;
}QNode;
typedef struct _Queue
{
QNode *head;
QNode *tail;
}Queue;
Queue* init_queue()
{
Queue *queue=(Queue*)malloc(sizeof(Queue));
queue->head = queue->tail = NULL;
return queue;
}
int enQueue(Queue *pQueue,TNode *pTNode,int pDepth)
{
QNode *pQNode = (QNode *)malloc(sizeof(QNode));
pQNode->depth = pDepth;
pQNode->blank = 0; //default config
if(pTNode==NULL)
{
//change default setting; 1 means it's blank QNode
pQNode->blank =1;
}
pQNode->t_node= pTNode;
if(pQueue->head == NULL)
{//when it's empty
pQueue->head = pQNode;
pQueue->tail = pQNode;
}
else
{
pQueue->tail->next = pQNode;
pQueue->tail = pQNode;
}
}
QNode* deQueue(Queue *pQueue)
{
if(pQueue->head == NULL)
{
return NULL;
}
QNode *deNode= pQueue->head;
pQueue->head = pQueue->head->next;
//pQueue->head = pQueue->head->next;
//deNode = deNode->next;
return deNode;
}
TNode* init_TNode(int value)
{
TNode *new_node = (TNode*)malloc(sizeof(TNode));
new_node->value=value;
new_node->left = new_node->right = NULL;
return new_node;
}
//0:empty
int ifEmpty(Queue *pQueue)
{
if(pQueue->head == NULL)
{
//printf("empty tree\n");
return 0;
}
//printf("queue is not empty\n");
return 1;
}
int insert_tree(Tree pTree,int pValue)
{
//found NULL sub tree, then add to his father->left
if(!pTree)
{
return 0;
}
TNode *tNode = init_TNode(pValue);
if(tNode==NULL)
{
printf("create TNode error!\n");
return 0;
}
if(pValue < pTree->value)
if(insert_tree(pTree->left,pValue)==0)
{
//no left child any more,set a new left child to pTree
pTree->left = tNode;
printf("insert :%d\n",pValue);
}
if(pValue > pTree->value)
if(insert_tree(pTree->right,pValue)==0)
{
pTree->right = tNode;
printf("insert :%d\n",pValue);
}
}
Tree creatTree(int num)
{
srand(time(NULL));
Tree root = init_TNode(rand()%100);
printf("root is %d\n",root->value);
int i ;
for(i=1;i<num;i++)
{
insert_tree(root,rand()%100);
}
printf("creat tree succuess!Tree heigh is:%d\n",get_tree_height(root));
return root ;
}
int get_tree_height(Tree pRoot)
{
if(!pRoot)
{
return 0;
}
int lh=0,rh=0;
lh = get_tree_height(pRoot->left);
rh = get_tree_height(pRoot->right);
return (lh<rh)?(rh+1):(lh+1);
}
int breath_travel(Tree pRoot,Queue *pQueue)
{
int height = get_tree_height(pRoot);
int pad_num = 3;
//compare to the node's depth in the "while loop"
int current_depth = 1;
if(!pRoot)
{
return 0;
}
enQueue(pQueue,pRoot,1);
printf("_______________________\n");
printf("breath begin,enter root:\n");
while(ifEmpty(pQueue)!=0)
{
QNode *qNode = deQueue(pQueue);
//the sub node's depth is 1 more then the parent's
int child_depth = qNode->depth + 1 ;
if(qNode->depth > current_depth)
{
current_depth = qNode->depth;
printf("\n\n");
}
// ***************0**************** pad_between = 31 ; pad_front = 15 (depth == 1)
// *******0***************0******** pad_between = 15 ; pad_front = 7 (depth == 2)
// ***0*******0*******0*******0**** pad_between = 7 ; pad_front = 3 (depth == 3)
// *0***0***0***0***0***0***0***0** pad_between = 3 ; pad_front = 1 (depth == 4)
// 0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0* pad_between = 1 ; pad_front = 0; (depth == 5)
// Tree height = 5
// pad_num = 1
// padding between node = (1+2*pad_front)*pad_num = (1+ (1<<(height-depth))-1)*pad_num
// (1<< (height - current_depth))-1=2^(height - current_depth)-1
int pad_front = (1<< (height - current_depth))-1;
if((qNode->blank == 1))
{
//add the parent node's padding:2
if(pad_front == 0) printf("%*s%*s",pad_num,"o",pad_num," ");
else printf("%*s%*s%*s",pad_front*pad_num," ",pad_num,"o",(1+pad_front)*pad_num," ");
//pad_front*pad_num+(1+pad_front)*pad_num=(1+2*pad_front)*pad_num=padding between node
if(child_depth <= height)
{
//enter two NULL sub-tree node.
//every time you enter NULL TNode,there's corresponding blank QNode.
enQueue(pQueue,NULL,child_depth);
enQueue(pQueue,NULL,child_depth);
}
}
else
{
if(pad_front == 0) printf("%*d%*s",pad_num,qNode->t_node->value,pad_num," ");
else printf("%*s%*d%*s",pad_front*pad_num," ",pad_num,qNode->t_node->value,(1+pad_front)*pad_num," ");
if(child_depth <=height)
{
enQueue(pQueue,qNode->t_node->left,child_depth);
enQueue(pQueue,qNode->t_node->right,child_depth);
}
}
} //while end
printf("\n-----------\nbreath end!\n-----------\n");
return 1;
}
int main(int argc,char **argv)
{
Queue *queue=init_queue();
int i;
ifEmpty(queue);
printf("insert node to queue\n");
int num = NUM; //default
if(argc == 2)
{
num = atoi(argv[1]);
}
Tree root = creatTree(num);
if(!root)
{
printf("create Tree failed!\n");
return 0;
}
breath_travel(root,queue);
return 0;
}
the problem is in the deQueue function when I want to print the tree my visual studio told me " pQueue->head= pQueue->head->next;" this line had a 0xCDCDCDCD
problem in the deQueue function I don't know why I even tried to put all this funtion in the main function but the problem was still there:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define NUM 6
typedef struct _node
{
int value;
struct _node *left;
struct _node *right;
}TNode, *Tree;
//add a *next in q_node is my purpose
//other wise , we need to add in the Tree node struct
//So, for the sake of doesn't modify the struct of tree
//I design a q_node struct to include it
//we can use define command to make it as a template.
typedef struct _q_node
{
TNode *t_node;
int depth;
int blank; //0: means correspoinding tree node is not NULL(default)
struct _q_node *next;
}QNode;
typedef struct _Queue
{
QNode *head;
QNode *tail;
}Queue;
Queue* init_queue()
{
Queue *queue = (Queue*)malloc(sizeof(Queue));
queue->head = queue->tail = NULL;
return queue;
}
int enQueue(Queue *pQueue, TNode *pTNode, int pDepth)
{
QNode *pQNode = (QNode *)malloc(sizeof(QNode));
pQNode->depth = pDepth;
pQNode->blank = 0; //default config
if (pTNode == NULL)
{
//change default setting; 1 means it's blank QNode
pQNode->blank = 1;
}
pQNode->t_node = pTNode;
if (pQueue->head == NULL)
{//when it's empty
pQueue->head = pQNode;
pQueue->tail = pQNode;
}
else
{
pQueue->tail->next = pQNode;
pQueue->tail = pQNode;
}
}
/*QNode* deQueue(Queue *pQueue)
{
if (pQueue->head == NULL)
{
return NULL;
}
QNode *deNode = pQueue->head;
pQueue->head = pQueue->head->next;
//pQueue->head = pQueue->head->next;
//deNode = deNode->next;
return deNode;
}
*/
TNode* init_TNode(int value)
{
TNode *new_node = (TNode*)malloc(sizeof(TNode));
new_node->value = value;
new_node->left = new_node->right = NULL;
return new_node;
}
//0:empty
int ifEmpty(Queue *pQueue)
{
if (pQueue->head == NULL)
{
//printf("empty tree\n");
return 0;
}
//printf("queue is not empty\n");
return 1;
}
int insert_tree(Tree pTree, int pValue)
{
//found NULL sub tree, then add to his father->left
if (!pTree)
{
return 0;
}
TNode *tNode = init_TNode(pValue);
if (tNode == NULL)
{
printf("create TNode error!\n");
return 0;
}
if (pValue < pTree->value)
if (insert_tree(pTree->left, pValue) == 0)
{
//no left child any more,set a new left child to pTree
pTree->left = tNode;
printf("insert :%d\n", pValue);
}
if (pValue > pTree->value)
if (insert_tree(pTree->right, pValue) == 0)
{
pTree->right = tNode;
printf("insert :%d\n", pValue);
}
}
Tree creatTree(int num)
{
srand((unsigned)time(NULL));
Tree root = init_TNode(rand() % 100);
printf("root is %d\n", root->value);
int i;
for (i = 1; i < num; i++)
{
insert_tree(root, rand() % 100);
}
printf("creat tree succuess!Tree heigh is:%d\n", get_tree_height(root));
return root;
}
int get_tree_height(Tree pRoot)
{
if (!pRoot)
{
return 0;
}
int lh = 0, rh = 0;
lh = get_tree_height(pRoot->left);
rh = get_tree_height(pRoot->right);
return (lh < rh) ? (rh + 1) : (lh + 1);
}
/*
int breath_travel(Tree pRoot, Queue *pQueue)
{
int height = get_tree_height(pRoot);
int pad_num = 3;
//compare to the node's depth in the "while loop"
int current_depth = 1;
if (!pRoot)
{
return 0;
}
enQueue(pQueue, pRoot, 1);
printf("_______________________\n");
printf("breath begin,enter root:\n");
while (ifEmpty(pQueue) != 0)
{
//QNode *qNode = deQueue(pQueue);
//the sub node's depth is 1 more then the parent's
if (pQueue->head == NULL)
{
return NULL;
}
QNode *qNode = pQueue->head;
pQueue->head = pQueue->head->next;
int child_depth = qNode->depth + 1;
if (qNode->depth > current_depth)
{
current_depth = qNode->depth;
printf("\n\n");
}
// ***************0**************** pad_between = 31 ; pad_front = 15 (depth == 1) 一共31个*
// *******0***************0******** pad_between = 15 ; pad_front = 7 (depth == 2)
// ***0*******0*******0*******0**** pad_between = 7 ; pad_front = 3 (depth == 3)
// *0***0***0***0***0***0***0***0** pad_between = 3 ; pad_front = 1 (depth == 4)
// 0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0* pad_between = 1 ; pad_front = 0; (depth == 5)
// Tree height = 5
// pad_num = 1
// padding between node = (1+2*pad_front)*pad_num = (1+ (1<<(height-depth))-1)*pad_num
// (1<< (height - current_depth))-1=2^(height - current_depth)-1
int pad_front = (1 << (height - current_depth)) - 1;
if ((qNode->blank == 1))
{
//add the parent node's padding:2
if (pad_front == 0) printf("%*s%*s", pad_num, "o", pad_num, " ");
else printf("%*s%*s%*s", pad_front*pad_num, " ", pad_num, "o", (1 + pad_front)*pad_num, " ");
//pad_front*pad_num+(1+pad_front)*pad_num=(1+2*pad_front)*pad_num=padding between node
if (child_depth <= height)
{
//enter two NULL sub-tree node.
//every time you enter NULL TNode,there's corresponding blank QNode.
enQueue(pQueue, NULL, child_depth);
enQueue(pQueue, NULL, child_depth);
}
}
else
{
if (pad_front == 0) printf("%*d%*s", pad_num, qNode->t_node->value, pad_num, " ");
else printf("%*s%*d%*s", pad_front*pad_num, " ", pad_num, qNode->t_node->value, (1 + pad_front)*pad_num, " ");
if (child_depth <= height)
{
enQueue(pQueue, qNode->t_node->left, child_depth);
enQueue(pQueue, qNode->t_node->right, child_depth);
}
}
} //while end
printf("\n-----------\nbreath end!\n-----------\n");
return 1;
}
*/
int main(int argc, char **argv)
{
Queue *pQueue = init_queue();
int i;
ifEmpty(pQueue);
printf("insert node to queue\n");
int num = NUM; //default
if (argc == 2)
{
num = atoi(argv[1]);
}
Tree pRoot = creatTree(num);
if (!pRoot)
{
printf("create Tree failed!\n");
return 0;
}
//breath_travel(root, queue);
int height = get_tree_height(pRoot);
int pad_num = 3;
//compare to the node's depth in the "while loop"
int current_depth = 1;
if (!pRoot)
{
return 0;
}
enQueue(pQueue, pRoot, 1);
printf("_______________________\n");
printf("breath begin,enter root:\n");
while (ifEmpty(pQueue) != 0)
{
//QNode *qNode = deQueue(pQueue);
//the sub node's depth is 1 more then the parent's
if (pQueue->head == NULL)
{
return NULL;
}
QNode *qNode = pQueue->head;
pQueue->head = pQueue->head->next;
int child_depth = qNode->depth + 1;
if (qNode->depth > current_depth)
{
current_depth = qNode->depth;
printf("\n\n");
}
// ***************0**************** pad_between = 31 ; pad_front = 15 (depth == 1)
// *******0***************0******** pad_between = 15 ; pad_front = 7 (depth == 2)
// ***0*******0*******0*******0**** pad_between = 7 ; pad_front = 3 (depth == 3)
// *0***0***0***0***0***0***0***0** pad_between = 3 ; pad_front = 1 (depth == 4)
// 0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0* pad_between = 1 ; pad_front = 0; (depth == 5)
// Tree height = 5
// pad_num = 1
// padding between node = (1+2*pad_front)*pad_num = (1+ (1<<(height-depth))-1)*pad_num
// (1<< (height - current_depth))-1=2^(height - current_depth)-1
int pad_front = (1 << (height - current_depth)) - 1;
if ((qNode->blank == 1))
{
//add the parent node's padding:2
if (pad_front == 0) printf("%*s%*s", pad_num, "o", pad_num, " ");
else printf("%*s%*s%*s", pad_front*pad_num, " ", pad_num, "o", (1 + pad_front)*pad_num, " ");
//pad_front*pad_num+(1+pad_front)*pad_num=(1+2*pad_front)*pad_num=padding between node
if (child_depth <= height)
{
//enter two NULL sub-tree node.
//every time you enter NULL TNode,there's corresponding blank QNode.
enQueue(pQueue, NULL, child_depth);
enQueue(pQueue, NULL, child_depth);
}
}
else
{
if (pad_front == 0) printf("%*d%*s", pad_num, qNode->t_node->value, pad_num, " ");
else printf("%*s%*d%*s", pad_front*pad_num, " ", pad_num, qNode->t_node->value, (1 + pad_front)*pad_num, " ");
if (child_depth <= height)
{
enQueue(pQueue, qNode->t_node->left, child_depth);
enQueue(pQueue, qNode->t_node->right, child_depth);
}
}
} //while end
printf("\n-----------\nbreath end!\n-----------\n");
return 0;
}

Red Black Tree in C

I am trying to implement red black tree in C. For reference I am using CLRS.
But when I run the code I am getting "Segmentation fault (core dumped)" error message.
I can't figure out what's wrong in my code so, could anyone tell me what's wrong in my code?
The problem seems to be in the function rb_insert_fixup(), but I don't know what's wrong in it.
Code
#include <stdio.h>
#include <stdlib.h>
//constants
#define RED 0
#define BLACK 1
struct node
{
int key;
struct node *left;
struct node *right;
struct node *parent;
int color;
};
struct node *rb_insert(struct node *tree, struct node *z);
struct node *rb_insert_fixup(struct node *tree, struct node *z);
struct node *left_rotate(struct node *t, struct node *x);
struct node *right_rotate(struct node *t, struct node *x);
struct node *create_node(int key);
int main()
{
struct node *tree = NULL;
struct node *new;
new = create_node(5);
tree = rb_insert(tree, new);
new = create_node(15);
tree = rb_insert(tree, new);
new = create_node(4);
tree = rb_insert(tree, new);
new = create_node(14);
tree = rb_insert(tree, new);
printf("inserting 14\n");
printf("%d %d\n%d %d\n", (tree->left)->key, (tree->left)->color, ((tree->right)->left)->key, ((tree->right)->left)->color);
return 0;
}
struct node *rb_insert_fixup(struct node *tree, struct node *z)
{
struct node *y = NULL;
printf("fixup \n");
while ( z->parent != NULL && (z->parent)->color == RED )
{
printf("while\n");
if ( (z->parent)->parent != NULL && printf("if condition %d\n", (((z->parent)->parent)->left)->color) && z->parent == ((z->parent)->parent)->left )
{
printf("start if\n");
y = ((z->parent)->parent)->right;
if ( y->color == RED )
{
(z->parent)->color = BLACK;
y->color = BLACK;
((z->parent)->parent)->color = RED;
z = (z->parent)->parent;
}
else if ( z == (z->parent)->right )
{
z = z->parent;
tree = left_rotate(tree, z);
}
(z->parent)->color = BLACK;
((z->parent)->parent)->color = RED;
tree = right_rotate(tree, ((z->parent)->parent));
printf("End if\n");
}
else
{
y = ((z->parent)->parent)->left;
if ( y->color == RED )
{
(z->parent)->color = BLACK;
y->color = BLACK;
((z->parent)->parent)->color = RED;
z = (z->parent)->parent;
}
else if ( z == (z->parent)->left )
{
z = z->parent;
tree = right_rotate(tree, z);
}
(z->parent)->color = BLACK;
((z->parent)->parent)->color = RED;
tree = left_rotate(tree, ((z->parent)->parent));
printf("End else\n");
}
printf("End while\n");
}
tree->color = BLACK;
return tree;
}
struct node *rb_insert(struct node *tree, struct node *z)
{
struct node *y = NULL;
struct node *x = tree;
while (x != NULL)
{
y = x;
if (z->key < x->key)
{
x = x->left;
}
else
{
x = x->right;
}
}
z->parent = y;
if (y == NULL)
{
tree = z;
}
else if (z->key < y->key)
{
y->left = z;
}
else
{
y->right = z;
}
z->left = NULL;
z->right = NULL;
z->color = RED;
tree = rb_insert_fixup(tree, z);
//printf("bye insert\n");
return tree;
}
struct node *right_rotate(struct node *t, struct node *x)
{
struct node *y = x->left;
x->left = y->right;
if (y->right != NULL)
{
(y->right)->parent = x;
}
y->parent = x->parent;
if (x->parent == NULL)
{
t = y;
}
else if (x == (x->parent)->left)
{
(x->parent)->left = y;
}
else
{
(x->parent)->right = y;
}
y->right = x;
x->parent = y;
return t;
}
struct node *left_rotate(struct node *t, struct node *x)
{
struct node *y = x->right;
x->right = y->left;
if (y->left != NULL)
{
(y->left)->parent = x;
}
y->parent = x->parent;
if (x->parent == NULL)
{
t = y;
}
else if (x == (x->parent)->left)
{
(x->parent)->left = y;
}
else
{
(x->parent)->right = y;
}
y->left = x;
x->parent = y;
return t;
}
struct node *create_node(int key)
{
struct node *new = malloc(sizeof(struct node));
if (new == NULL)
{
fprintf(stderr, "Malloc failed to create a new node\n");
exit(EXIT_FAILURE);
}
else
{
new->key = key;
new->left = NULL;
new->right = NULL;
new->parent = NULL;
new->color = BLACK;
}
}
I have written the code wrong. After writing it again from scratch (using CLRS) and including sentinal node this time, everything is fine.
The rb_delete_fixup() function is as follows. The changes are in inner if-else. Similarly we have to change the inner if-else of rb_insert_fixup. It was a blunder to not write the correct code from the pseudocode.
Node *rb_delete_fixup(Node *tree, Node *tree_nil, Node *x)
{
Node *w;
while ( x != tree && x->color == BLACK )
{
if ( x == x->parent->left )
{
w = x->parent->right;
if ( w->color == RED )
{
w->color = BLACK;
x->parent->color = RED;
tree = left_rotate(tree, tree_nil, x->parent);
w = x->parent->right;
}
if ( w->left->color == BLACK && w->right->color == BLACK )
{
w->color = RED;
x = x->parent;
}
else
{
if ( w->right->color == BLACK )
{
w->left->color = BLACK;
w->color = RED;
tree = right_rotate(tree, tree_nil, w);
w = x->parent->right;
}
w->color = x->parent->color;
x->parent->color = BLACK;
w->right->color = BLACK;
tree = left_rotate(tree, tree_nil, x->parent);
x = tree;
}
}
else
{
w = x->parent->left;
if ( w->color == RED )
{
w->color = BLACK;
x->parent->color = RED;
tree = right_rotate(tree, tree_nil, x->parent);
w = x->parent->left;
}
if ( w->left->color == BLACK && w->right->color == BLACK )
{
w->color = RED;
x = x->parent;
}
else
{
if ( w->left->color == BLACK )
{
w->right->color = BLACK;
w->color = RED;
tree = left_rotate(tree, tree_nil, w);
w = x->parent->left;
}
w->color = x->parent->color;
x->parent->color = BLACK;
w->left->color = BLACK;
tree = right_rotate(tree, tree_nil, x->parent);
x = tree;
}
}
}
x->color = BLACK;
}

Segmentation Fault in a Simple Red-Black Tree

I'm trying to build a simple red-black tree in C. Unfortunately, I have encountered a segmentation fault that I'm not sure how to fix. I've included the code below and marked to line where the fault is occurring.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define RED 1
#define BLACK 0
typedef struct RBNode {
char key[50];
int color;
struct RBNode *left;
struct RBNode *right;
struct RBNode *parent;
} RBNode;
typedef struct RBTree {
struct RBNode *root;
struct RBNode *nil;
} RBTree;
void inorderPrint(RBTree*, RBNode*);
void insertRB(RBTree*, RBNode*);
void insertRBFixup(RBTree*, RBNode*);
void leftRotate(RBTree*, RBNode*);
void rightRotate(RBTree*, RBNode*);
int count;
int main (int argc, char* argv[]) {
RBTree *tree = malloc(sizeof(RBTree));
tree->nil = malloc(sizeof(RBNode));
tree->nil->color = BLACK;
tree->root = NULL;
tree->nil->left = tree->root;
tree->nil->right = tree->root;
RBNode *curr = NULL;
curr = malloc(sizeof(RBNode));
strcpy(curr->key, "CAT");
insertRB(tree, curr);
strcpy(curr->key, "HAT");
insertRB(tree, curr);
strcpy(curr->key, "BIT");
insertRB(tree, curr);
strcpy(curr->key, "CAR");
insertRB(tree, curr);
strcpy(curr->key, "MAP");
insertRB(tree, curr);
inorderPrint(tree, tree->root);
return 1;
}
void inorderPrint(RBTree* tree, RBNode *node) {
if ((node != NULL) && (node != tree->nil)) {
inorderPrint(tree, node->left);
printf("%s\n", node->key);
inorderPrint(tree, node->right);
}
}
void leftRotate(RBTree *tree, RBNode *x) {
struct RBNode *y = NULL;
y = x->right;
x->right = y->left;
if (y->left != tree->nil) {
y->left->parent = x; //Segmentation fault occurs here
}
y->parent = x->parent;
if (x->parent == tree->nil) {
tree->root = y;
} else if (x == x->parent->left) {
x->parent->left = y;
} else {
x->parent->right = y;
}
y->left = x;
x->parent = y;
}
void rightRotate(RBTree *tree, RBNode *x) {
RBNode *y = x->left;
x->left = y->right;
if (y->right != tree->nil) {
y->right->parent = x;
}
y->parent = x->parent;
if (x->parent == tree->nil) {
tree->root = y;
} else if (x == x->parent->right) {
x->parent->right = y;
} else {
x->parent->left = y;
}
y->right = x;
x->parent = y;
}
void insertRB(RBTree *tree, RBNode *z) {
RBNode *y = tree->nil;
RBNode *x = tree->root;
while ((x != tree->nil) && (x != NULL)) {
y = x;
if (strcmp(z->key, x->key) < 0) {
x = x->left;
} else {
x = x->right;
}
}
z->parent = y;
if (y == tree->nil) {
tree->root = z;
} else if (strcmp(z->key, y->key) < 0) {
y->left = z;
} else {
y->right = z;
}
z->left = tree->nil;
z->right = tree->nil;
z->color = RED;
insertRBFixup(tree, z);
}
void insertRBFixup(RBTree *tree, RBNode *z) {
RBNode *y = NULL;
while (z->parent->color == RED) {
if (z->parent == z->parent->parent->left) {
y = z->parent->parent->right;
if (y->color == RED) {
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
} else if (z == z->parent->right) {
z = z->parent;
leftRotate(tree, z);
} else {
z->parent->color = BLACK;
z->parent->parent->color = RED;
rightRotate(tree, z->parent->parent);
}
} else {
y = z->parent->parent->left;
if (y->color == RED) {
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
} else if (z == z->parent->left) {
z = z->parent;
rightRotate(tree, z);
} else {
z->parent->color = BLACK;
z->parent->parent->color = RED;
leftRotate(tree, z->parent->parent);
}
}
}
tree->root->color = BLACK;
}
I think it might have something to do with how I initialized the red-black tree in main(), but I'm not sure and I've tried many different other ways to initialize it.
Do any of you guys know where I'm going wrong?
In
if (y->left != tree->nil) {
y->left->parent = x; //Segmentation fault occurs here
}
y->left can be NULL.
leftRotate need to check for NULL pointers

Segmentation Fault when Deleting in an AVL Tree?

I seem to be get a strange segmentation fault when I am attempting to delete in my implementation of an AVL Tree holding strings. The problem comes in the fact that I seem to only get segmentation fault when I am deleting a leaf node. Here is the code for deletion, is there anywhere that could create a problem? According to GDB the error is the function deleteBalance.
struct node{
char *word;
int balance;
struct node *children[2];
};
struct tree{
struct node *root;
int numElements;
};
struct tree *treeCreate(void){
struct tree *s = malloc(sizeof(struct tree));
s->root = NULL;
s->numElements = 0;
return s;
}
char *stringDuplicate (const char *s) {
char *d = malloc (strlen (s) + 1);
if (d == NULL) return NULL;
strcpy (d,s);
return d;
}
size_t treeSize(const struct tree *s){
return s->numElements;
}
struct node *make_node(char *word){
struct node *temp = malloc(sizeof(*temp));
if(temp != NULL){
temp->word = word;
temp->children[0] = temp->children[1] = NULL;
temp->balance = 0;
}
return temp;
}
void adjustBalance(struct node *root, int direction, int temp_bal){
struct node *temp1 = root->children[direction];
struct node *temp2 = temp1->children[!direction];
if(temp2->balance == 0){
root->balance = temp1->balance = 0;
}else if(temp2->balance == temp_bal){
root->balance = -temp_bal;
temp1->balance = 0;
}else{
root->balance = 0;
temp1->balance = temp_bal;
}
temp2->balance = 0;
}
struct node *singleRotation(struct node *root, int direction){
struct node *temp = root->children[!direction];
root->children[!direction] = temp->children[direction];
temp->children[direction] = root;
return temp;
}
struct node *doubleRotation(struct node *root, int direction){
struct node *temp = root->children[!direction]->children[direction];
root->children[!direction]->children[direction] = temp->children[!direction];
temp->children[!direction] = root->children[!direction];
root->children[!direction] = temp;
temp = root->children[!direction];
root->children[!direction] = temp->children[direction];
temp->children[direction] = root;
return temp;
}
struct node *insertBalance(struct node *root, int direction){
struct node *temp = root->children[direction];
int temp_bal;
if(direction == 0){
temp_bal = -1;
}else{
temp_bal = 1;
}
if(temp->balance == temp_bal){
root->balance = temp->balance = 0;
root = singleRotation(root, !direction);
}else{
adjustBalance(root, direction, temp_bal);
root = doubleRotation(root, !direction);
}
return root;
}
struct node *insertRecursive(struct node *root, char *word, int *done){
if(root == NULL){
root = make_node(word);
}
else{
int direction = strcmp(word, root->word);
if(direction > 0){
direction = 1;
}else if(direction < 0){
direction = 0;
}
root->children[direction] = insertRecursive(root->children[direction], word, done);
if(!*done){
if(direction == 0){
root->balance += -1;
}else{
root->balance += 1;
}
if(root->balance == 0){
*done = 1;
}else if(abs(root->balance) > 1){
root = insertBalance(root, direction);
*done = 1;
}
}
}
return root;
}
void treeInsert(struct tree *tree, const char *word){
int done = 0;
char *newWord = stringDuplicate(word);
tree->root = insertRecursive(tree->root, newWord, &done);
}
struct node *deleteBalance(struct node *root, int direction, int *done){
struct node *temp = root->children[!direction];
int temp_bal;
if(direction == 0){
temp_bal = -1;
}else{
temp_bal = 1;
}
if(temp->balance == -temp_bal){ //ERROR OCCURRING HERE
root->balance = temp->balance = 0;
root = singleRotation(root, direction);
}else if(temp->balance == temp_bal){
adjustBalance(root, !direction, -temp_bal);
root = doubleRotation(root, direction);
}else{
root->balance = -temp_bal;
temp->balance = temp_bal;
root = singleRotation(root, direction);
*done = 1;
}
return root;
}
struct node *deleteRecursion(struct node *root, char *word, int *done){
if(root != NULL){
int direction;
if(strcmp(word, root->word) == 0){
if(root->children[0] == NULL || root->children[1] == NULL){
struct node *temp;
if(root->children[0] == NULL){
direction = 1;
}else{
direction = 0;
}
temp = root->children[direction];
free(root);
return temp;
}
else{
struct node *heir = root->children[0];
while(heir->children[1] != NULL){
heir = heir->children[1];
}
root->word = heir->word;
word = heir->word;
}
}
direction = strcmp(word, root->word);
if(direction > 0){
direction = 1;
}else if(direction < 0){
direction = 0;
}
root->children[direction] = deleteRecursion(root->children[direction], word, done);
if(!*done){
if(direction == 0){
root->balance += -1;
}else{
root->balance += 1;
}
if(abs(root->balance) == 1){
*done = 1;
}else if(abs(root->balance) > 1){
root = deleteBalance(root, direction, done);
}
}
}
return root;
}
void treeDelete(struct tree *tree, const char *word){
int done = 0;
char *newWord = stringDuplicate(word);
tree->root = deleteRecursion(tree->root, newWord, &done);
}
Edit: I have added all the functions I use, both insert and delete.

Resources