PDA

Tam Sürümünü Görmek İçin : ikili ağaca eleman eklemede problem


dreamscöpçe
08/01/2008, 16:45
merhaba arkadaşlar yazdığım programda derlediğimde herhangi bir hata yok fakat turbu c de adım adım çalıştırdığımda şunu gördüm: insert fonksiyonuna girdiğinde ilk eklenecek eleman için ilk if deyiminin çalışması doğru fakat daha sonraki eklemelerde onun çalışmaması gerekirken tekrar onu çalıştırıyo ve hiç bir zaman ikinci if deyimine geçmiyor burada 2. if deyimi dediğim else ten sonrası yani ağacın boştan farklı olma durumu.bu da rootptr hiç bir zaman nulldan farklı olmuyor anlamına geliyor. ve hatayı nasıl düzeltmem gerektiğini bulamadım. yardım ederseniz çok sevinirim:) başta yaptığım tanımlamaları da veriyorum..

typedef struct binarytree{int data;
struct binarytree *left;
struct binarytree *right;
}tree;
void insertnode(tree *rootptr,int value);
void inorder(tree *rootptr);

void main()
{
char cev;
tree *root;
root=NULL;

do
{ printf("tamsayi bir deger giriniz");
scanf("%d",&num);
insertnode(root,num);
printf("any data?? y for yes, n for no\n");
cev=getch();
}while(char(cev)!='n');

printf("\n\n the inorder traversal is:\n");
inorder(root);
}/*end main*/

void insertnode(tree *rootptr,int value)
{

/*if tree is empty*/
if(rootptr==NULL)
{
rootptr=(tree*)malloc(sizeof(tree));
/*if memory was allocated then assign data*/
if(rootptr!=NULL)
{
rootptr->data=value;
rootptr->left=NULL;
rootptr->right=NULL;
rootptr=(tree*)malloc(sizeof(tree));
}/*endif*/
else /*if rootptr==NULL*/

printf("%d not inserted.No memory available.\n",value);

return;
}/*endif*/
else
{
/*tree is not empty*/
/*data to insert is less than data in current node*/
if (value<rootptr->data)
{
insertnode(rootptr->left,value);
}/*endif*/

/*data to insert greater than data in current node*/
else if (value>rootptr->data)
{
insertnode(rootptr->right,value);
}/*end elseif*/

else
{
/*duplicate data value ignored*/
printf("dup");
}/*end else*/
}/*end else*/
}/*end function insertnode*/


void inorder(tree *rootptr)
{
/*if(!rootptr) return;*/
/*if tree is not empty then traverse*/
if(rootptr!=NULL)
{ inorder(rootptr->left);
printf("%3d",rootptr->data);
inorder(rootptr->right);
}/*endif*/
}/*end function inorder*/


acehreli
08/01/2008, 19:16
Cok yapilan bir hatayi tekrarliyorsun: C'de parametreler fonksiyonlara kopyalanarak gonderilirler.

rootptr=(tree*)malloc(sizeof(tree));

dediginde degisen, insertnode'un yerel parametresi olan rootptr. O rootptr,

insertnode(root,num);

dedigin yerdeki root'un bir kopyasi; root degil... O root'un degismesi icin onu adresiyle gondermen gerekir:

insertnode(&root, num);

Tabii onun calismasi icin de insertnode'da bir kac degisiklik gerekiyor:


/* Isaretci isaretcisi alacak */
void insertnode(tree ** rootptr,int value)
{

/* Icindeki butun rootptr'lar (*rootptr) ile degistirilecek */
*rootptr=(tree*)malloc(sizeof(tree));
}


Ali

choldax
08/01/2008, 19:35
else yerine 2. if'i else if diye yap. çünkü compiler if ve else'i bir bütün olarak alır ve kodun kalanına bakmaz :)

dreamscöpçe
08/01/2008, 20:27
teşekkürler önerileriniz için ikisini de yaptım dediklerinizin hata vermio fakat çalışırken insert içinde iken aşağıda gördüğünüz koyu renkli yazılanlardan birine girdiğinde sürekli giriş yapıyor.yani sonsuz defa insertnode(&((*rootptr)->left),value); yapıyor. çok moralim bozuldu 3 gündür bunla uğraşıorum ya:aglama:


else if((*rootptr)!=NULL)
{
/*tree is not empty*/
/*data to insert is less than data in current node*/
if (value<(*rootptr)->data)
{
insertnode(&((*rootptr)->left),value);
}/*endif*/

/*data to insert greater than data in current node*/
else if (value>(*rootptr)->data)
{
insertnode(&((*rootptr)->right),value);
}/*end elseif*/

else
{
/*duplicate data value ignored*/
printf("dup");
}/*end else*/
}/*end else if*/

choldax
08/01/2008, 20:34
insertnode(&rootptr->left,value) şeklinde dene

acehreli
08/01/2008, 21:03
Moralini bozma; sonuca cok yakinsin. :) Surada fazladan yaptigin malloc, daha onceki butun emegini siliyor:


(*rootptr)->data=value;
(*rootptr)->left=NULL;
(*rootptr)->right=NULL;
(*rootptr)=(tree*)malloc(sizeof(tree));


Cunku rootptr'a yepyeni bir yeri gosteriyorsun. O son satiri kaldirirsan calisacak.

Ali

c++
13/01/2008, 13:59
arkadaşlar bu dosyaların uzantısı varmı varsa ne olcak ?
hacking@intikam.org

acehreli
13/01/2008, 19:47
Geleneksel olarak .c uzantisi kullanilir. deneme.c gibi...

Ali

jit
15/01/2008, 19:42
/* Isaretci isaretcisi alacak */
void insertnode(tree ** rootptr,int value)
{

/* Icindeki butun rootptr'lar (*rootptr) ile degistirilecek */
*rootptr=(tree*)malloc(sizeof(tree));
}
evet haklısın orda sürekli rootptra yeni bir değer atadığı için null olmuyor ve sürekli aynı ife giriyor.benim başka bir sorum var.

yukardaki kodda methodu declare ederken böyle yazmışsın.

void insertnode(tree ** rootptr,int value)

şu şekilde olması gerekmiyor mu?

void insertnode(tree* &rootptr,int value)

yoksa ikisi de aynı şey mi.benim dediğimde pointerın adresini yolluyoruz.senin dediğinde pointerın pointerını yolluyoruz. yani pointerın pointerı bir adres değil de bir değer ihtiva eder.aslında değer değil de point ettiği şeyin adresini ihtiva eder dolayısıyla da değer ihtiva etmiş gibi olur.

acehreli
15/01/2008, 22:20
Bu kodun C++ oldugunu dusundurecek hicbir sey gormedigim icin, C'de

void insertnode(tree* &rootptr,int value);

yazim hatasidir. C++'ta oradaki '&' karakteri, rootptr'in bir referans oldugunu gosterir. Referanlari anlamada bana en yardimi olan aciklama "referans, varolan bir nesnenin takma adidir" olmustu.

Dolayisiyla, yukaridaki bildirim C++'ta 'rootptr'in, insertnode'un cagrildigi yerdeki bir nesneyi ifade eden bir takma ad olarak dusunulur. rootptr'da yapilan degisiklik, o nesneyi degistirir.

C'de referans olmadigi icin isaretciler kullanilir. Isaretcinin degerini, isaret ettigi nesnenin adresi olarak dusunebiliriz. Oyle dusununce

tree t = /* ... */;
tree * p = &t;
tree ** pp = &p;

Nasil p t'nin adresini tutuyorsa, pp de p'nin adresini tutuyor. Baska karisik bir sey yok... Yani sonucta *pp deyince p, *p deyince de t anlasiliyor.

Ali