C return big number confusion - c

When I input the string instead of y or n in this code, it will return the large number.
So I want to know how to fix it.
My first thought is that if I input the string instead of this,
it will return to the first paragraph and run again.
But when I trying to use this, it will return and run again.
But It will save the string and change it into an ASCII code.
#include <stdlib.h>;
#include <stdio.h>;
int main() {
int num = 1; //設置迴圈變數
int change; //設置可變動變數
int count=0; // 跑了幾次
char ans1,ans2,ans3,ans4,ans5,ans6,ans7 ; //答案共7個
int final_ans = 0;//最後答案
printf("thinking a number on your mind, and I will guess it!\n\n");
first:
for(num=1; num<=100; num+=2) {
++count;
printf("%-4.2d", num);//4格寬 數字顯示2位
if(count%9==0) {
printf("\n");//每執行9次換行
}
}
count = 0;//清空變數
printf("\n");
printf("Is your number on the table (y/n)? \n");
scanf("%s", &ans1);
if((ans1=='Y') || (ans1=='y')) { //若有數字
final_ans += 1;
}
second:
for(num=2; num<=100; num+=2) {
change = num;
++count;
if(count%2==0) {
change--;
}
printf("%-4.2d", change);//4格寬 數字顯示2位
if(count%9==0) {
printf("\n");//每執行9次換行
}
}
printf("\n");
printf("Is your number on the table (y/n)? \n");
scanf("%s", &ans2);
count = 0;//清空變數
change = 0;//清空變數
if((ans2=='Y') || (ans2=='y')) {
final_ans += 2;
}
third:
for(num=4; num<=100; num++) {
change = num;
++count;
if(count%4==1&&num!=4) {
num+=4;
}
printf("%-4.2d", num);//4格寬 數字顯示2位
if(count%9==0) {
printf("\n");//每執行9次換行
}
}
printf("\n");
printf("Is your number on the table (y/n)? \n");
scanf("%s", &ans3);
count = 0;//清空變數
change = 0;//清空變數
if((ans3=='Y') || (ans3=='y')) {
final_ans +=4;
}
fourth:
for(num=8; num<=100; num++) {
change = num;
++count;
if(count%8==1&&num!=8) {
num+=8;
}
if(num>100) {
break;
}
printf("%-4.2d", num);//4格寬 數字顯示2位
if(count%9==0) {
printf("\n");//每執行9次換行
}
}
printf("\n");
printf("Is your number on the table (y/n)? \n");
scanf("%s", &ans4);
count = 0;//清空變數
change = 0;//清空變數
if((ans4=='Y') || (ans4=='y')) {
final_ans += 8;
}
fifth:
for(num=16; num<=100; num++) {
change = num;
++count;
if(count%16==1&&num!=16) {
num+=16;
}
if(num>100) {
break;
}
printf("%-4.2d", num);//4格寬 數字顯示2位
if(count%9==0) {
printf("\n");//每執行9次換行
}
}
printf("\n");
printf("Is your number on the table (y/n)? \n");
scanf("%s", &ans5);
count = 0;//清空變數
change = 0;//清空變數
if((ans5=='Y') || (ans5=='y')) {
final_ans += 16;
}
sixth:
for(num=32; num<=100; num++) {
change = num;
++count;
if(count%32==1&&num!=32) {
num+=32;
}
if(num>100) {
break;
}
printf("%-4.2d", num);//4格寬 數字顯示2位
if(count%9==0) {
printf("\n");//每執行9次換行
}
}
printf("\n");
printf("Is your number on the table (y/n)? \n");
scanf("%s", &ans6);
count = 0;//清空變數
change = 0;//清空變數
if((ans6=='Y') || (ans6=='y')) {
final_ans += 32;
}
seventh:
for(num=64; num<=100; num++) {
++count;
printf("%-4.2d", num);//4格寬 數字顯示2位
if(count%9==0) {
printf("\n");//每執行9次換行
}
}
printf("\n");
printf("Is your number on the table (y/n)? \n");
scanf("%s", &ans7);
if((ans7=='Y') || (ans7=='y')) {
final_ans += 64;
}
else if((ans1=='n') || (ans1=='N')) { //若無數字
final_ans += 0;
goto second;//回到第二個table
} else if((ans2=='n') || (ans2=='N')) { //若無數字
final_ans += 0;
goto third;//回到第三個table
} else if((ans3=='n') || (ans3=='N')) { //若無數字
final_ans += 0;
goto fourth;//回到第四個table
} else if((ans4=='n') || (ans4=='N')) { //若無數字
final_ans += 0;
goto fifth;//回到第五個table
} else if((ans5=='n') || (ans5=='N')) { //若無數字
final_ans += 0;
goto sixth;//回到第六個table
} else if((ans6=='n') || (ans6=='N')) { //若無數字
final_ans += 0;
goto seventh;//回到第七個table
} else if((ans7=='n') || (ans7=='N')) { //若無數字
final_ans += 0;
}
if(final_ans<=100) { //判斷最後答案
printf("your secret number is %d",final_ans);
} else if(final_ans>100) {
printf("WRONG!%d is not a number form 1~100",final_ans);
}
}

you have put ; after every library please remove that
#include <stdlib.h>; // remove the ;
#include <stdio.h>; // remove the ;
correct code must be
#include <stdlib.h>
#include <stdio.h>
By editing that I got correct answers. it works for me.
I have think about 73
output -:
thinking a number on your mind, and I will guess it!
01 03 05 07 09 11 13 15 17
19 21 23 25 27 29 31 33 35
37 39 41 43 45 47 49 51 53
55 57 59 61 63 65 67 69 71
73 75 77 79 81 83 85 87 89
91 93 95 97 99
Is your number on the table (y/n)?
y
02 03 06 07 10 11 14 15 18
19 22 23 26 27 30 31 34 35
38 39 42 43 46 47 50 51 54
55 58 59 62 63 66 67 70 71
74 75 78 79 82 83 86 87 90
91 94 95 98 99
Is your number on the table (y/n)?
n
04 05 06 07 12 13 14 15 20
21 22 23 28 29 30 31 36 37
38 39 44 45 46 47 52 53 54
55 60 61 62 63 68 69 70 71
76 77 78 79 84 85 86 87 92
93 94 95 100
Is your number on the table (y/n)?
n
08 09 10 11 12 13 14 15 24
25 26 27 28 29 30 31 40 41
42 43 44 45 46 47 56 57 58
59 60 61 62 63 72 73 74 75
76 77 78 79 88 89 90 91 92
93 94 95
Is your number on the table (y/n)?
y
16 17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 48 49
50 51 52 53 54 55 56 57 58
59 60 61 62 63 80 81 82 83
84 85 86 87 88 89 90 91 92
93 94 95
Is your number on the table (y/n)?
n
32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58
59 60 61 62 63 96 97 98 99
100
Is your number on the table (y/n)?
n
64 65 66 67 68 69 70 71 72
73 74 75 76 77 78 79 80 81
82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99
100
Is your number on the table (y/n)?
n
64 65 66 67 68 69 70 71 72
73 74 75 76 77 78 79 80 81
82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99
100
Is your number on the table (y/n)?
y
your secret number is 73

Related

How to print a "neat" 2D array in C

I am able to print out a 2D array into an output file but it is not uniform. I would like to have the 2D array evenly spaced when it is printed out. I am fairly new at programing in C so any help would be greatly appreciated!
My Code:
#include <stdio.h>
#include <stdlib.h>
/**
* Driver method for program
*/
int main()
{
int nums[200];
int i = 0;
int j = 0;
FILE * in_file;
FILE * out_file;
srand(time(0)); //seed for random generator
/**
* if loop reads text file and stores numbers into array
*/
if (in_file = fopen("Data.txt", "r")) {
while (fscanf(in_file, "%d", &nums[i]) != EOF) {
i++;
}
int numbsinfile = i;
int random = randomNumber(2, 12);
int matrix1[5][random];
int matrix2[random][5];
out_file = fopen("out.txt", "w");
fprintf(out_file, "Matrix 1: \n");
fprintf(out_file, "Rows = 5 \n");
fprintf(out_file, "Columns = %d \n\n", random);
for(i = 0; i < 5; i++ ){
for(j = 0; j < random; j++){
int rand = randomNumber(0, numbsinfile);
matrix1[i][j] = nums[rand];
fprintf(out_file, "%d \t\t", matrix1[i][j]);
}
fprintf(out_file, "\n");
}
fclose(in_file);
fclose(out_file);
}
return 0;
}
/**
* Generates and prints random
* numbers in range [lower, upper].
*/
int randomNumber(int lower, int upper) {
int num = (rand() % (upper - lower + 1)) + lower;
return num;
}
The input file I am using along with the output file that my code produces. I am basically just wanting to clean up the 2D array that is printed to the output file.
input file:
23 34 -54 21 45 34 65 -54 21 45 34 65 -34 24 58
49 45 10 -57 20
57 39 20 58 23 10 20 58 -60 76 -82 28
28 -37 49 358 47 -50 37 29
57 -29 -20 47 69
93 57 23 49 -38 49 27 -40 48 39
56 -30 47 28 49
37 49
27 26 10 20 58 -60 26 10 20 58 -60 76 -82 28
28 -37 49 -28 93 28
73 47 27 83 37 -29 40 37 49 20
17 -26 12 17 17
18 38 29 39 -118
19 10 20 58 -60 76 -82 28
28 -37 49 59 10 58 -60 76 -82 28
28 -37 49 59 10 20 58 -60 76 -82 28
28 -37 49 30 -58 58 38 49 30 -58 58 38
49 30 -58 58 38
28 39
39 48 23 -50 28
48 29 39 40 29
My output file:
Matrix 1:
Rows = 5
Columns = 12
28 39 20 49 58 76 37 -26 47 -40 216309856 26
57 -50 30 47 29 58 73 20 26 216309856 49 26
216309856 30 59 45 20 23 -50 83 -50 -37 28 30
10 10 23 28 47 45 34 10 19 -38 -118 28
47 49 -40 20 49 29 10 20 58 69 10 28
How to print a “neat” 2D array in C (?)
Find the longest text width using snprintf(NULL, 0, some_format, ...
int width = 1;
for(i = 0; i < 5; i++ ) {
for(j = 0; j < random; j++) {
int rand = randomNumber(0, numbsinfile);
matrix1[i][j] = nums[rand];
int w = snprintf(NULL, 0, "%d", matrix1[i][j]);
if (w > width) width = w;
}
}
Use * in the specifier and width for printing.
for(i = 0; i < 5; i++ ) {
for(j = 0; j < random; j++) {
fprintf(out_file, " %*d", width, matrix1[i][j]);
}
fprintf(out_file, "\n");
}

Odd behavior in my code for a certain test case

The program is supposed to swap neighbouring elements which don't have a common denominator, and an element can only be swapped once.
When i run the program, pretty much for any input works fine. Except for this one:
100 //input for number of elements
48 92 76 93 17 38 59 34 53 99 58 20 50 0 38 37 16 36 91 12 59 1 76 82 20 76 7 72 13 70 64 23 81 70 41 69 11 0 16 41 37 83 41 99 73 79 4 38 24 32 87 38 95 24 77 30 61 13 89 67 87 76 22 31 67 31 25 90 6 76 21 43 40 55 72 91 91 28 18 58 72 71 83 22 99 23 86 58 75 53 69 29 5 55 46 8 98 55 19 46 //the elements
For this input, the program hangs and prints nothing. Does someone know what is going on in this particular case?
#include <stdio.h>
int nzd(int a, int b)
{
if(a==b || b==0)
return a;
if(a>b)
return nzd(a-b, b);
return nzd(a, b-a);
}
int swap(int *niza, int i)
{
int temp;
temp=*(niza+i);
*(niza+i)=*(niza+i+1);
*(niza+i+1)=temp;
}
int main()
{
int a[100], n, i;
scanf("%d", &n);
for(i=0; i<n; i++)
{
scanf("%d", &a[i]);
}
for(i=0; i<n; i++)
{
if(i+1==n) continue;
if(nzd(a[i], a[i+1])==1)
{
swap(a, i);
i++;
}
}
for(i=0; i<n; i++)
{
printf("%d ", a[i]);
}
return 0;
}
Your gcd function checks for the case of b==0 but not the case for a==0. Because you skip that check, you end up calling nzd(0, b-0); which is exactly the same as the prior call. This puts you in an infinite recursion loop which will eventually cause a stack overflow.
Add the check for this case in your function:
if(a==b || b==0 || a == 0)
Also, a faster implementation of gcd, called Euclid's algorithm, is as follows:
int gcd(int a, int b)
{
if (b==0) {
return a;
} else {
return (b, a%b);
}
}
Your function nzd() fails to handle the case a == 0 correctly and gets stuck in an endless loop. You need to handle this case, too:
int nzd(int a, int b)
{
if(a==b || a==0 || b==0)
return a;
if(a>b)
return nzd(a-b, b);
return nzd(a, b-a);
}

Could somebody help me with my Code (C language)?

I am a beginner in C language and I have been asked to: write a whole program printing in separate lines odd numbers from 100 to 0, and marking with "!!!" those numbers that are multiplications of 7.
I tried to do that but unfortunately iam printing numbers which are duplications for example (91 and 91!!!). How can I avoid this situation?
Here is my code maybe someone can help me with this task?
#include <stdio.h>
int main ()
{
int i;
for (i=100;i>=0;i--)
{
if(i%2)
{
printf("%d\n",i);
}
if (i%7==0 && i%2!=0)
{
printf("%d!!!\n",i);
}
}
}
This is a solution based on Aditi Rawat comment.
#include "stdio.h"
int main ()
{
int i;
for (i=100; i>=0; i--)
{
if (i%7==0 && i%2!= 0)
{
printf("%d!!!\n",i);
}
else
{
if(i%2 != 0)
printf("%d\n",i);
}
}
return 0;
}
OUTPUT:
99
97
95
93
91!!!
89
87
85
83
81
79
77!!!
75
73
71
69
67
65
63!!!
61
59
57
55
53
51
49!!!
47
45
43
41
39
37
35!!!
33
31
29
27
25
23
21!!!
19
17
15
13
1

What's wrong with the matrix?

What's wrong with this code?
My task is: Create a square matrix of integers with a size of 9x9. Fill the matrix with random numbers. Display the main and side diagonal symmetrically with respect to the vertical axis. The example of expected result is here: matrix
Matrix :
20 20 76 65 93 76 16 2 85
6 87 78 43 48 81 71 90 38
10 12 35 77 48 88 24 53 7
12 66 51 35 74 7 30 22 49
58 14 71 46 68 68 10 81 51
98 16 74 47 64 25 17 30 37
2 44 44 74 34 54 86 73 28
85 4 57 75 18 28 51 76 2
35 17 53 76 15 91 83 85 72
The main and side diagonal:
85 20 76 65 93 76 16 2 20
6 90 78 43 48 81 71 87 38
10 12 24 77 48 88 35 53 7
12 66 51 7 74 35 30 22 49
58 14 71 46 68 68 10 81 51
98 16 74 25 64 47 17 30 37
2 44 86 74 34 54 44 73 28
85 76 57 75 18 29 51 4 2
72 17 53 76 15 91 83 85 35
But in fact the program prints only the main matrix with random numbers and after that stops.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <Windows.h>
int main()
{
int a = 9;
int matrix[a][a];
int temp;
int i, j, n;
srand((unsigned)time(NULL));
printf("Matrix : \n\n");
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
matrix[i][j] = rand() % 100;
printf("%d\t", matrix[i][j]);
}
printf("\n\n");
}
printf("The main and side diagonal:\n\n");
for (i = 0; i < a; ++i) {
temp = matrix[i][i];
matrix[i][i] = matrix[i][(a - 1) - i];
matrix[i][(a - 1) - i] = temp;
}
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
printf("Result:", matrix[i][j]);
printf("\n\n\n");
system("pause");
return 0;
}
}
}
You are returning where you are not supposed to. (in middle of the calculation). You should return after you end up working on the for loops.
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
printf("Result:", matrix[i][j]); <--- Not printing element
printf("\n\n\n");
system("pause");
return 0; <-----
}
}
It should be
for (i = 0; i < a; ++i) {
for (j = 0; j < a; ++j) {
printf("Result: %d ", matrix[i][j]); <----You forgot the
//format specifier
printf("\n\n\n");
system("pause");
}
}
return 0;<-----
Readability is hampered when the indentation is like this. You implemented wrong logic out of it.
OP asks that it stops after printing "Result" that is because you forgot to put the format specifier in the code. That's why none of the element is printed.
Op wants to print the main and side diagonal symmetrically with respect to the vertical axis.
Now this is everything to with the print part.
Now we have to find a way that will let us distinguish which one is diagonal element and which one is not.
Suprisingly the answer should be known to someone who is writing the previous swapping logic. (Though it is not clear why OP swapped it).
Now all element matrix[p][q] will be from either diagonal if p=q or p+q=a-1. (Note that matrix is a square matrix).
But OP meant to print the matrix
for (i = 0; i < a; ++i) {
if( i == 0) printf("The main and side diagonal : \n");
for (j = 0; j < a; ++j) {
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
}
Use functions. You print the matrix twice; you should have a function to print the matrix which you call twice.
With such a function, you'd not make the mistakes in the tail end of your code. For example, you could use this:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static void print_matrix(const char *tag, int size, int matrix[size][size])
{
printf("%s (%dx%d):\n\n", tag, size, size);
for (int i = 0; i < size; ++i)
{
const char *pad = "";
for (int j = 0; j < size; ++j)
{
printf("%s%-2d", pad, matrix[i][j]);
pad = " ";
}
printf("\n\n");
}
}
int main(int argc, char **argv)
{
unsigned seed = time(0);
int a = 9;
int matrix[a][a];
if (argc == 2)
seed = atoi(argv[1]);
srand(seed);
printf("Seed: %u\n", seed);
for (int i = 0; i < a; ++i)
{
for (int j = 0; j < a; ++j)
matrix[i][j] = rand() % 100;
}
print_matrix("Matrix", a, matrix);
for (int i = 0, j = a - 1; i < a; ++i, --j)
{
int temp = matrix[i][i];
matrix[i][i] = matrix[i][j];
matrix[i][j] = temp;
}
print_matrix("The main and side diagonal", a, matrix);
return 0;
}
The code reports the seed it uses; that allows you to reproduce any run by specifying the seed to use as a command line argument.
Example output:
Seed: 1511470282
Matrix (9x9):
11 39 3 88 98 63 75 81 76
93 9 60 22 45 50 46 58 65
13 99 25 43 14 57 44 70 65
30 57 55 0 37 84 47 49 40
60 28 46 1 96 78 33 20 9
93 61 11 38 84 16 91 26 15
43 85 66 72 85 39 96 45 45
45 25 33 3 78 90 61 65 62
88 84 56 34 74 8 78 57 74
The main and side diagonal (9x9):
76 39 3 88 98 63 75 81 11
93 58 60 22 45 50 46 9 65
13 99 44 43 14 57 25 70 65
30 57 55 84 37 0 47 49 40
60 28 46 1 96 78 33 20 9
93 61 11 16 84 38 91 26 15
43 85 96 72 85 39 66 45 45
45 65 33 3 78 90 61 25 62
74 84 56 34 74 8 78 57 88
The swapping process, in case it isn't obvious, swaps the first and last elements of the first row, the second and last but one element in the second row, and so on, forming an X of swapped elements.

Post Order print without recursion

This is what i have so far. I really don't understand where i went wrong. It needs to print after it has visited the left most node and then right then print.
void printPostOrderIterative(BSTNode *root)
{
BSTNode *cur;
Stack s;
s.top = NULL;
Stack output;
output.top = NULL;
if (!root) {
return;
}
push(&s, root);
while (isEmpty(&s) != 1 ) {
cur = s.top;
push(&output,cur);
pop(&s);
if (cur->left){
push(&s, cur->left);
}
if (cur->right){
push(&s, cur->right);
}
}
while (isEmpty(&output) != 1) {
printf("%d", output.top);
pop(&output);
}
}
Currently, the code just keeps looping in the first while loop.
Here is some working code. I had to implement an approximation to your stack code, and the BST code, but I made only very simple changes to your function. There are arguments that I should not have had to do the creation: Stack Overflow encourages you to create an MCVE (How to create a Minimal, Complete, and Verifiable Example?)
SSCCE (Short, Self-Contained, Correct Example) — two names and links for the same basic idea.
Without any major algorithmic tweaks, your code (a) completes and (b) produces the same answer as a recursive post-order print function (on one sample data set).
static void printPostOrderIterative(BSTNode *root)
{
if (!root) // Moved to avoid stack initialization before returning
return; // …ditto…
Stack s;
Stack output;
init(&s); // Different initialization
init(&output); // Different initialization
push(&s, root);
while (isEmpty(&s) != 1)
{
BSTNode *cur = top(&s); // Different code
push(&output, cur);
pop(&s);
if (cur->left)
push(&s, cur->left);
if (cur->right)
push(&s, cur->right);
}
while (isEmpty(&output) != 1)
{
BSTNode *c = top(&output); // Different code
printf(" %d", c->data); // Added space
pop(&output);
}
putchar('\n'); // Extra code
clean(&s); // Extra code
clean(&output); // Extra code
}
Thus the problem is probably not in the code you show — it is more likely in the code you don't show. My best guess is that the stack implementation is slightly faulty, but since you don't show it, it is hard to be sure.
Full code
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct BSTNode BSTNode;
struct BSTNode
{
int data;
BSTNode *left;
BSTNode *right;
};
typedef struct Stack
{
size_t size;
size_t top;
BSTNode **stack;
} Stack;
static void err_syserr(const char *fmt, ...)
{
int errnum = errno;
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
if (errnum != 0)
fprintf(stderr, "(%d: %s)\n", errnum, strerror(errnum));
exit(1);
}
static void push(Stack *sp, BSTNode *np)
{
assert(sp != 0 && np != 0);
if (sp->top == sp->size)
{
size_t n_size = (sp->size + 2) * 2;
void *n_data = realloc(sp->stack, n_size * sizeof(*sp->stack));
if (n_data == 0)
err_syserr("Out of memory (%zu bytes requested)\n",
n_size * sizeof(*sp->stack));
sp->stack = n_data;
sp->size = n_size;
}
sp->stack[sp->top++] = np;
}
static bool isEmpty(Stack *sp)
{
return sp->top == 0;
}
static void pop(Stack *sp)
{
if (!isEmpty(sp))
sp->top--;
}
static void init(Stack *sp)
{
sp->top = 0;
sp->size = 0;
sp->stack = 0;
}
static BSTNode *top(Stack *sp)
{
if (sp->top == 0)
return 0;
return sp->stack[sp->top - 1];
}
static void clean(Stack *sp)
{
while (sp->top > 0)
free(sp->stack[--sp->top]);
free(sp->stack);
init(sp);
}
static BSTNode *new_node(int data)
{
BSTNode *np = malloc(sizeof(*np));
if (np == 0)
err_syserr("Out of memory (%zu bytes requested)\n", sizeof(*np));
np->data = data;
np->left = 0;
np->right = 0;
return np;
}
static void printPostOrderIterative(BSTNode *root)
{
if (!root)
return;
Stack s;
Stack output;
init(&s); // Different initialization
init(&output); // Different initialization
push(&s, root);
while (isEmpty(&s) != 1)
{
BSTNode *cur = top(&s); // Different code
push(&output, cur);
pop(&s);
if (cur->left)
push(&s, cur->left);
if (cur->right)
push(&s, cur->right);
}
while (isEmpty(&output) != 1)
{
BSTNode *c = top(&output);
printf(" %d", c->data);
pop(&output);
}
putchar('\n'); // Extra code
clean(&s); // Extra code
clean(&output); // Extra code
}
static void printPostOrderRecursive(BSTNode *root)
{
if (root != 0)
{
printPostOrderRecursive(root->left);
printPostOrderRecursive(root->right);
printf(" %d", root->data);
}
}
static void printInOrderRecursive(BSTNode *root)
{
if (root != 0)
{
printInOrderRecursive(root->left);
printf(" %d", root->data);
printInOrderRecursive(root->right);
}
}
static BSTNode *bst_add(BSTNode *root, int data)
{
if (root == 0)
root = new_node(data);
else if (root->data > data)
root->left = bst_add(root->left, data);
else
root->right = bst_add(root->right, data);
return root;
}
static void bst_destroy(BSTNode *root)
{
if (root != 0)
{
bst_destroy(root->left);
bst_destroy(root->right);
free(root);
}
}
int main(void)
{
int data[] =
{
71, 57, 4, 31, 47, 65, 69, 65, 98, 81,
54, 58, 17, 37, 48, 64, 64, 93, 40, 22,
45, 62, 99, 47, 18, 86, 67, 99, 68, 27,
};
enum { NUM_DATA = sizeof(data) / sizeof(data[0]) };
BSTNode *root = 0;
for (int i = 0; i < NUM_DATA; i++)
{
root = bst_add(root, data[i]);
printInOrderRecursive(root);
putchar('\n');
}
printPostOrderRecursive(root);
putchar('\n');
printPostOrderIterative(root);
bst_destroy(root);
return 0;
}
Sample output
71
57 71
4 57 71
4 31 57 71
4 31 47 57 71
4 31 47 57 65 71
4 31 47 57 65 69 71
4 31 47 57 65 65 69 71
4 31 47 57 65 65 69 71 98
4 31 47 57 65 65 69 71 81 98
4 31 47 54 57 65 65 69 71 81 98
4 31 47 54 57 58 65 65 69 71 81 98
4 17 31 47 54 57 58 65 65 69 71 81 98
4 17 31 37 47 54 57 58 65 65 69 71 81 98
4 17 31 37 47 48 54 57 58 65 65 69 71 81 98
4 17 31 37 47 48 54 57 58 64 65 65 69 71 81 98
4 17 31 37 47 48 54 57 58 64 64 65 65 69 71 81 98
4 17 31 37 47 48 54 57 58 64 64 65 65 69 71 81 93 98
4 17 31 37 40 47 48 54 57 58 64 64 65 65 69 71 81 93 98
4 17 22 31 37 40 47 48 54 57 58 64 64 65 65 69 71 81 93 98
4 17 22 31 37 40 45 47 48 54 57 58 64 64 65 65 69 71 81 93 98
4 17 22 31 37 40 45 47 48 54 57 58 62 64 64 65 65 69 71 81 93 98
4 17 22 31 37 40 45 47 48 54 57 58 62 64 64 65 65 69 71 81 93 98 99
4 17 22 31 37 40 45 47 47 48 54 57 58 62 64 64 65 65 69 71 81 93 98 99
4 17 18 22 31 37 40 45 47 47 48 54 57 58 62 64 64 65 65 69 71 81 93 98 99
4 17 18 22 31 37 40 45 47 47 48 54 57 58 62 64 64 65 65 69 71 81 86 93 98 99
4 17 18 22 31 37 40 45 47 47 48 54 57 58 62 64 64 65 65 67 69 71 81 86 93 98 99
4 17 18 22 31 37 40 45 47 47 48 54 57 58 62 64 64 65 65 67 69 71 81 86 93 98 99 99
4 17 18 22 31 37 40 45 47 47 48 54 57 58 62 64 64 65 65 67 68 69 71 81 86 93 98 99 99
4 17 18 22 27 31 37 40 45 47 47 48 54 57 58 62 64 64 65 65 67 68 69 71 81 86 93 98 99 99
18 27 22 17 45 40 37 47 48 54 47 31 4 62 64 64 58 68 67 65 69 65 57 86 93 81 99 99 98 71
18 27 22 17 45 40 37 47 48 54 47 31 4 62 64 64 58 68 67 65 69 65 57 86 93 81 99 99 98 71
Discussion
Since you used interleaved declarations and statement, you're using at least C99 so I've used <stdbool.h> and bool type. This code compiles cleanly, at least when compiled with the options (Mac OS X 10.11.4, GCC 5.3.0):
$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
> -Wold-style-definition -Werror nr-post.c -o nr-post
$
The code runs cleanly under valgrind (3.12.0-SVN).
The first lines of output are printed in-order as the tree is built up (from 30 integers from the range 0..99 generated at random). This allows me to see that the tree is built correctly from the ground up. The last two lines of output are first from printPostOrderRecursive(), a simple recursive implementation of post-order printing, and then from (my mild adaptation of your) printPostOrderIterative().
Without your stack implementation available, I have to guess that you have a problem somewhere in there. With a straight-forward implementation of a stack as shown (where the top is an index into the array of node pointers), your code is fine. We can't tell whether you have compilation warnings you're ignoring.
Hmmm, reviewing my code, I see it doesn't check that top() returns a non-null pointer. It's tempting to add an assertion, and a run-time error rather than returning null. There are plenty of other assertions that could be added — non-null stack pointers passed to the stack functions, in particular.

Resources