PDA

Tam Sürümünü Görmek İçin : binary treede insert


jit
15/01/2008, 20:22
struct TreeNode {
// An object of type TreeNode represents one node
// in a binary tree of strings.

string item; // The data in this node.
TreeNode left; // Pointer to left subtree.
TreeNode right; // Pointer to right subtree.

TreeNode(string str) {
// Constructor. Make a node containing str.
item = str;
left = NULL;
right = NULL;
}

}; // end struct Treenode

TreeNode *root; // Pointer to the root node in the tree.
root = NULL; // Start with an empty tree.

void treeInsert(TreeNode *&root, string newItem) {
// Add the item to the binary sort tree to which the parameter
// "root" refers. Note that root is passed by reference since
// its value can change in the case where the tree is empty.
if ( root == NULL ) {
// The tree is empty. Set root to point to a new node containing
// the new item. This becomes the only node in the tree.
root = new TreeNode( newItem );
// NOTE: The left and right subtrees of root
// are automatically set to NULL by the constructor.
// This is important!
return;
}
else if ( newItem < root->item ) {
treeInsert( root->left, newItem );
}
else {
treeInsert( root->right, newItem );
}
} // end treeInsert()



nette gezerken şöyle bir classa rastladım. fakat parametredeki pointerın adresini yollama olayını tam olarak anlamadım.anlatırsanız sevinirim.


acehreli
15/01/2008, 22:26
Diger konuda da yazdigim gibi, '&' karakterinin anlami, "fonksiyonu cagirdigim yerdeki nesnenin takma adidir". Bu ornek, fonksiyonun cagrildigi yerdeki bir nesneden bahsetmenin iki degisik yolunu gosteriyor:

#include <iostream>

void referans_ile(int & i)
{
i = 42;
}

void isaretci_ile(int * p)
{
*p = 7;
}

void goster(const char * baslik, const int & sayi)
{
std::cout << baslik << ": " << sayi << '\n';
}

int main()
{
int sayi = 0;
goster("baslangicta ", sayi);

referans_ile(sayi);
goster("referans ile", sayi);

isaretci_ile(&sayi);
goster("isaretci ile", sayi);
}

C'de yalnizca isaretci kullanilabilir...

Ali

jit
15/01/2008, 22:39
benim burda sormak istediğim şu.verdiğim örnekte pointerın adresi yerine pointerın kendisini gönderseydi ne gibi bir sorunla karşılaşabilirdi.

jit
15/01/2008, 23:11
misal burda da anlamadığım bir şey var. her zaman aklıma takılan bir şey burda da karşıma çıktı umarım şimdi anlarım.

referans_ile fonksiyonu parametre olarak ne alıyor? bir int değerinin adresini alıyor.peki siz mainden ne gönderiyorsunuz

int sayi=0;
referans_ile(sayi);

yani bir int değeri gönderiyorsunuz.yani fonksiyon parametre olarak bir int değerinin adresini beklerken siz int değerinin ta kendisini gönderiyorsunuz.neden burda bir sorun çıkarmıyor.

benim dediğime göre olması gereken bu fakat sorun çıkartıyor burada.

referans_ile(&sayi);
goster("referans ile", sayi);

hata ise bu:
referans_ile' : cannot convert parameter 1 from 'int *' to 'int &'

yanlış anlamayın kod doğru. ben sadece bir şeyleri sorgulayarak öğrenmeye çalışıyorum.

quasimodo
15/01/2008, 23:14
oradaki adres operatoru normal kullanim anlaminda degil. Sadece diyorsun ki fonksiyon sana gonderecegim degiskenin ta kendisini al takma ad olarakta bunu kullan.

jit
15/01/2008, 23:19
oradaki adres operatoru normal kullanim anlaminda degil.


evet fonksiyonun işleyişine bakarsak senin dediğin doğru ama syntaxına bakınca algılayamıyorum olayı

normal kullanım anlamından kasıt ne. yani nasıl anlayacağım & operatörünü gördüğüm zaman ne anlamda kullanıldığını. benim bildiğim & operatörü bir objenin bir değişkenin adresi demektir. yani ben hiç takma adıdır vs olarak öğrenmedim. ağlayacağım neredeyse (:

quasimodo
15/01/2008, 23:27
int sayi = 2;

//sayi artik her yerde degeri 2 dir dimi?
int & takma = sayi;
//bak bu satirdan itibaren takmayi degistirdiginde aslinda sayi
//degismis olacak
takma = 13;
cout << sayi;

jit
15/01/2008, 23:39
int sayi = 2;

//sayi artik her yerde degeri 2 dir dimi?
int & takma = sayi;
//bak bu satirdan itibaren takmayi degistirdiginde aslinda sayi
//degismis olacak
takma = 13;
cout << sayi;

yani buradaki & operatörü adres değil diyorsun ama buradaki

int *p = &sayi;
cout << *p;

& operatörü adres bildiriyor diyorsun. doğru mu anladım

quasimodo
15/01/2008, 23:45
Evet :)

jit
15/01/2008, 23:50
fazla soru sordum farkındayım ama binary tree classındaki treeInsert fonksiyonunda neden sadece pointerı değil de pointerın takmasını yolluyor. ordaki amacını anlayamadım. yukardaki fonksiyon gerçekten çok hoş bir fonksiyon.

quasimodo
15/01/2008, 23:54
Bence bi farki yok ama onuda @acehreli anlatsin artik lutfen :D

jit
16/01/2008, 00:12
heh he :) anladığım kadarıyla orda binary tree yapısını koruyabilmek için öyle bir şey yapıyor. yine de emin değilim acehreli gelince anlatır umarım

acehreli
16/01/2008, 00:23
referans_ile fonksiyonu parametre olarak ne alıyor? bir int değerinin adresini alıyor.

Yukaridaki yanlis anlamani duzeltmen gerekiyor. "Bir int degerinin adresini aliyor" olsaydi, soyle yazardik:

void isaretci_ile(int * i);

Ama oyle degil. :)

Ali

acehreli
16/01/2008, 00:46
jit, isaretci yerine onun takma adini yollamasinin nedeni, fonksiyonun cagrildigi yerdeki bir isaretciyi degistirmek icin.

Eger isaretci yollasaydi, fonksiyon icindeki isaretci, fonksiyonun cagrildigi yerdeki isaretcinin bir *kopyasi* olurdu. Fonksiyonun cagrildigi yerdeki isaretci degil, onun kopyasi degismis olurdu.

Bu konuyu anlaman icin sana kisa bir program gosteriyorum:

#include <stdio.h>

void degis_tokus(const int * birinci, const int * ikinci)
{
const int * gecici = birinci;
birinci = ikinci;
ikinci = gecici;
}

int main()
{
const int i1 = 1;
const int i2 = 2;

const int * p1 = &i1;
const int * p2 = &i2;

printf("once : %d %d\n", *p1, *p2);

degis_tokus(p1, p2);

printf("sonra: %d %d\n", *p1, *p2);
printf("Yanlis calisti! :( Ben 2 1 yazmasini istiyordum ama\n");
printf("hAlA baslangictaki int'lere isaret ediyorlar...\n");
}


degis_tokus fonksiyonundan dOndUkten sonra p1'in i2'yi, p2'nin de i1'i gostermesini istiyorum. (Dikkat: i1 ve i2'nin degerlerini degistirmek istemiyorum (zaten onun icin 'const' yapmisim), p1 ve p2'nin neyi gosterdiklerini degistirmeye calisiyorum.) Ama program yanlis calisiyor. Duzeltebilir misin? Duzelttigin zaman konuyu anlayacaksin. :)

Ali

jit
16/01/2008, 01:18
fonksiyonu bu şekilde değiştireceğiz.

void degis_tokus(const int * &birinci, const int * &ikinci)
{
const int * gecici = birinci;
birinci = ikinci;
ikinci = gecici;
}

deneme yanılma değil valla ilk seferde yaptım. :kuul:

çok sağolun valla.bu incelikler kafayı çok ağrıtıyor. en azından benim kafamı çok ağrıtıyor:)

misal ben & i programlarımda kullanırım ama bilinçsiz olarak kullandığımı anladım şimdi.yani programım çalışırdı ama işte deneme yanılma şeklinde. "aa bu niye segmataion fault verdi.dur bakalım önüne & koyalım düzelir belki" şeklindeydi. bilinçli olarak yapmak elbette daha güzel olacaktır. tekrar teşekkürler.

acehreli
16/01/2008, 01:30
Guzel! :) C'de '&' (referans) olmadigi icin soyle olmasi gerekirdi:


void degis_tokus(const int ** birinci, const int ** ikinci)
{
/* ... */
}


Tabii icini ve cagrildigi yeri de degistirmek gerekirdi...

Ali

jit
16/01/2008, 01:38
evet aynen.

http://forum.ceviz.net/showpost.php?p=349755&postcount=10

burda da çok güzel anlatmıştın o hadiseyi :)

jit
16/01/2008, 02:15
madem konu açıldı o zaman c ile olanını da yazalım. pointer manyağı oldum valla gece gece :)


#include <stdio.h>

void degis_tokus(const int ** birinci, const int ** ikinci)
{
const int *gecici = *birinci;
*birinci = *ikinci;
*ikinci= gecici;
}

int main()
{
const int i1 = 1;
const int i2 = 2;

const int *p1 = &i1;
const int *p2 = &i2;

printf("once : %d %d\n", *p1, *p2);

degis_tokus(&p1, &p2);

printf("sonra: %d %d\n", *p1, *p2);
}