I am having a problem with my program in C, for some reason it does not give back the right results I am looking for. When I run it it shows the instructions twice and then says invalid choice even when I have not inputted a choice, when I do put a choice it doesn't out output what I want it to even though I believe the code is right.
And this is the output that the program gives: The code is as follows:
#include <stdio.h>
#include <stdlib.h>
int arr[100005];
int n;
void max(int index){
if (index>=n)return;
int left=2*index 1;
int right = 2*index 2;
int mx_ind=index;
if (left < n && arr[left]>arr[mx_ind]){
mx_ind=left;
}
if (right < n && arr[left]>arr[mx_ind]){
mx_ind=right;
}
if (mx_ind !=index){
int tmp=arr[mx_ind];
arr[mx_ind]=arr[index];
arr[index]=tmp;
max(mx_ind);
}
}
int insert(int num,int location){
int p;
while (location>0)
{
p=(location-1)/2;
if(num>=arr[p])
{
arr[location]=arr[p];
}
else break;
location=p;
}
arr[location]=num;
return 0;
}
void del(int index){
arr[index]=arr[n-1];
n=n-1;
max(index);
}
void buildmaxheap(){
for (int i=n/2-1;i>=0;i--){
max(i);
}
}
void display(){
for (int i=0;i<n;i ){
printf("%d",arr[i]);
printf("\n");
}
}
int returnmax(){
return arr[0];
}
int extractmax(){
int mx=arr[0];
del(0);
return mx;
}
int main()
{
printf("enter num of elements");
scanf("%d",&n);
printf("enter value of elements");
for(int i=0;i<n;i ){
scanf("%d",&arr[i]);
}
buildmaxheap();
int num,index;
char choice;
while(1){
printf("1. extract max\n");
printf("2. insert new key\n");
printf("3. change key at A[i]\n");
printf("4. delete key at A[i] \n");
printf("5. return max\n");
printf("6. exit\n");
printf("Enter your choice:");
scanf("%c",&choice);
switch(choice)
{
case '1':
printf("Max value is : %d\n", extractmax);
break;
case '2':
scanf("%d",&num);
insert(num,n);
n ;
printf("Content of array is:");
display();
break;
case '3':
scanf("%d %d",&index,&num);
arr[index]=num;
if (arr[(index-1)/2]>num)max(index);
else insert(num,index);
printf("content of array is : ");
display();
break;
case '4':
scanf("%d",&index);
del(index);
printf("Content of array is : \n");
display();
break;
case '5':
printf("Max value is : %d\n", extractmax);
break;
case '6':
exit(1);
break;
default:printf("invalid choice\n");
}
}
return 0;
}
Any help would be appreciated.
CodePudding user response:
A few issues:
The "invalid choice" output occurs because
choice
gets a white space (line break) as value. To avoid that white space is taken as the choice, exclude that by prefixing thescanf
format string with a space:scanf(" %c", &choice)
In
max
you have a bug in the secondif
condition. You should useright
as index instead ofleft
For some operations it is required that the array is not empty. This should be checked to avoid problems.
In case 3 the expression
arr[(index - 1) / 2]
is invalid whenindex
is zero.
Furthermore, I would suggest not calling exit(1)
when the user chooses 6, but make that a while
condition.
Here is a corrected version:
#include <stdio.h>
#include <stdlib.h>
int arr[100005];
int n;
void max(int index) {
if (index >= n) return;
int left = 2 * index 1;
int right = left 1;
int mx_ind = index;
if (left < n && arr[left] > arr[mx_ind]) {
mx_ind = left;
}
if (right < n && arr[right] > arr[mx_ind]) { // bug fix
mx_ind = right;
}
if (mx_ind != index) {
int tmp = arr[mx_ind];
arr[mx_ind] = arr[index];
arr[index] = tmp;
max(mx_ind);
}
}
int insert(int num, int location){
int p;
while (location > 0) {
p = (location - 1) / 2;
if (num >= arr[p]) {
arr[location] = arr[p];
}
else break;
location = p;
}
arr[location] = num;
return 0;
}
void del(int index) {
arr[index] = arr[n - 1];
n--;
max(index);
}
void buildmaxheap() {
for (int i = n / 2 - 1; i >= 0; i--) {
max(i);
}
}
void display() {
for (int i = 0; i < n; i ) {
printf("%d ", arr[i]);
}
printf("\n");
}
int returnmax() {
return arr[0];
}
int extractmax() {
int mx = arr[0];
del(0);
return mx;
}
int main() {
printf("enter num of elements: ");
scanf("%d", &n);
printf("enter value of elements: ");
for(int i = 0; i < n; i ) {
scanf("%d", &arr[i]);
}
buildmaxheap();
int num,index;
char choice = ' ';
while (choice != '6') { // Nicer to add the condition here
// Maybe always start each iteration with this:
printf("Content of array is: ");
display();
printf("1. extract max\n");
printf("2. insert new key\n");
printf("3. change key at A[i]\n");
printf("4. delete key at A[i] \n");
printf("5. return max\n");
printf("6. exit\n");
printf("Enter your choice: ");
scanf(" %c", &choice); // Skip white space
switch (choice) {
case '1':
if (n == 0) { // Add this protection
printf("The array is empty\n");
} else {
// Should call the function
printf("Max value is: %d\n", extractmax());
}
break;
case '2':
scanf("%d", &num);
insert(num, n);
n ;
break;
case '3':
// Help the user:
printf("Enter index and new value: ");
scanf("%d %d", &index, &num);
// Add this protection:
if (index >= n) {
printf("The array does not have this index\n");
} else {
arr[index] = num;
// Add case for when index is 0
if (index == 0 || arr[(index - 1) / 2] > num) max(index);
else insert(num, index);
}
break;
case '4':
// Help the user:
printf("Enter index: ");
scanf("%d", &index);
// Add this protection:
if (index >= n) {
printf("The array does not have this index\n");
} else {
del(index);
}
break;
case '5':
if (n == 0) { // Add this protection
printf("The array is empty\n");
} else {
// Call the function, and the right one:
printf("Max value is : %d\n", returnmax());
}
break;
case '6':
break; // Just break and use while condition to quit (no exit())
default:
printf("invalid choice '%c'\n", choice);
}
}
return 0;
}
The names for the functions max
and insert
are misleading. max
is not returning a maximum value, and insert
is not making the list longer. It is more common to name these functions respectively siftDown
and siftUp
, or something similar.