There are lots of C examples by using an array to represent the tree.
However, I'm trying to use a tree(Nodes) for the Binary heap.
I was trying to add the child left and then right. In order to insert the elements in Width-first-Search, I've used a Queue. Is this necessary?
My Queue is using a Node* not a int type. Because, if I put a int in the Queue I must search the position of the Node(more time needed). Is this an appropriate way to built a Binary heap?
During the insertion, there are bubbling up and downs. However, since i have a binary heap and also a Queue. Do I have to match the orders in Queue also?
4.Do I need to search for inserting position like a BST? or do I approach to the address directly by using Queue?
I've learned the theory. However, the codes and structures are unfamiliar.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int left(int a,int b)
{
return (int)(a-floor((float)a/(float)b)*b);
}
typedef struct Node
{
int data;
struct Node* leftNext;
struct Node* rightNext;
}Node;
struct queue
{
Node** data;
int top;
int bottom;
int size;
}typedef Queue;
int push(Queue* Q,Node* input)
{
printf("PUSH : %d\n",input);
//한칸은 비울 것임.
if(left((*Q).top-(*Q).bottom,(*Q).size)==(*Q).size-1)
{
printf("큐가 다 찼습니다.\n");
return 0;
}
else
{
//큐의 크기를 넘으면 아래로 이동
if((*Q).top==(*Q).size)
(*Q).top=0;
printf("TOP : %d\n",(*Q).top);
(*Q).data[(*Q).top++]=input;
return 1;
}
}
Node* pop(Queue* Q)
{
if(left((*Q).top-(*Q).bottom,(*Q).size)==0)
printf("큐가 비었습니다.\n");
else
{
if((*Q).bottom==(*Q).size)
(*Q).bottom=0;
printf("BOTTOM : %d\n",(*Q).bottom);
return (*Q).data[(*Q).bottom];
}
}
typedef struct Heap
{
Node* head;
}Heap;
int insert(Node** head,int data,Queue* Q)
{
if((*head)!=NULL)
{
if((*head)->leftNext==NULL)
{
(*head)->leftNext=(Node*)malloc(sizeof(Node));
(*head)->leftNext->data=data;
(*head)->leftNext->leftNext=NULL;
(*head)->leftNext->rightNext=NULL;
push(Q,&(*head)->leftNext);
}
else if((*head)->rightNext==NULL)
{
(*head)->rightNext=(Node*)malloc(sizeof(Node));
(*head)->rightNext->data=data;
(*head)->rightNext->leftNext=NULL;
(*head)->rightNext->rightNext=NULL;
push(Q,&(*head)->rightNext);
(*Q).bottom++;
}
else
{
if(insert((pop(Q)),data,Q)==1)
return 1;
else
return 0;
}
}
else
{
printf("헤드가 비었습니다.");
return 0;
}
return 1;
}
int main()
{
//입력 15 6 12 7 10 17
Heap h;
//큐 초기화
Queue Q;
//큐 크기
int temp=100;
Q.data=(Node**)malloc(sizeof(Node*)*temp);
Q.size=temp;
Q.top=0;
Q.bottom=0;
h.head=(Node*)malloc(sizeof(Node));
h.head->data=15;
h.head->leftNext=NULL;
h.head->rightNext=NULL;
insert(&(h.head),6,&Q);
insert(&(h.head),12,&Q);
insert(&(h.head),7,&Q);
insert(&(h.head),10,&Q);
insert(&(h.head),17,&Q);
return 0;
}
Related
I am in a bit of a pickle. I have a variation of a linked list where not only do the nodes contain a value, but also each node will have a flag declaring whether it is a valid node or not (1 is valid; 0 is invalid). I have some functions that I am having difficulty with. I have deleteLast which deletes the last valid node, or in other words, clears the valid flag to 0. Bear in mind the last valid node might not be the last node; I was hoping countNodes would of use here. deleteValue 'deletes' first valid node with specified value. restoreValue restores the first 'deleted' node with specified value. lastly, compact makes a new list of valid nodes only in reverse order of the old list. deleteLast is the function I'm having most difficulty with. Any feedback on that function or any of the other functions will be of great help. Here's some code:
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
struct Node{
struct Node *link;
int value;
int valid;
}
int countNodes (Node *ptrToFirst){
int count=0;
if(ptrToFirst==NULL){
return 0;
}
else{
while(ptrToFirst!=NULL){
if(ptrToFirst->valid==1)
count++;
ptrToFirst=ptrToFirst->link;
}
}
int deleteLast(Node *ptrToFirst){
Node p;
if(countNodes||ptrToFirst!=NULL){
while(ptrToFirst!=NULL){
ptrToFirst->link;
if(ptrToFirst->valid==1)
if(ptrToFirst->link==NULL){
}
}
}
else return 0;
}
int deleteValue(Node *ptrToFirst, int val){
if(ptrToFirst==NULL){
return 0;
}
while(ptrToFirst!=NULL){
if(ptrToFirst->value==val&&ptrToFirst->valid==1){
ptrToFirst->valid=0;
return 0;
}
else
ptrToFirst=ptrToFirst->link;
}
}
int restoreValue(Node *start, int val){
if(start==NULL){
return 0;
}
while(start!=NULL){
if(start->value==val&&start->valid==0)
start->valid=1;
return 1;
else
start=start->link;
}
}
int compact(Node *old, **ptrToNewHeadPtr){
Node temp;
if(old!=NULL){
while(old!=NULL){
if(old->valid==1)
temp=old;
*ptrToNewHeadPtr=temp;
old=old->link;
}
return 1;
}
else return 0;
}
I was learning how to implement Hash table but i am bit confused here in because in the book below code was available and i understood well enough the code, but inside book there was no definition of HASH function ,i know we have to define it by own ,but according the below code that was given give inside book HASH is taking two arguments wherever i used the HASH like in HashInsert it is taking two arguments index=HASH(data,t->size) if we assume that return type of HASH as int
now for eg we can define HASH as
int HASH(int data,int tsize){
return(data%7);
}
but according to my program how should i update t->size(table size) inside HASH function or how should i use that
Please help me in proper implementation of the above HASH function
#define Load_factor 20
#include<stdio.h>
#include<stdlib.h>
struct Listnode{
int key;
int data;
struct Listnode* next;
};
struct HashTableNode{
int bcount; /// Number of elements in block
struct Listnode* next;
};
struct HashTable{
int tsize; /// Table size
int count;
struct HashTableNode** Table;
};
struct HashTable* createHashTable(int size){
struct HashTable* h;
h=(struct HashTable*)malloc(sizeof(struct HashTable));
h->tsize=size/Load_factor;
h->count=0;
h->Table=(struct HashTableNode**)malloc(sizeof(struct HashTableNode*)*h->tsize);
if(!h->Table){
printf("Memory Error");
return NULL;
}
for(int i=0;i<h->tsize;i++){
h->Table[i]->bcount=0;
h->Table[i]->next=NULL;
}
return h;
}
/// Hashsearch
int HashSearch(struct HashTable* h,int data){
struct Listnode* temp;
temp=h->Table[HASH(data,h->tsize)]->next;
while(temp) ///same as temp!=NULL
{
if(temp->data==data)
return 1;
temp=temp->next;
}
return 0;
}
int HashDelete(struct HashTable* h,int data)
{
int index;
struct Listnode *temp,*prev;
index=HASH(data,h->tsize);
for(temp=h->Table[index]->next,prev=NULL;temp;prev=temp,temp=temp->next)
{
if(temp->data==data)
{
if(prev!=NULL)
prev->next=temp->next;
free(temp);
h->Table[index]->bcount--;
h->count--;
return 1;
}
}
return 0;
}
int HashInsert(struct HashTable *h ,int data){
int index;
struct Listnode* temp,*newnode;
if(HashSearch(h,data))
return 0;
index = HASH(data,h->tsize);
temp=h->Table[index]->next;
newnode=(struct Listnode*)malloc(sizeof(struct Listnode));
if(!newnode)
return -1;
newnode->key=index;
newnode->data;
newnode->next=h->Table[index]->next;
h->Table[index]->next=newnode;
h->Table[index]->bcount++;
h->count++;
return 1;
}
i am just learning implementation of hashing so main is looking quiet weird
int main(){
return 0;
}
You shouldn't! I mean you shouldn't modify it.
Instead the function gets the size of the hash-table (the number of "buckets") so it can use it to create a bucket index from the hash value. This is typically done through modulo %.
So instead of a fixed magic number 7 you modulo with the size:
return(data%tsize);
I get unexpected output in the code for the following problem:
Construct a complete (or almost complete) binary tree from given integer array.
Use a linked list representation of a queue.
Complete binary tree is full BT, and all leafs are on the same level.
Almost complete BT doesn't have to be full BT, and all leafs are on the same level.
Example 1: Almost Complete BT
arr[]={10,9,-5,1,2}
Tree:
10
/ \
9 -5
/ \
1 2
Example 2: Complete BT
arr[]={10,9,-5,1,2,7,4}
Tree:
10
/ \
9 -5
/ \ / \
1 2 7 4
Code
#include <stdio.h>
#include <stdlib.h>
typedef struct node_tree
{
int info;
struct node_tree *left,*right;
}TREE_NODE;
typedef struct node_queue
{
TREE_NODE *tn;
struct node_queue *next;
}QUEUE_NODE;
TREE_NODE *newTN(int info)
{
TREE_NODE *newN=(TREE_NODE*)malloc(sizeof(TREE_NODE));
newN->left=newN->right=0;
newN->info=info;
return newN;
}
void push_queueN(QUEUE_NODE **pf,QUEUE_NODE **pr,TREE_NODE *tn)
{
QUEUE_NODE *newQN=(QUEUE_NODE*)malloc(sizeof(QUEUE_NODE));
newQN->tn=tn;
newQN->next=0;
if(*pf==0)
*pf=*pr=newQN;
else
{
(*pr)->next=newQN;
*pr=newQN;
}
}
int pop_queueN(QUEUE_NODE **pf,QUEUE_NODE **pr,TREE_NODE **tn)
{
if(*pf==0)
return 0;
QUEUE_NODE *p=*pf;
*tn=p->tn;
if(*pf==*pr)
*pf=*pr=0;
else
*pf=p->next;
free(p);
return 1;
}
TREE_NODE *complete(int *arr,int n)
{
TREE_NODE *root;
QUEUE_NODE *pf=0,*pr=0;
int check=0,i;
int *p=arr;
if(p==NULL)
root=NULL;
root=newTN(arr[0]);
push_queueN(&pf,&pr,root);
p++;
for(i=0;i<n;i++)
{
TREE_NODE *parent=pf->tn;
if(pop_queueN(&pf,&pr,&parent))
check=1;
else
check=0;
TREE_NODE *leftChild=NULL,*rightChild=NULL;
leftChild=newTN(&p);
push_queueN(&pf,&pr,leftChild);
p++;
if(p)
{
rightChild=newTN(&p);
push_queueN(&pf,&pr,rightChild);
p++;
}
parent->left=leftChild;
parent->right=rightChild;
}
return root;
}
int height(TREE_NODE *root)
{
if(root==0)
return 0;
int hl=height(root->left);
int hr=height(root->right);
return 1+(hl>hr?hl:hr);
}
void printCurrLevel(TREE_NODE *root,int level)
{
if(root==0)
return;
if(level==1)
printf("%d",root->info);
else if(level>1)
{
printCurrLevel(root->left,level-1);
printCurrLevel(root->right,level-1);
}
}
void levelOrder(TREE_NODE *root)
{
int h=height(root),i;
for(i=1;i<=h;i++)
printCurrLevel(root,i);
}
int main()
{
int arr[]={10,9,-5,1,2};
int n=sizeof(arr)/sizeof(arr[0]);
TREE_NODE *root;
root=complete(arr,n);
levelOrder(root);
return 0;
}
There are some issues with pointers in function complete().
Could someone point out where are the possible errors?
I'm sure I'm making some silly mistake, hope somebody can help me out and clear some of my basic concepts.
Here's my code to create and print a basic BST in C:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct bst
{
int value;
struct bst *left;
struct bst *right;
}T;
T *temp=NULL, *newnode;
T *tree; // had globally declared as NULL previously
T* createnode(int val)
{
newnode=(T*)malloc(sizeof(T));
if(newnode==NULL)
{
printf("Memory not allocated! \n");
}
else
{
newnode->value=val;
newnode->right=NULL;
newnode->left=NULL;
}
return newnode;
}
T * insert_tree(T *tree, int val)
{
if(tree==NULL)
{
newnode=createnode(val);
tree=newnode;
return tree;
}
if (val < tree->value)
{
tree->left=insert_tree(tree->left,val);
}
else if(val > tree->value)
{
tree->right=insert_tree(tree->right, val);
}
return tree;
}
void display_preorder(T *tree) //changed to accept parameter
{
if(tree)
{
printf("%d \n", tree->value);
display_preorder(tree->left);
display_preorder(tree->right);
}
}
int main(void)
{
insert_tree(tree,34);
insert_tree(tree,45);
insert_tree(tree,88);
insert_tree(tree,87);
display_preorder();
return 0;
}
It runs and executes without error, but, the output screen is blank.
Can somebody please point out the errors and mistakes?
Thank You.
The problem is in the insert_tree function.
Because your function gets only a pointer of a tree and not a pointer to a pointer you returned the value.
So, in the main you should place the tree equal to the function.
Your function gets the tree pointer by value and not by reference.
like this:
int main(void)
{
tree = insert_tree(tree, 34);
tree = insert_tree(tree, 45);
tree = insert_tree(tree, 88);
tree = insert_tree(tree, 87);
display_preorder(tree);
getchar();
return 0;
}
I am trying to insert values to a queue based on a condition. Condition is the value entered previously should be larger than the value which is going to be inserted. My problem is according to my data i have been provided with, one value is small than all the other values, so other values are not inserted in to the queue.
I am stuck here the whole day, without any clue.
Here is what i have done so far :
#include<stdio.h>
#include<malloc.h>
#define MAX 180
struct cakes{
int spongecake;
int meringue;
int chocalate;
int red_velvet;
struct newcake *next;
};
struct Queue{
int front;
int rear;
int count;
int cake[10];
};
void order_out(struct cakes *);
void init(struct Queue *);
int isFull(struct Queue *);
void insert(struct Queue *,int);
int isEmpty(struct Queue *);
int removes(struct Queue *);
main()
{
struct cakes *head;
head=(struct cakes*)malloc(sizeof(struct cakes));
order_out(head);
}
void init(struct Queue *q)
{
q->front=0;
q->rear=10-1;
q->count=0;
}
int isFull(struct Queue *q)
{
if(q->count==10)
{
return 1;
}
else
{
return 0;
}
}
void insert(struct Queue *q,int x)
{
if(!isFull(q))
{
q->rear=(q->rear+1)%10;
q->cake[q->rear]=x;
q->count++;
}
}
int isEmpty(struct Queue *q)
{
if(q->count==0)
{
return 1;
}
else
{
return 0;
}
}
int removes(struct Queue *q)
{
int caked=NULL;
if(!isEmpty(q))
{
caked=q->cake[q->front];
q->front=(q->front+1)%10;
q->count--;
return caked;
}
}
void order_out(struct cakes *theorder)
{
struct Queue s;
int k=0;
int i=1;
int value1;
int value2;
int counter=1;
theorder->spongecake=20;
theorder->meringue=75;
theorder->chocalate=40;
theorder->red_velvet=30;
init(&s);
insert(&s,theorder->chocalate);
value1=theorder->chocalate;
for(;k<10;k++)
{
if(value1>theorder->spongecake)
{
insert(&s,theorder->spongecake);
value1=theorder->spongecake;
}
if(value1>theorder->meringue)
{
insert(&s,theorder->meringue);
value1=theorder->meringue;
}
if(value1>theorder->red_velvet)
{
insert(&s,theorder->red_velvet);
value1=theorder->red_velvet;
}
}
while(!isEmpty(&s))
{
printf("\n%d",removes(&s));
}
}
Any idea on how to make the other values entered in to the queue but also at the same time check whether the previous value is larger than the current value.
EDIT :
I tried adding a count meaning if the count % value1==0, then i tried to make the value1 into a bigger value by multiplying by 5 but still only those 2 values got inserted.
Thank you for your time.