Jump to content
BulForum.com

Има ли отворени?


sasquatch

Recommended Posts

  • Replies 50
  • Created
  • Last Reply

Ето задачката за която говорех - в двусвързано дърво (всеки възел има указател към своя предшественик и към левия и десния си наследник), по зададени указателите към два възела да се напише функция, която приема като параметри само тези два указателя, и връща указател към общият предшественик на двата възела, към които сочат указателите.

Измислих едно решение, което обаче разчита на това, че всеки възел има поле в което е отбелязана неговата дълбочина в дървото. Това е структурата която използвам за възел от дървото, и самата функция, която след офертата на dinux беше редуцирана около 2.5 пъти като код, супер :) :

struct TreeNode{
TreeNode(){
 this->top = NULL;
 this->left = NULL;
 this->right = NULL;
 this->depth=0;
}
TreeNode(TreeNode * top){
 this->top = top;
 this->left = NULL;
 this->right = NULL;
 this->depth=top->depth + 1;
}
TreeNode * top;
TreeNode * left;
TreeNode * right;
long depth;
};

TreeNode * findTheClosestCommonAncestorDinux(TreeNode * firstNode, TreeNode * secondNode)
{
if(firstNode->depth < secondNode->depth) {
 TreeNode * tmp = firstNode;
 firstNode = secondNode;
 secondNode = tmp;
}
while(firstNode->depth > secondNode->depth) firstNode = firstNode->top;
if(firstNode == secondNode) return firstNode->top;
while(firstNode != secondNode) {
 firstNode = firstNode->top;
 secondNode = secondNode->top;
}
return firstNode;
}

Сега обмислям вариант в който да не използвам дълбочина на възел, записана в него и ако може и функцията да не е рекурсивна.

Link to comment
Share on other sites

Измътих го май, или поне това е първоначален вариант някакъв:)

TreeNode * findTheClosestCommonAncestorV2(TreeNode * firstNode, TreeNode * secondNode)
{
TreeNode * first=firstNode,* second = secondNode;
while(first->top){
 first = first->top;
 if(first == second) return first->top;
}

first = firstNode;
while(second->top){
 second = second->top;
 if(first == second) return first->top;
}	
second = secondNode;
while(first->top){
 first = first->top;
 second = second->top ? second->top : second;
 if(first == second) return first;

 TreeNode * tmp = first;
 
 while(first->top){
	 first = first->top;
	 if(first == second) return first->top;
 }
 first = tmp;
 tmp = second;
 while(second->top){
	 second = second->top;
	 if(first == second) return first->top;
 }
 second = tmp;
}
return NULL;
}

Link to comment
Share on other sites

Ми ся не ми се занимава с задачи ама тук има всички задач, давани на националните състезания през годините. Който има мерак да решава ще се поозори доста.

Link to comment
Share on other sites

  dok said:
Ми ся не ми се занимава с задачи ама тук има всички задач, давани на националните състезания през годините. Който има мерак да решава ще се поозори доста.

В тоя дух, виждали ли сте задачата за разходката на коня?Колкото до горните задачи - изрових цялата книга за алгоритми на Преслав Наков("Програмиране = ++Алгоритми"), и нищо подобно не намерих.

Link to comment
Share on other sites

  xiT said:
Не ми се пише програма, ама на един цикъл става :) xor

Ама няма ли да трябва първо да се сортират и след тва xor ? Или числата които се повтарят са последователни?

Link to comment
Share on other sites

  sasquatch said:
Ама няма ли да трябва първо да се сортират и след тва xor ?

Ne shtoto :

x xor x = 0

x xor y = y xor x

x xor (x xor y) = y

 

Zadachata q reshih ama she q napisha sled 1-2 chasa che sq nqmam vreme

Link to comment
Share on other sites

Аре дай да го видим това решение.

Link to comment
Share on other sites

Eto q funkciqta! Ne sym q kompiliral i moje da ima nqkoq druga greshka, no smqtam che ideqta se vijda. Polzvam dopylnitelno char pole value, inicializirano s 0. Do kolkoto vidqh po-dobro (po vreme) reshenie s tozi tip predstavqne na dyrvoto nqma! Ne mislq che e chak tolkova strashno izpolzvaneto na dopylnitelniq bait (moje da se dokara i do bit s malka modifikaciq), kato se ima predvit kak se obyrzqva algorityma (do slojnost O(n) (n e raztoqnieto, na koito otstoi po-dalechniq element ot tyrseniq node))!

[B]EDIT:[/B]Mahnah pyrva versiq shot tyi i tyi ne bachka!

Versiq 2:) (dano da raboti)

TreeNode * findTheClosestCommonAncestorV2(TreeNode * firstNode, TreeNode * secondNode)
{
   TreeNode * first=firstNode,* second = secondNode;

   //temp->top = NULL;

   while (first || second)
   {     if (first != NULL)
         {  if (++(first->value) == 2) return first;
            first = first->top ? first->top : NULL;
         }
         if (second != NULL)
         {  if (++(second->value) == 2) return second;
            second = second->top ? second->top : NULL;
         }
   }
   return NULL;
}

 

Vijte i kajete, ako sym sgafil nqkade :bgrin: !

Link to comment
Share on other sites

А това решение за коя задача беше?За дърветата ли?

Link to comment
Share on other sites

  JDFU said:

Не става нещо, тествам го в случая когато двата възела са на макс дълбочина функцията гърми на тоя ред:

temp->top = NULL;

temp не е инициализиран да сочи към нищо :)

Имам в предвид този случай:

tree.gif

Обратните връзки не съм ги правил, считам че чертата покзва права и обратна връзка.

Link to comment
Share on other sites

  sasquatch said:
Не става нещо, тествам го в случая когато двата възела са на макс дълбочина  функцията гърми на тоя ред:

temp->top = NULL;

temp не е инициализиран да сочи към нищо :)

huu de, a kato go inicializirash stana li ne razbrah ili trqbva da opravq neshto po cikyla?

 

EDIT: razbrah za koi sluchai! misylta mi e dali problemite bqha 2 (temp-a i gyrmeneto)

Link to comment
Share on other sites

  JDFU said:
huu de, a kato go inicializirash stana li ne razbrah ili trqbva da opravq neshto po cikyla?

 

EDIT: razbrah za koi sluchai! misylta mi e dali problemite bqha 2 (temp-a i gyrmeneto)

Ами не мога да схвана идеята нещо, накъде трябва да сочи тоя temp?

Link to comment
Share on other sites

  sasquatch said:
Ами не мога да схвана идеята нещо, накъде трябва да сочи тоя temp?

Gotoo, Promenih koda! Dano toq pyt da stane. Sega mahnah i temp-a.

 

Temp-a go polzvam prosto kato bufer (s cel da izbegna mnogokratnoto uvelichavane na broqcha na korena) v momenta v koito stigna vyrha!

Link to comment
Share on other sites

Супер, но искам да ти кажа че когато напишеш

 

TreeNode * temp;

 

temp e равно на NULL, на следващия ред се опитваш да направиш следното:

 

temp->top = NULL;

 

т.е. да дадеш стойност на атрибут на обект който го няма, тоя указател temp не е инициализиран да сочи към обект, като се опитваш да access-неш свойството на обекта и гърмиш, защото указателя не сочи обект.

Link to comment
Share on other sites

  sasquatch said:
Супер, но искам да ти кажа че когато напишеш

 

TreeNode * temp;

 

temp e равно на NULL, на следващия ред се опитваш да направиш следното:

 

temp->top = NULL;

 

т.е. да дадеш стойност на атрибут на обект който го няма, тоя указател temp не е инициализиран да сочи към обект, като се опитваш да access-неш свойството на обекта и гърмиш, защото указателя не сочи обект.

znam be prosto v byrzinata go izpusnah :) Inache 2-ra versiq raboti nali?

Link to comment
Share on other sites

Ти под value какво разбираш - дълбочината на възела ли? Ако е така не работи. На мен идеята в моята функция ми беше следната:

 

1. Проверявм дали някой от възлите които са дадени не е наследник на другия. Ако да връщам top на предшественика. Ако не следвва (2).

 

2. Започвам да се изкачвам в дървото, проверявям дали не са съвпаднали възлите, ако да връщам един от тях (значи са били съседни, или са били наследници на тоя в който съм попаднал, и са били на еднаква дълбочина).

Ако не следва (3).

 

3. Проверявам дали след като съм се изкачил 1-о ниво нагоре някой от двата не е наследник на другия, ако е така връщам предшественика (т.е. възлите са били на различна дълбочина, не и не са се наследявали един друг).

Ако не следва (2).

Link to comment
Share on other sites

  sasquatch said:
Ти под value какво разбираш - дълбочината на възела ли? Ако е така не работи.

NE! value mi e po-skoro count, koito broi kolko pyti sym minal prez vyzel. Tyi kato kachvaiki se ot vseki ot dvata vyzela nagore az poseshavam vseki vyzel ednokratno, to v slucheq,v koito veche sym minal za 2-ri pyt value trqbva da mi e 2! Tova che vyrvq stypka po stypka po stypka mi garantira, che pyrvoto sreshtane na 2 e tyrseniq vyzel

Link to comment
Share on other sites

Значи първоначално value е нула за всички възли, ок разбрах :) Сега става наистина бачка, но проблема е да не разчиташ на стойността на възела, не знаеш какво друго има в един възел освен left, right и top.

Ако можеше да се ползва такава информация, тогава се използва дълбочината на възела и има две стъпки:

1. Изравняване на дълбочината на двата възела, проверка дали не са един и същ вече и т.н.

2. Намиране на общия наследник чрез не повече операции от дълбочината на дървото.

Link to comment
Share on other sites

  sasquatch said:
Значи първоначално value е нула за всички възли, ок разбрах :) Сега става наистина бачка, но проблема е да не разчиташ на стойноста на дървото, един вид ти не знаеш какво друго има в един възел освен left, right и top.

Ami az naistina, ne znam nishto drugo. Az moga i da izveda tva value izvyn struct-a na dyrvoto v otdelen, v koito shte pazq pointer kym vyzela za koito stava vypros. Nqma kak da se razminesh bez da pazish dopylnitelna informaciq. V protiven sluchai poluchavash dosta po-losh(po vreme) algoritym!

Link to comment
Share on other sites

  JDFU said:
Ami az naistina, ne znam nishto drugo. Az moga i da izveda tva value izvyn struct-a na dyrvoto v otdelen, v koito shte pazq pointer kym vyzela za koito stava vypros. Nqma kak da se razminesh bez da pazish dopylnitelna informaciq. V protiven sluchai poluchavash dosta po-losh(po vreme) algoritym!

Въпроса е каква ще е тая структура :) Иначе не е лошо като идея.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.


×
×
  • Create New...