#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
struct
LNode
{
int
data;
int
minHeapIndex;
int
maxHeapIndex;
struct
LNode *next, *prev;
};
struct
List
{
struct
LNode *head;
};
struct
MinHeap
{
int
size;
int
capacity;
struct
LNode* *array;
};
struct
MaxHeap
{
int
size;
int
capacity;
struct
LNode* *array;
};
struct
MyDS
{
struct
MinHeap* minHeap;
struct
MaxHeap* maxHeap;
struct
List* list;
};
void
swapData(
int
* a,
int
* b)
{
int
t = *a; *a = *b; *b = t; }
void
swapLNode(
struct
LNode** a,
struct
LNode** b)
{
struct
LNode* t = *a; *a = *b; *b = t; }
struct
LNode* newLNode(
int
data)
{
struct
LNode* node =
(
struct
LNode*)
malloc
(
sizeof
(
struct
LNode));
node->minHeapIndex = node->maxHeapIndex = -1;
node->data = data;
node->prev = node->next = NULL;
return
node;
}
struct
MaxHeap* createMaxHeap(
int
capacity)
{
struct
MaxHeap* maxHeap =
(
struct
MaxHeap*)
malloc
(
sizeof
(
struct
MaxHeap));
maxHeap->size = 0;
maxHeap->capacity = capacity;
maxHeap->array =
(
struct
LNode**)
malloc
(maxHeap->capacity *
sizeof
(
struct
LNode*));
return
maxHeap;
}
struct
MinHeap* createMinHeap(
int
capacity)
{
struct
MinHeap* minHeap =
(
struct
MinHeap*)
malloc
(
sizeof
(
struct
MinHeap));
minHeap->size = 0;
minHeap->capacity = capacity;
minHeap->array =
(
struct
LNode**)
malloc
(minHeap->capacity *
sizeof
(
struct
LNode*));
return
minHeap;
}
struct
List* createList()
{
struct
List* list =
(
struct
List*)
malloc
(
sizeof
(
struct
List));
list->head = NULL;
return
list;
}
struct
MyDS* createMyDS(
int
capacity)
{
struct
MyDS* myDS =
(
struct
MyDS*)
malloc
(
sizeof
(
struct
MyDS));
myDS->minHeap = createMinHeap(capacity);
myDS->maxHeap = createMaxHeap(capacity);
myDS->list = createList();
return
myDS;
}
int
isMaxHeapEmpty(
struct
MaxHeap* heap)
{
return
(heap->size == 0); }
int
isMinHeapEmpty(
struct
MinHeap* heap)
{
return
heap->size == 0; }
int
isMaxHeapFull(
struct
MaxHeap* heap)
{
return
heap->size == heap->capacity; }
int
isMinHeapFull(
struct
MinHeap* heap)
{
return
heap->size == heap->capacity; }
int
isListEmpty(
struct
List* list)
{
return
!list->head; }
int
hasOnlyOneLNode(
struct
List* list)
{
return
!list->head->next && !list->head->prev; }
void
minHeapify(
struct
MinHeap* minHeap,
int
index)
{
int
smallest, left, right;
smallest = index;
left = 2 * index + 1;
right = 2 * index + 2;
if
( minHeap->array[left] &&
left < minHeap->size &&
minHeap->array[left]->data < minHeap->array[smallest]->data
)
smallest = left;
if
( minHeap->array[right] &&
right < minHeap->size &&
minHeap->array[right]->data < minHeap->array[smallest]->data
)
smallest = right;
if
(smallest != index)
{
swapData(&(minHeap->array[smallest]->minHeapIndex),
&(minHeap->array[index]->minHeapIndex));
swapLNode(&minHeap->array[smallest],
&minHeap->array[index]);
minHeapify(minHeap, smallest);
}
}
void
maxHeapify(
struct
MaxHeap* maxHeap,
int
index)
{
int
largest, left, right;
largest = index;
left = 2 * index + 1;
right = 2 * index + 2;
if
( maxHeap->array[left] &&
left < maxHeap->size &&
maxHeap->array[left]->data > maxHeap->array[largest]->data
)
largest = left;
if
( maxHeap->array[right] &&
right < maxHeap->size &&
maxHeap->array[right]->data > maxHeap->array[largest]->data
)
largest = right;
if
(largest != index)
{
swapData(&maxHeap->array[largest]->maxHeapIndex,
&maxHeap->array[index]->maxHeapIndex);
swapLNode(&maxHeap->array[largest],
&maxHeap->array[index]);
maxHeapify(maxHeap, largest);
}
}
void
insertMinHeap(
struct
MinHeap* minHeap,
struct
LNode* temp)
{
if
(isMinHeapFull(minHeap))
return
;
++minHeap->size;
int
i = minHeap->size - 1;
while
(i && temp->data < minHeap->array[(i - 1) / 2]->data )
{
minHeap->array[i] = minHeap->array[(i - 1) / 2];
minHeap->array[i]->minHeapIndex = i;
i = (i - 1) / 2;
}
minHeap->array[i] = temp;
minHeap->array[i]->minHeapIndex = i;
}
void
insertMaxHeap(
struct
MaxHeap* maxHeap,
struct
LNode* temp)
{
if
(isMaxHeapFull(maxHeap))
return
;
++maxHeap->size;
int
i = maxHeap->size - 1;
while
(i && temp->data > maxHeap->array[(i - 1) / 2]->data )
{
maxHeap->array[i] = maxHeap->array[(i - 1) / 2];
maxHeap->array[i]->maxHeapIndex = i;
i = (i - 1) / 2;
}
maxHeap->array[i] = temp;
maxHeap->array[i]->maxHeapIndex = i;
}
int
findMin(
struct
MyDS* myDS)
{
if
(isMinHeapEmpty(myDS->minHeap))
return
INT_MAX;
return
myDS->minHeap->array[0]->data;
}
int
findMax(
struct
MyDS* myDS)
{
if
(isMaxHeapEmpty(myDS->maxHeap))
return
INT_MIN;
return
myDS->maxHeap->array[0]->data;
}
void
removeLNode(
struct
List* list,
struct
LNode** temp)
{
if
(hasOnlyOneLNode(list))
list->head = NULL;
else
if
(!(*temp)->prev)
{
list->head = (*temp)->next;
(*temp)->next->prev = NULL;
}
else
{
(*temp)->prev->next = (*temp)->next;
if
((*temp)->next)
(*temp)->next->prev = (*temp)->prev;
}
free
(*temp);
*temp = NULL;
}
void
deleteMax(
struct
MyDS* myDS)
{
MinHeap *minHeap = myDS->minHeap;
MaxHeap *maxHeap = myDS->maxHeap;
if
(isMaxHeapEmpty(maxHeap))
return
;
struct
LNode* temp = maxHeap->array[0];
maxHeap->array[0] =
maxHeap->array[maxHeap->size - 1];
--maxHeap->size;
maxHeap->array[0]->maxHeapIndex = 0;
maxHeapify(maxHeap, 0);
minHeap->array[temp->minHeapIndex] = minHeap->array[minHeap->size - 1];
--minHeap->size;
minHeap->array[temp->minHeapIndex]->minHeapIndex = temp->minHeapIndex;
minHeapify(minHeap, temp->minHeapIndex);
removeLNode(myDS->list, &temp);
}
void
deleteMin(
struct
MyDS* myDS)
{
MinHeap *minHeap = myDS->minHeap;
MaxHeap *maxHeap = myDS->maxHeap;
if
(isMinHeapEmpty(minHeap))
return
;
struct
LNode* temp = minHeap->array[0];
minHeap->array[0] = minHeap->array[minHeap->size - 1];
--minHeap->size;
minHeap->array[0]->minHeapIndex = 0;
minHeapify(minHeap, 0);
maxHeap->array[temp->maxHeapIndex] = maxHeap->array[maxHeap->size - 1];
--maxHeap->size;
maxHeap->array[temp->maxHeapIndex]->maxHeapIndex = temp->maxHeapIndex;
maxHeapify(maxHeap, temp->maxHeapIndex);
removeLNode(myDS->list, &temp);
}
void
insertAtHead(
struct
List* list,
struct
LNode* temp)
{
if
(isListEmpty(list))
list->head = temp;
else
{
temp->next = list->head;
list->head->prev = temp;
list->head = temp;
}
}
void
Delete(
struct
MyDS* myDS,
int
item)
{
MinHeap *minHeap = myDS->minHeap;
MaxHeap *maxHeap = myDS->maxHeap;
if
(isListEmpty(myDS->list))
return
;
struct
LNode* temp = myDS->list->head;
while
(temp && temp->data != item)
temp = temp->next;
if
(!temp || temp && temp->data != item)
return
;
minHeap->array[temp->minHeapIndex] = minHeap->array[minHeap->size - 1];
--minHeap->size;
minHeap->array[temp->minHeapIndex]->minHeapIndex = temp->minHeapIndex;
minHeapify(minHeap, temp->minHeapIndex);
maxHeap->array[temp->maxHeapIndex] = maxHeap->array[maxHeap->size - 1];
--maxHeap->size;
maxHeap->array[temp->maxHeapIndex]->maxHeapIndex = temp->maxHeapIndex;
maxHeapify(maxHeap, temp->maxHeapIndex);
removeLNode(myDS->list, &temp);
}
void
Insert(
struct
MyDS* myDS,
int
data)
{
struct
LNode* temp = newLNode(data);
insertAtHead(myDS->list, temp);
insertMinHeap(myDS->minHeap, temp);
insertMaxHeap(myDS->maxHeap, temp);
}
int
main()
{
struct
MyDS *myDS = createMyDS(10);
Insert(myDS, 10);
Insert(myDS, 20);
Insert(myDS, 30);
Insert(myDS, 40);
Insert(myDS, 50);
printf
("Maximum = %d \n", findMax(myDS));
printf
("Minimum = %d \n\n", findMin(myDS));
deleteMax(myDS);
printf
("After deleteMax()\n");
printf
("Maximum = %d \n", findMax(myDS));
printf
("Minimum = %d \n\n", findMin(myDS));
deleteMin(myDS);
printf
("After deleteMin()\n");
printf
("Maximum = %d \n", findMax(myDS));
printf
("Minimum = %d \n\n", findMin(myDS));
Delete(myDS, 40);
printf
("After Delete()\n");
printf
("Maximum = %d \n", findMax(myDS));
printf
("Minimum = %d \n", findMin(myDS));
return
0;
}