thắc mắc về câu lệnh return
Đề bài: Viết chương trình nhập giá trị cho cây nhị phân, theo quy tắc từ trái sang phải, từ trên xuống dưới.
VD: Nhập theo thứ tự: 1, 2, 3 ,4, 5, 6, 7, 8, 9. Thì cây sẽ như sau:
---------------1
-------2-------------3
—4------5-----6------7
8----9
(cái ‘-’ là thay cho dấu ’ ’ ạ ghi ’ ’ nó cứ bị kéo về lề :/)
Code của em như sau: (chỉ cần đọc hàm main(), Node *nhap(Node *Root, int x, int STT), Node *timVT(Node *Root, int STT)
thôi ạ. case 2 là prettyprint để kiểm tra kết qủa đúng rồi ạ)
À quên mất, ý tưởng của em như sau:
Theo cách nhập, lúc nào mình cũng sẽ có được 1 cây nhị phân hoàn chỉnh (lệch trái nhất có thể). Theo tính chất của cây nhị phân hoàn chỉnh, con trái của nút thứ i sẽ là i2, con phải là i2+1. Vì thế trong hàm main() em sẽ truyền vào số thứ tự (STT). Em lấy số thứ tự đấy chia 2 liên tiếp, lưu kết qủa vào 1 mảng, ví dụ muốn nhập vào nút thứ 9 thì sẽ có mảng = {9, 4, 2, 1}. Em lấy phần tử 2, 2%2 == 0 nên từ gốc em lần sang trái, lấy tiếp phần tử 4 trong mảng =>đi sang con trái của 2=>4 sẽ là parent của nút ccần chèn. Xét STT, nếu lẻ thì em chèn phải, chắn thì chèn trái vào nút đó.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEPTH 20
#define be_rong 3 //muon sua be rong %xd thi sua o nhung cho nay
typedef struct Node
{
int key;
struct Node *Left;
struct Node *Right;
}Node;
int depth(Node *Ptr);
void print_gach_thang(Node *Ptr, int i, int sau);
void printf_gach_ngang(Node *Ptr, int i, int sau, int LR);
void print_1_nut(Node *Ptr, int i, int sau);
void pretty(Node *Ptr, int i, int nut1Muc[], int sau, int LR);
void prettyPrint(Node *Root);
Node *timVT(Node *Root, int STT);
Node *nhap(Node *Root, int x, int STT);
Node *timVT(Node *Root, int STT)
{
Node *Now = Root;
int way[10], n = 0, i = 0;
while(STT != 0)
{
way[n] = STT;
n++;
STT /= 2;
}
//printf("n: %d", n);
//printf(" array: ");
//for(i = 0; i<n; i++)
//{
// printf("%d ", way[i]);
//}
//printf("
");
n -= 2;
while(n > 0)
{
if(way[n] % 2 == 0)
{
// printf(" LOOP n: %d, se sang (%d)
", n, Now->Left->key);
Now = Now->Left;
}
else
{
// printf(" LOOP n: %d, se sang (%d)
", n, Now->Right->key);
Now = Now->Right;
}
n--;
}
//printf(" RETURN(%d)
", Now->key);
return Now;
}
Node *nhap(Node *Root, int x, int STT)
{
Node *New = (Node *)malloc(sizeof(Node));
New->key = x;
New->Left = NULL;
New->Right = NULL;
if(Root == NULL)
{
return New;
}
else
{
// printf(" Root hien tai: %p(%d)
", Root, Root->key);//1
Node *Ptr = timVT(Root, STT);
if(STT % 2 == 0)
{
Ptr->Left = New;
}
else
{
Ptr->Right = New;
}
printf(" Root hien tai: %p(%d)
", Root, Root->key);//2
}
// return Root;//neu them dong nay thi chuong trinh chay dung//3
}
main()
{
int luaChon, x, STT = 1;
Node *Root = NULL;
while(1)
{
printf("
1) nhap
");
printf(" 2) in
");
printf(" 3) thoat
");
printf(" -: ");
scanf("%d", &luaChon);
while(getchar() != '
');
if(luaChon == 3) exit(1);
switch(luaChon)
{
case 1:
while(1)
{
printf("
Bat dau qua trinh nhap nut thu %d
", STT);
printf("Nhap x: ");
scanf("%d", &x);
while(getchar() != '
');
if(x == 999) break;
Root = nhap(Root, x, STT);
STT++;
}
break;
case 2:
prettyPrint(Root);
break;
}
}
}
int depth(Node *Ptr)
{
int d = 1;
if(Ptr == NULL)
{
return 0;
}
else
{
int l = depth(Ptr->Left);
int r = depth(Ptr->Right);
if(l > r)
{
return d+l;
}
else
{
return d+r;
}
}
}
void prettyPrint(Node *Root)
{
int sau, i, j;
FILE *taptin;
FILE *taptin1;
FILE *taptin2;
FILE *taptin3;
int nut1Muc[DEPTH]={};
char str[1000];
long VT;
sau = depth(Root);
if(sau <= 5)
{
taptin3 = fopen("so.txt", "w+");//xoa het du lieu trong file
taptin1 = fopen("gach_thang.txt", "w+");//xoa het du lieu trong file
taptin2 = fopen("gach_ngang.txt", "w+");//xoa het du lieu trong file
for(i=0; i<500; i++)
{
fprintf(taptin2, "
");
}
fclose(taptin2);
for(i=0; i<500; i++)
{
fprintf(taptin1, "
");
}
fclose(taptin1);
for(i=0; i<500; i++)
{
fprintf(taptin3, "
");
}
fclose(taptin3);
pretty(Root, 1, nut1Muc, sau, 2);
taptin3 = fopen("so.txt", "r+");
taptin1 = fopen("gach_thang.txt", "r+");
taptin2 = fopen("gach_ngang.txt", "r+");
fgets(str, 999, taptin2);//khong lay dong dau cua tap tin 2
taptin = fopen("output.txt", "w+");
for(i=0; i <= (sau-1)*4; i++)//tong hop 3 file
{
if(i%4 == 0)
{
fgets(str, 999, taptin3);
fprintf(taptin, "%s", str);
}
else if(i%4 == 1)
{
fgets(str, 999, taptin1);
fprintf(taptin, "%s", str);
}
else if(i%4 == 3)
{
VT = ftell(taptin1);
fgets(str, 999, taptin1);
fprintf(taptin, "%s", str);
rewind(taptin1);
fseek(taptin1, VT, SEEK_CUR);
}
else if(i%2 == 0)
{
fgets(str, 999, taptin2);
fprintf(taptin, "%s", str);
}
}
rewind(taptin);
while(fgets(str, 999, taptin) != NULL && strcmp(str, "
") != 0)
{
printf("%s", str);
}
fclose(taptin);
remove("so.txt");
remove("gach_thang.txt");
remove("gach_ngang.txt");
remove("tmp.txt");
}
else
{
printf("Xin loi! Chi pretty print duoc nhung cay co depth <= 5
");
}
}
void print_gach_thang(Node *Ptr, int i, int sau)
{
FILE *taptin = fopen("gach_thang.txt", "r+");
FILE *tmp = fopen("tmp.txt", "w+");
if(taptin != NULL)
{
int a = 0;
char c;
char str[1000];
int j, k, space = 0;
long VT;
for(a=1; a <= i; a++)
{
fgets(str, 9999, taptin);//muon sua be rong %xd thi sua o nhung cho nay
}
fseek(taptin, -1, SEEK_CUR);
if(strcmp(str, "
") == 0)//thut dau dong
{
space = 0;
for(j = sau; j > i; j--)
{
space = (space*2)+1;
}
for(k=0; k < be_rong; k++)
{
for(j=0; j<space; j++)
{
fprintf(taptin, " ");
}
}
}
fseek(taptin, 1, SEEK_CUR);
VT = ftell(taptin);
while(fgets(str, 9999, taptin) != NULL)//muon sua be rong %xd thi sua o nhung cho nay
{
fprintf(tmp, "%s", str);
}
rewind(taptin);
fseek(taptin, VT, SEEK_CUR);
fseek(taptin, -1, SEEK_CUR);
if(Ptr == NULL)
{
for(k=0; k < be_rong; k++)
{
fprintf(taptin, " ");
}
}
else
{
fprintf(taptin, " |");//muon sua be rong %xd thi sua o nhung cho nay
}
VT = ftell(taptin);
space = 1;//in khoang cach den phan tu tiep theo
for(j = i; j < sau; j++)
{
space = (space*2)+1;
}
if(i <= sau)
{
for(k=0; k < be_rong; k++)
{
for(j = 0; j<space; j++)
{
fprintf(taptin, " ");
}
}
}
fprintf(taptin, "
");
rewind(tmp);
while(fgets(str, 9999, tmp) != NULL)//muon sua be rong %xd thi sua o nhung cho nay
{
fprintf(taptin, "%s", str);
}
fclose(taptin);
fclose(tmp);
}
else
{
printf("Qua trinh mo file gap loi
");
}
}
void printf_gach_ngang(Node *Ptr, int i, int sau, int LR)//giong ham print_1_nut o duoi, chi khac "%3d" thanh "---" va neu la con trai thi in "-" thay vi " "
{
FILE *taptin = fopen("gach_ngang.txt", "r+");
FILE *tmp = fopen("tmp.txt", "w+");
if(taptin != NULL)
{
int a = 0;
char c;
char str[1000];
char str1[1000];
int j, k, space = 0;
long VT;
for(a=1; a <= i; a++)
{
fgets(str, 9999, taptin);//muon sua be rong %xd thi sua o nhung cho nay
}
fseek(taptin, -1, SEEK_CUR);
if(strcmp(str, "
") == 0)//thut dau dong
{
space = 0;
for(j = sau; j > i; j--)
{
space = (space*2)+1;
}
for(k=0; k < be_rong; k++)
{
for(j=0; j<space; j++)
{
fprintf(taptin, " ");
}
}
}
fseek(taptin, 1, SEEK_CUR);
VT = ftell(taptin);
while(fgets(str1, 9999, taptin) != NULL)//muon sua be rong %xd thi sua o nhung cho nay
{
fprintf(tmp, "%s", str1);
}
rewind(taptin);
fseek(taptin, VT, SEEK_CUR);
fseek(taptin, -1, SEEK_CUR);
if(strcmp(str, "
") != 0)
{
space = 1;//in khoang cach den phan tu tiep theo
for(j = i; j < sau; j++)
{
space = (space*2)+1;
}
space = space/2;
if(i <= sau)
{
for(k=0; k < be_rong; k++)
{
for(j = 0; j<space; j++)
{
if(LR == 2 && Ptr != NULL)//con phai
{
fprintf(taptin, "-");
}
else
{
fprintf(taptin, " ");
}
}
}
}
}
if(Ptr != NULL)
{
if(LR == 1)//con trai
{
fprintf(taptin, " -");//muon sua be rong %xd thi sua o nhung cho nay
}
else
{
fprintf(taptin, "---");//muon sua be rong %xd thi sua o nhung cho nay
}
}
else
{
fprintf(taptin, " ");//muon sua be rong %xd thi sua o nhung cho nay
}
space = 1;//in khoang cach den phan tu tiep theo
for(j = i; j < sau; j++)
{
space = (space*2)+1;
}
space = space/2+1;
if(i <= sau)
{
for(k=0; k < be_rong; k++)
{
for(j = 0; j<space; j++)
{
if(LR == 1 && Ptr != NULL)//con trai
{
fprintf(taptin, "-");
}
else
{
fprintf(taptin, " ");
}
}
}
}
fprintf(taptin, "
");
rewind(tmp);
while(fgets(str, 9999, tmp) != NULL)//muon sua be rong %xd thi sua o nhung cho nay
{
fprintf(taptin, "%s", str);
}
fclose(taptin);
fclose(tmp);
}
else
{
printf("Qua trinh mo file gap loi
");
}
}
void print_1_nut(Node *Ptr, int i, int sau)
{
FILE *taptin = fopen("so.txt", "r+");
FILE *tmp = fopen("tmp.txt", "w+");
if(taptin != NULL)
{
int a = 0;
char c;
char str[1000];
int j, k, space = 0;
long VT;
for(a=1; a <= i; a++)
{
fgets(str, 9999, taptin);//muon sua be rong %xd thi sua o nhung cho nay
}
fseek(taptin, -1, SEEK_CUR);
if(strcmp(str, "
") == 0)//thut dau dong
{
space = 0;
for(j = sau; j > i; j--)
{
space = (space*2)+1;
}
for(k=0; k < be_rong; k++)
{
for(j=0; j<space; j++)
{
fprintf(taptin, " ");
}
}
}
fseek(taptin, 1, SEEK_CUR);
VT = ftell(taptin);
while(fgets(str, 9999, taptin) != NULL)//muon sua be rong %xd thi sua o nhung cho nay
{
fprintf(tmp, "%s", str);
}
rewind(taptin);
fseek(taptin, VT, SEEK_CUR);
fseek(taptin, -1, SEEK_CUR);
if(Ptr == NULL)
{
for(k=0; k < be_rong; k++)
{
fprintf(taptin, " ");
}
}
else
{
fprintf(taptin, "%3d", Ptr->key);//muon sua be rong %xd thi sua o nhung cho nay
}
VT = ftell(taptin);
space = 1;//in khoang cach den phan tu tiep theo
for(j = i; j < sau; j++)
{
space = (space*2)+1;
}
if(i <= sau)
{
for(k=0; k < be_rong; k++)
{
for(j = 0; j<space; j++)
{
fprintf(taptin, " ");
}
}
}
fprintf(taptin, "
");
rewind(tmp);
while(fgets(str, 9999, tmp) != NULL)//muon sua be rong %xd thi sua o nhung cho nay
{
fprintf(taptin, "%s", str);
}
fclose(taptin);
fclose(tmp);
}
else
{
printf("Qua trinh mo file gap loi
");
}
}
void pretty(Node *Ptr, int i, int nut1Muc[], int sau, int LR)
{
int soNut1Hang = 0;
print_1_nut(Ptr, i, sau);
print_gach_thang(Ptr, i, sau);
printf_gach_ngang(Ptr, i, sau, LR);
if(i < sau)
{
if(Ptr != NULL)
{
pretty(Ptr->Left, i+1, nut1Muc,sau, 1);
pretty(Ptr->Right, i+1, nut1Muc, sau, 2);
}
else
{
pretty(NULL, i+1, nut1Muc,sau, 1);
pretty(NULL, i+1, nut1Muc, sau, 2);
}
}
}
Câu hỏi 1: Nếu thêm return Root;
vào cuối hàm Node *nhap(Node *Root, int x, int STT)
thì chương trình sẽ chaỵ đúng. Còn nếu bỏ đi thì sẽ sai, khi đó nó sẽ thay đổi được gía trị của Root mặc dù em không return. Tại sao lại nó lại thay đổi được Root ạ?
Câu hỏi 2: Nếu cũng bỏ return Root;
, thêm printf(" Root hien tai: %p(%d)
", Root, Root->key);
vào đầu else (trong hàm nhập, em đánh số 1 ấy ạ) thì nó sẽ chạy được đến 7 (nhập lần lượt từ 1 đến 7). Còn nếu thêm vào cuối else (trong hàm nhập, em đánh số 2 ấy ạ) thì nó chỉ chạy được đến 3 (nhập lần lượt từ 1 đến 3) thôi Tại sao cùng trong else, không thay đổi Root mà hàm Printf lại gây ra lỗi được ạ?