Не изменяется глобальная переменная при выходе из функции - C (СИ)
Формулировка задачи:
Здравствуйте, никак не могу понять, почему глобальная переменная-счетчик меняется в функции Create(вижу в конструкторе), но во время рекурсии все изменения исчезают.Пробовала передавать с помощью указателей в функцию, но такой же эффект. Я приведу весь код программы:
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#include <alloc.h>
#include <math.h>
#define ESC 27
#define TRUE 1
#define FALSE 0
typedef struct TREE *pTREE;
typedef struct TREE //Tree - звено дерева
{
int x; //x - вершины дерева
int bal; //показатель баланса (0,1,-1)
pTREE L,R; //Адресные поля. Адрес левой части и Адрес правой части (от left,right)
} tree;
pTREE Create_T(tree *T,int *mas,long i,long *Count)//создание случайного дерева поиска
{ int growth;
long count;
tree *T1=0, *T2=0;
count=*Count;
if (!T) {
T= (tree*)malloc(sizeof(tree));//выделение памяти под корень дерева
T->x=mas[i];
T->L=0;
T->R=0;
T->bal=0; // Вершине присвоили нулевой баланс.
growth=TRUE;
}
else if (mas[i]<(T->x)) //Если вновь вводимый элемент mas[i] меньше чем элемент x из вершины дерева, создаем левую ветвь
{
T->L=Create_T(T->L,mas,i,&count); //рекурсивно помещаем элемент в новую ветку дерева
if (growth==1) // выросла левая ветвь
switch (T->bal)
{
case 1: T->bal=0; growth=FALSE; break; // Предыдущая несбалансированность уравновесилась.
case 0: T->bal=-1; break; // Вес "склонился" влево.
case -1: //баланс нарушился и дерево необходимо перестраивать
T1 = T->L;
if (T1->bal==-1) //Однократный LL-поворот.
{
++count;
T->L=T1->R;
T1->R=T;
T->bal=0;
T=T1;
}
else //Двукратный LR-поворот.
{
++count;
T2 = T1->R;
T1->R = T2->L;
T2->L = T1;
T->L = T2->R;
T2->R = T;
//Пересчет баланса вершины с указателем T.
if (T2->bal==-1) T->bal = 1;
else T->bal = 0;
// Пересчет баланса вершины с указателем T1.
if (T2->bal==1)
T1->bal = -1;
else
T1->bal = 0;
T = T2;
}
T->bal = 0;
growth = FALSE;
break;
}
}
// иначе выросла правая дуга.
else if ((mas[i]>(T->x)))//Если вновь вводимый элемент mas[i] больше, чем элемент x из вершины дерева, создаем правую ветвь
{
T->R=Create_T(T->R,mas,i,&count); //рекурсивно помещаем элемент в новую ветку дерева
if (growth==1) // Если высота поддерева увеличилась, то выросла правая дуга.
switch (T->bal)
{
case -1: T->bal = 0; growth = FALSE; break;
case 0: T->bal = 1;break;
case 1: //баланс нарушился и дерево необходимо перестраивать
T1 = T->R;
if (T1->bal==1)
{ //Однократный RR-поворот.
++count;
T->R = T1->L;
T1->L = T;
T->bal = 0;
T = T1;
}
else
{ //Двухкратный RL-поворот.
++count;
T2 = T1->L;
T1->L = T2->R;
T2->R = T1;
T->R = T2->L;
T2->L = T;
// Пересчет баланса вершины с указателем p.
if (T2->bal==1)
T->bal = -1;
else
T->bal = 0;
//Пересчет баланса вершины с указателем p1.
if (T2->bal==-1)
T1->bal = 1;
else T1->bal = 0;
T = T2;
}
T->bal = 0;
growth = FALSE;
break;
}
}
return T;
}
int Sum_L (tree *T, int L) //средняя длинна пути до вершины. L: уровень вершины
{
if (!T)
return 0;
else
return (L+Sum_L(T->L,L+1)+Sum_L(T->R,L+1));
}
int size (tree *T) //вычисление размера дерева
{
if (!T)
return 0;
else
return (1+size(T->L)+size(T->R));
}
int main()
{
long i=0, n=0,//количество вершин в дереве
count=0;//количество поворотов при баллансировке
int *mas; //массив случайных чисел
tree *T=NULL; //инициализация указателя на АВЛ дерево
char key;
float H_av=0.0;
do
{
n=0;
count=0;
H_av=0.0;
T=NULL;
randomize();
clrscr ();
fflush(stdin);
printf("\n Construction of ABL tree.\n ");
printf("\n Enter the number of vertex: n= ");
scanf("%d",&n);
if (n==0){
printf("\n Error ! The number of vertex is NULL!");
getch();
exit(0);
}
mas=(int*)malloc(n*sizeof (int)); //выделение памяти под массив вершин
if (mas==NULL){
puts("Err 1! The array is not created!");
getch();
exit(0);
}
mas[0]=4;
mas[1]=5;
mas[2]=7;
mas[3]=2;
mas[4]=1;
mas[5]=3;
mas[6]=6;
/*for (i=0; i<n; i++){ //заполнение массива случайными числами
mas[i]=random(100);
} */
for (i = 0; i < n; i++) {
T=Create_T(T,mas,i,&count); //создание случайного АВЛ дерева
}
if (T==NULL){
printf ("\n Err 4. Fault create of ABL tree! \n");
getch();
exit(0);
}
H_av=Sum_L(T,1)/size(T); //средняя высота дерева
printf("\n The average height of the tree %1.0f \n ", H_av);
printf("\n The count of rotatin is %d \n ", count);
free(T);
for (i = 0; i < n; i++) {
free(mas);
}
puts ("\n\n Repeat the program with other number of vertices? (No=Esc)");
key=getch();
}
while (key!=ESC);
return 0;
}Решение задачи: «Не изменяется глобальная переменная при выходе из функции»
textual
Листинг программы
++(*Count); //... T->L=Create_T(T->L,mas,i,Count);
Объяснение кода листинга программы
Count- глобальная переменная, которая увеличивается на 1.T- структура данных, в которой хранится информация о списке.L- поле структурыT, которое содержит указатель на первый элемент списка.Create_T- функция, которая создает новый элемент списка и добавляет его в список.mas- массив, в котором хранятся данные элементов списка.i- индекс элемента списка, который добавляется.Count- глобальная переменная, которая передается в функциюCreate_Tи используется для отслеживания количества элементов в списке.