#include <stdio.h>
#include <stdlib.h>
typedef enum TypeTag {
ADD,
SUB,
MUL,
DIV,
ABS,
FIB,
} TypeTag;
typedef struct Node {
TypeTag type;
int value;
struct Node *left;
struct Node *right;
} Node;
#define MAXN 100
int fib[MAXN];
// function to create a new node
Node* makeFunc(TypeTag type) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->type = type;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
// fibonacci function using dynamic programming
int fibonacci(int n) {
int fib[n+1];
fib[0] = 0;
fib[1] = 1;
for(int i = 2; i <= n; i++) {
fib[i] = fib[i-1] + fib[i-2];
}
return fib[n];
}
// function to calculate the value of a node
int calc(Node* node) {
if (node->type == ADD) {
return calc(node->left) + calc(node->right);
}
else if (node->type == SUB) {
return calc(node->left) - calc(node->right);
}
else if (node->type == MUL) {
return calc(node->left) * calc(node->right);
}
else if (node->type == DIV) {
return calc(node->left) / calc(node->right);
}
else if (node->type == ABS) {
return abs(calc(node->left));
}
else if (node->type == FIB) {
return fibonacci(calc(node->left));
}
return node->value;
}
int main() {
for (int i = 0; i < MAXN; i++) {
fib[i] = -1;
}
Node *add = makeFunc(ADD);
add->left = makeFunc(10);
add->right = makeFunc(6);
Node *mul = makeFunc(MUL);
mul->left = makeFunc(5);
mul->right = makeFunc(4);
Node *sub = makeFunc(SUB);
sub->left = makeFunc(calc(add));
sub->right = makeFunc(calc(sub));
Node *fibo = makeFunc(FIB);
fibo->left = makeFunc(abs(calc(sub)));
fibo->value = fibonacci(calc(fibo->left));
printf("add : %d\n", calc(add));
printf("mul : %d\n", calc(mul));
printf("sub : %d\n", calc(sub));
printf("fibo : %d\n", calc(fibo));
printf("Hello world");
// return 0;
}
I think the problem is coming from the makeFunc function but i am not sure what else to do.I tried to print hello world to see if the problem is from my implementations but it still did not print.
I was trying to solve this problem
{
TypeTag type;
} Node;
typedef enum TypeTag {
...
}
Using this structure, please write a function that returns fibonacci sequence based on the following arithmetic operations (+, -,
*, /) and conditions. The fibonacci function should be implemented using Dynamic Programming.
main()
{
Node *add = (*makeFunc(ADD))(10, 6);
Node *mul = (*makeFunc(MUL))(5, 4);
Node *sub = (*makeFunc(SUB))(mul, add);
Node *fibo = (*makeFunc(SUB))(sub, NULL);
calc(add);
calc(mul);
calc(sub);
calc(fibo)
}
Output
add : 16
mul : 20
sub : -4
fibo : 2
You can't use makeFunc(4) to make the representation of the number 4, because 4 == ABS. You should use a separate type for nodes that represent numbers rather than functions. Then use another function to create nodes of this type.
Another problem is here:
sub->right = makeFunc(calc(sub));
You can't call calc(sub) until after you've filled in both sub->left and sub->right. I'm guessing you meant to use calc(mul).
#include <stdio.h>
#include <stdlib.h>
typedef enum TypeTag {
ADD,
SUB,
MUL,
DIV,
ABS,
FIB,
LIT
} TypeTag;
typedef struct Node {
TypeTag type;
int value;
struct Node *left;
struct Node *right;
} Node;
#define MAXN 100
int fib[MAXN];
// function to create a new node
Node* makeFunc(TypeTag type) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->type = type;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
Node* makeValue(int value) {
Node *newNode = makeFunc(LIT);
newNode->value = value;
return newNode;
}
// fibonacci function using dynamic programming
int fibonacci(int n) {
int fib[n+1];
fib[0] = 0;
fib[1] = 1;
for(int i = 2; i <= n; i++) {
fib[i] = fib[i-1] + fib[i-2];
}
return fib[n];
}
// function to calculate the value of a node
int calc(Node* node) {
if (node->type == ADD) {
return calc(node->left) + calc(node->right);
}
else if (node->type == SUB) {
return calc(node->left) - calc(node->right);
}
else if (node->type == MUL) {
return calc(node->left) * calc(node->right);
}
else if (node->type == DIV) {
return calc(node->left) / calc(node->right);
}
else if (node->type == ABS) {
return abs(calc(node->left));
}
else if (node->type == FIB) {
return fibonacci(calc(node->left));
}
else if (node->type == LIT) {
return node->value;
}
printf("Invalid node type %d\n", node->type);
exit(1);
}
int main() {
for (int i = 0; i < MAXN; i++) {
fib[i] = -1;
}
Node *add = makeFunc(ADD);
add->left = makeValue(10);
add->right = makeValue(6);
Node *mul = makeFunc(MUL);
mul->left = makeValue(5);
mul->right = makeValue(4);
Node *sub = makeFunc(SUB);
sub->left = makeValue(calc(add));
sub->right = makeValue(calc(mul));
Node *fibo = makeFunc(FIB);
fibo->left = makeValue(abs(calc(sub)));
fibo->value = fibonacci(calc(fibo->left));
printf("add : %d\n", calc(add));
printf("mul : %d\n", calc(mul));
printf("sub : %d\n", calc(sub));
printf("fibo : %d\n", calc(fibo));
printf("Hello world\n");
// return 0;
}
Related
I need to create this tree:
the tree
I need to implement a function that takes the tree's node (root), a number, and returns how many times the binary representation of the number occurs in the tree.
For example:
9(1001) occurs 4 times
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct TreeNode {
int val;
struct TreeNode* leftNode;
struct TreeNode* rightNode;
};
void strrev(char * arr, int start, int end) {
char temp;
if (start >= end) {
return;
}
temp = * (arr + start);
*(arr + start) = * (arr + end);
*(arr + end) = temp;
start++;
end--;
strrev(arr, start, end);
}
char * itoa(int number, char * arr, int base) {
int i = 0, r, negative = 0;
if (number == 0) {
arr[i] = '0';
arr[i + 1] = '\0';
return arr;
}
if (number < 0 && base == 10) {
number *= -1;
negative = 1;
}
while (number != 0) {
r = number % base;
arr[i] = (r > 9) ? (r - 10) + 'a' : r + '0';
i++;
number /= base;
}
if (negative) {
arr[i] = '-';
i++;
}
strrev(arr, 0, i - 1);
arr[i] = '\0';
return arr;
}
int count_occurrences(struct TreeNode* root, int number) {
int count = 0;
char binary[33];
itoa(number, binary, 2);
int length = strlen(binary);
struct TreeNode* current = root;
for (int i = 0; i < length; i++) {
if (binary[i] == '0') {
if (current->leftNode != NULL) {
current = current->leftNode;
} else {
return count;
}
} else {
if (current->rightNode != NULL) {
current = current->rightNode;
} else {
return count;
}
}
if (current->val == number) {
count++;
}
}
return count;
}
struct TreeNode* createNode(int value) {
struct TreeNode* newNode = malloc(sizeof(struct TreeNode));
newNode->val = value;
newNode->leftNode = NULL;
newNode->rightNode = NULL;
return newNode;
}
struct TreeNode* insertLeftNode(struct TreeNode* rootNode, int value) {
rootNode->leftNode = createNode(value);
return rootNode->leftNode;
}
struct TreeNode* insertRightNode(struct TreeNode* rootNode, int value) {
rootNode->rightNode = createNode(value);
return rootNode->rightNode;
}
int main() {
struct TreeNode* rootNode = createNode(1);
insertLeftNode(rootNode, 1);
insertRightNode(rootNode, 0);
insertLeftNode(rootNode->leftNode, 0);
insertRightNode(rootNode->leftNode, 1);
insertLeftNode(rootNode->rightNode, 0);
insertRightNode(rootNode->rightNode, 0);
insertLeftNode(rootNode->leftNode->leftNode, 0);
insertRightNode(rootNode->leftNode->leftNode, 0);
insertLeftNode(rootNode->rightNode->rightNode, 0);
insertRightNode(rootNode->rightNode->rightNode, 0);
printf("\n%d", count_occurrences(rootNode, 9));
}
I am using itoa(), but for some reasons it doesn't return nothing.
Itoa gave compiler warning so i copied it from internet.
Also I think i am not correctly creating the tree.
Problem is function bin_search. it works steady on function insert. However, it gets frozen on function search. I think if it's fine on insert, it should be fine on search, but it isn't. Here is my code...
"bst.h":
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node {
int key;
void *data;
struct Node *left, *right;
void (*destroy)(void *data);
} node;
typedef struct Tree {
node *head;
char name;
} tree;
#define key(node) node->key
#define data(node) node->data
#define left(node) node->left
#define right(node) node->right
#define destroy(node) node->destroy
#define tree_head(tree) tree->head
"functions.c":
#include "bst.h"
int bin_search(node *curr, int key, int cnt, node **found) {
cnt++; printf("cnt+\n");
if (curr == NULL) {
return -1;
} else if (curr->key == key) {
printf("curr_key = key\n"); return cnt;
}
if (curr->key < key) {
printf("curr_key < key\n");
if (curr->right == NULL) {
*found = curr;
return -(cnt + 1);
}
return bin_search(curr->right, key, cnt, found);
} else {
printf("curr_key > key\n");
if (curr->left == NULL) {
*found = curr;
return -(cnt + 1);
}
return bin_search(curr->left, key, cnt, found);
}
}
int insert(tree *root, int key, void *data, void (*destroy)(void *data)) {
if (root->head == NULL) {
node* new_node = (node *)malloc(sizeof(node));
left(new_node) = NULL; right(new_node) = NULL; destroy(new_node) = destroy; key(new_node) = key; data(new_node) = data;
tree_head(root) = new_node;
printf("created first node\n"); return 1;
}
int cnt; node **found;
if ((cnt = bin_search(root->head, key, 0, found)) < 0) {
node* new_node = (node *)malloc(sizeof(node));
left(new_node) = NULL; right(new_node) = NULL; destroy(new_node) = destroy; key(new_node) = key; data(new_node) = data;
if ((*found)->key < key) {
(*found)->right = new_node;
} else {
(*found)->left = new_node;
}
printf("created a node at %d\n", -cnt); return 1;
} else {
printf("already exists in tree"); return -1;
}
}
int search(tree *root, int key, void **data) {
if (root->head == NULL) {
printf("tree is empty\n"); return -1;
}
int cnt; node **found;
if ((cnt = bin_search(root->head, key, 0, found)) < 0) {
return -1;
} else {
if ((*found)->key < key) {
*data = (*found)->right->data;
} else {
*data = (*found)->left->data;
}
return cnt;
}
}
"main.c":
#include "bst.h"
#define MAX_NUM 8
#define MAX_LEGNTH 200
int main() {
// create a tree
tree root; root.head = NULL; root.name = 'a';
FILE *inpt = fopen("list.txt", "r"); char buffer[MAX_LEGNTH];
int count = 0;
while (fgets(buffer, MAX_LEGNTH, inpt) != NULL) {
printf("adding: %d\n", atoi(buffer)); insert(&root, atoi(buffer), buffer, NULL);
count++;
}
fclose(inpt);
int result; void **found;
result = search(&root, 2, found); printf("%d\n", result); // problem in here!!
return 0;
}
what is the problem with my 'search' function. I can't find it.
Besides the utterly non-standard use of sizeof(void), you are not providing a correct out-parameter to search. The point of the found argument is to receive the node pointer if the prospect key was discovered. This...
int cnt;
node **found; // <== LOOK HERE
if ((cnt = bin_search(root->head, key, 0, found)) < 0) {
is not the way to do that. It should be done like this:
int cnt;
node *found = NULL;
if ((cnt = bin_search(root->head, key, 0, &found)) < 0) {
// ^^^^^^
and all references to found thereafter should be through found->, not (*found)->
This mistake is made in three different places in your code. The last one is semi-broken, but still broken nonetheless.
void **found = (void *)malloc(sizeof(void));
int result = search(&root, 2, found);
printf("%d\n", result);
That should use this:
void *found = NULL;
int result = search(&root, 2, &found);
printf("%d\n", result);
Whether the rest of your code is broken I cannot say, and frankly we're not in the business of being an online-debugger. Use your local debugger tools; that's what they're for. But the items listed above are definitely a problem.
I am making a Hash Map with people's names as its key using C language. I am using separate chaining to resolve the collision.
This is my code:
#include<stdio.h>
#include<stdlib.h>
#define MinTableSize 1
#include <stdbool.h>
//Colission resolution Using linked list
struct ListNode;
typedef struct ListNode *Position;
struct HashTbl;
typedef struct HashTbl *HashTable;
typedef unsigned int Index;
Index Hash(const char *Key, int Tablesize)
{
unsigned int HashVal = 0;
while(*Key != '\0')
{
HashVal += *Key++;
}
return HashVal % Tablesize;
}
struct ListNode
{
int Element;
Position Next;
};
typedef Position List;
struct HashTbl
{
int TableSize;
List *TheLists;
};
//Function to find next prime number for the size
bool isPrime(int n)
{
if(n <= 1)
{
return false;
}
if(n <= 3)
{
return true;
}
if(n%2 == 0 || n%3 == 0)
{
return false;
}
for(int i = 5; i*i <= n; i = i + 6)
{
if(n%i == 0 || n%(i + 2) == 0)
{
return false;
}
}
return true;
}
int NextPrime(int N)
{
if(N <= 1)
{
return 2;
}
int prime = N;
bool found = false;
while(!found)
{
prime++;
if(isPrime(prime))
{
found = true;
}
}
return prime;
}
HashTable InitializeTable(int TableSize)
{
HashTable H;
int i;
if(TableSize < MinTableSize)
{
printf("Table size is too small\n");
return NULL;
}
H = malloc(sizeof(struct HashTbl));
if(H == NULL)
{
printf("Out of space\n");
return NULL;
}
H->TableSize = NextPrime(TableSize);
H->TheLists = malloc(sizeof(List) * H->TableSize);
if(H->TheLists == NULL)
{
printf("Out of space\n");
return NULL;
}
for(i = 0; i < H->TableSize; i++)
{
H->TheLists[i] = malloc(sizeof(struct ListNode));
if(H->TheLists[i] == NULL)
{
printf("Out of space\n");
return NULL;
}
else
{
H->TheLists[i]->Next = NULL;
}
}
return H;
}
//funtion to find the value
Position Find(const char *Key, HashTable H)
{
Position P;
List L;
L = H->TheLists[Hash(Key, H->TableSize)];
P = L->Next;
while(P != NULL && P->Element != Key)
{
P = P->Next;
}
return P;
}
void Insert(const char *Key, HashTable H)
{
Position Pos;
Position NewCell;
List L;
Pos = Find(Key, H);
if(Pos == NULL)
{
NewCell = malloc(sizeof(struct ListNode));
if(NewCell == NULL)
{
printf("Out of space\n");
return NULL;
}
else
{
L = H->TheLists[Hash(Key, H->TableSize)];
NewCell->Next;
NewCell->Element = Key;
L->Next = NewCell;
printf("Key inserted\n");
}
}
else
{
printf("Key already exist\n");
}
}
int main()
{
char Name[6][20] = {"Joshua", "Erica", "Elizabeth", "Monica", "Jefferson", "Andrian"};
int Size = sizeof(Name[0])/sizeof(Name[0][0]);
HashTable H = InitializeTable(Size);
Insert(Name[0], H);
Insert(Name[1], H);
Insert(Name[2], H);
Insert(Name[3], H);
}
The putout of this code is:
Key inserted
Key inserted
This means, it only successfully inserted two keys, while the other name has not been inserted. I think there's some error in my Insert() function, but I got no clue. I tried using an online compiler and it compile properly.
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;
}
stack. I've got a binary tree of type TYPE (TYPE is a typedef of data*) that can add and remove elements. However for some reason certain values added will overwrite previous elements. Here's my code with examples of it inserting without overwriting elements and it not overwriting elements.
the data I'm storing:
struct data {
int number;
char *name;
};
typedef struct data data;
# ifndef TYPE
# define TYPE data*
# define TYPE_SIZE sizeof(data*)
# endif
The tree struct:
struct Node {
TYPE val;
struct Node *left;
struct Node *rght;
};
struct BSTree {
struct Node *root;
int cnt;
};
The comparator for the data.
int compare(TYPE left, TYPE right) {
int left_len; int right_len; int shortest_string;
/* find longest string */
left_len = strlen(left->name);
right_len = strlen(right->name);
if(right_len < left_len) { shortest_string = right_len; } else { shortest_string = left_len; }
/* compare strings */
if(strncmp(left->name, right->name, shortest_string) > 1) {
return 1;
}
else if(strncmp(left->name, right->name, shortest_string) < 1) {
return -1;
}
else {
/* strings are equal */
if(left->number > right->number) {
return 1;
}
else if(left->number < right->number) {
return -1;
}
else {
return 0;
}
}
}
And the add method
struct Node* _addNode(struct Node* cur, TYPE val) {
if(cur == NULL) {
/* no root has been made */
cur = _createNode(val);
return cur;
}
else {
int cmp;
cmp = compare(cur->val, val);
if(cmp == -1) {
/* go left */
if(cur->left == NULL) {
printf("adding on left node val %d\n", cur->val->number);
cur->left = _createNode(val);
}
else {
return _addNode(cur->left, val);
}
}
else if(cmp >= 0) {
/* go right */
if(cur->rght == NULL) {
printf("adding on right node val %d\n", cur->val->number);
cur->rght = _createNode(val);
}
else {
return _addNode(cur->rght, val);
}
}
return cur;
}
}
void addBSTree(struct BSTree *tree, TYPE val)
{
tree->root = _addNode(tree->root, val);
tree->cnt++;
}
The method to create a new node:
struct Node* _createNode(TYPE val) {
struct Node* new_node;
new_node = (struct Node*)malloc(sizeof(struct Node*));
new_node->val = val;
new_node->left = NULL;
new_node->rght = NULL;
return new_node;
}
The function to print the tree:
void printTree(struct Node *cur) {
if (cur == 0) {
printf("\n");
}
else {
printf("(");
printTree(cur->left);
printf(" %s, %d ", cur->val->name, cur->val->number);
printTree(cur->rght);
printf(")\n");
}
}
Here's an example of some data that will overwrite previous elements:
struct BSTree myTree;
struct data myData1, myData2, myData3;
myData1.number = 5;
myData1.name = "rooty";
myData2.number = 1;
myData2.name = "lefty";
myData3.number = 10;
myData3.name = "righty";
initBSTree(&myTree);
addBSTree(&myTree, &myData1);
addBSTree(&myTree, &myData2);
addBSTree(&myTree, &myData3);
printTree(myTree.root);
Which will print:
((
righty, 10
)
lefty, 1
)
Finally here's some test data that will go in the exact same spot as the previous data, but this time no data is overwritten:
struct BSTree myTree;
struct data myData1, myData2, myData3;
myData1.number = 5;
myData1.name = "i";
myData2.number = 5;
myData2.name = "h";
myData3.number = 5;
myData3.name = "j";
initBSTree(&myTree);
addBSTree(&myTree, &myData1);
addBSTree(&myTree, &myData2);
addBSTree(&myTree, &myData3);
printTree(myTree.root);
Which prints:
((
j, 5
)
i, 5 (
h, 5
)
)
Does anyone know what might be going wrong? Sorry if this post was kind of long.
it looks like there is an error in your _addNode procedure. It looks like you arent properly storing the new node references in the tree.
struct Node* _addNode(struct Node* cur, TYPE val) {
if(cur == NULL) {
/* no root has been made */
cur = _createNode(val);
return cur;
}
else {
int cmp;
cmp = compare(cur->val, val);
if(cmp == -1) {
/* go left */
cur->left = _addNode(cur->left, val);
}
else if(cmp >= 0) {
/* go right */
cur->left = _addNode(cur->right, val);
}
return cur;
}
the _addnode function was kind of confusing because you were using the return value inconsistently. i believe this version should avoid loosing any nodes.
I don't see an obvious flaw. I would suggest reworking the tree to hold int's or something simpler than your current data. If the tree works fine then at least you know where to look and not worry about the generic tree code.
I suspect _createNode(), can you add that code?