Ëåêöèÿ 13


Ðåêóðñèÿ


Çàäà÷à 1. Íàéòè ôàêòîðèàë öåëîãî ÷èñëà (èñõîäíûé òåêñò)


#define MAX_COUNT 1000


/* int counter = 0; */

...

fact(N);

...


int fact(int N) {

static int counter = 0;


if (++counter > MAX_COUNT) {

printf(“Call stack overflow\n”);

exit(-1);

}

if (N <= 1)

return N;

else

return N * fact(N-1);

}


Ðåêóðñèÿ íåáåçîïàñíà, òàê êàê íà êàæäûé âûçîâ ôóíêöèè òðàòèòñÿ ìåñòî â ñòåêå âûçîâîâ ôóíêöèé è ìîæåò ïðîèçîéòè âûõîä çà ãðàíèöó ñåãìåíòà ïàìÿòè (Segmentation Fault).


Ñòåê âûçîâà ôóíêöèé:


fact(1)

fact(2)

fact(3) - ...

fact(4) – frame 2

fact(5) – frame 1

main() - frame 0


Íà êàæäîì ñëîå ñîäåðæèòñÿ èíôîðìàöèÿ î ïàðàìåòðàõ âûçîâà ôóíêöèè, çíà÷åíèÿ ëîêàëüíûõ ïåðåìåííûõ è àäðåñ âîçâðàòà.

Êîãäà ìåñòî â ñòåêå çàêîí÷èòñÿ, òî âñÿ èíôîðìàöèÿ áóäåò ïèñàòüñÿ ìèìî ñòåêà è ïîâåäåíèå ïðîãðàììû ñòàíåò íåêîððåêòíûì.


GDBêîìàíäû:

btïîêàçàòü ñòåê âûçîâîâ ôóíêöèé

frame <íîìåð óðîâíÿ â ñòåêå âûçîâîâ> - ïåðåéòè íà çàäàííûé óðîâåíü â ñòåêå âûçîâîâ ôóíêöèé


Èãðà â 15. - êâàäðàò 4*4, êâàäðàòèêè 1-15, 16-ÿ êëåòêà ñâîáîäíà. Íàäî äâèãàòü êâàäðàòèêè òàê, ÷òîáû îíè ñòàëè óïîðÿäî÷åíû.

Ïðåìèÿ çà ðåøåíèå ñëåäóþùåé ïîçèöèè:

1 2 3 4

5 6 7 8

9 10 11 12

13 15 14


Ðåøàòü ïðîãðàììíî:

3*3 – ðåêóðñèÿ ðàáîòàëà

4*4 — ðåêóðñèÿ íå ðàáîòàëà :-)


Çàäà÷à ïðî îáõîä øàõìàòíîé äîñêè êîäîì êîíÿ.


28

19



6






5




7


18

27

20






21

4






8


17

26

3


9



25

22





13

10

16


2

23

14

11



1

24

15





12


1) Çàïîëíèòü âñþ òàáëèöó ÷èñëîì 0

2) Ðåàëèçîâàòü ôóíêöèþ «ñëåäóþùèé õîä» - èñêàòü âñå âîçìîæíûå õîäû (ìàêñèìóì 8), ïî î÷åðåäè (â öèêëå) ïèñàòü â ñîîòâåòñòâóþùóþ êëåòêó ñëåäóþùåå ÷èñëî è âûçûâàòü ñàìó ñåáÿ, ïîñëå âûçîâà ïðîâåðÿòü, çàêîí÷åí ëè ïóòü, è åñëè íåò, òî çàòèðàòü çàïèñàííîå ÷èñëî íóëåì.


Äåðåâî îáõîäà:

|

| |

| | | | | | | | | | | |



Ñïèðàëü Óëàìà (ïðîñòûå ÷èñëà îòìåòèòü çâåçäî÷êàìè):

7 8 9 10

6 1 2 11

5 4 3 12

14 13


Ðàáîòà ñ ìàññèâàìè


Çàäà÷à 2. Ñëèòü äâà îòñîðòèðîâàííûõ ìàññèâà (èñõîäíûé òåêñò)


void merge(double *a, int na, double *b, int nb, double *c) {

int i = 0, j = 0, k, nc = na + nb;

for (k = 0; k < nc; k++) {

if ((i < na) && ((j >= nb) || (a[i] < b[j]))) {

c[k] = a[i++];

} else {

c[k] = b[j++];

}

}

}


Çàìå÷àíèå. Äëÿ îïåðàöèé ++ è – ñóùåñòâóåò äâà âàðèàíòà èõ èñïîëüçîâàíèÿ: ïðåôèêñíûé è ïîñòôèêñíûé.

Îò ìåñòà ðàñïîëîæåíèÿ ýòîé îïåðàöèè çàâèñèò ïîðÿäîê åå âûïîëíåíèÿ.

Íàïðèìåð, åñëè ++ ðàñïîëîæåí ïåðåä ïåðåìåííîé, òî ñíà÷àëà ïðîèñõîäèò óâåëè÷åíèå åå çíà÷åíèÿ, à ïîòîì óæå — âû÷èñëåíèå çíà÷åíèÿ âûðàæåíèÿ.

Åñëè ++ ðàñïîëîæåí ïîñëå ïåðåìåííîé, òî ñíà÷àëà ïðîòñõîäèò âû÷èñëåíèå çíà÷åíèÿ âûðàæåíèÿ, à ïîòîì óæå - óâåëè÷åíèå åå çíà÷åíèÿ.


Çàäà÷à 3. Îòñîðòèðîâàòü ìàññèâ ïðè ïîìîùè ôóíêöèè merge() (ðåêóðñèâíîå ñëèÿíèå) (èñõîäíûé òåêñò)


Ñ÷èòàåì, ÷òî ôðàãìåíò èç îäíîãî ýëåìåíòà óæå îòñîðòèðîâàí


0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

5

12

-3

8

11

-7

1

9

-1

8’

15

21

-24

6

3

-3


Ñîðòèðóåì êàæäûé ôðàãìåíò, ñîñòîÿùèé èç äâóõ ýëåìåíòîâ:


0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

5

12

-3

8

-7

11

1

9

-1

8’

15

21

-24

6

-3’

3



Ñëèâàåì ïî äâà ôðàãìåíòà â áÎëüøèé ôðàãìåíò, 2 → 4:


0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

-3

5

8

12

-7

1

9

11

-1

8’

15

21

-24

-3’

3

6



Ñëèâàåì ïî äâà ôðàãìåíòà â áÎëüøèé ôðàãìåíò, 48:


0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

-7

-3

1

5

8

9

11

12

-24

-3’

-1

3

6

8’

15

21



Ñëèâàåì ïî äâà ôðàãìåíòà â áÎëüøèé ôðàãìåíò, 816:


0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

-24

-7

-3

-3’

-1

1

3

5

6

8

8’

9

11

12

15

21


Ïîðÿäîê îäèíàêîâûõ ýëåìåíòîâ ïðè òàêîé ñîðòèðîâêå ñîõðàíÿåòñÿ, òàê êàê â ôóíêöèè merge() èç îäèíàêîâûõ ýëåìåíòîâ ñíà÷àëà äîáàâëÿåòñÿ ëåâûé (èç ìàññèâà a).



#include <stdlib.h>

...

void sort(double *a, int n) {

double *b = (double*)malloc(n * sizeof(double));

if (b == NULL) {

exit(-1);

}

copy(a, b, n);

splitMerge(b, 0, n, a);

free(b);

}


/* Write fragment of array b starting from index beg till index end to array a in sorted order */

/* Çàïèñàòü ôðàãìåíò ìàññèâà b [beg, end) â ìàññèâ a â îòñîðòèðîâàííîì âèäå */

void splitMerge(double *b, int beg, int end, double *a) {

int mid;

/* ??? copy(&b[beg], &a[beg], end – beg); */

if ((end - beg) >= 2) {

mid = (beg + end) / 2;

splitMerge(a, beg, mid, b);

splitMerge(a, mid, end, b);

merge(&b[beg], mid - beg, &b[mid], end - mid, &a[beg]);

}

}


/* Copy array A of size N to array B */

void copy(double *A, double *B, int N) {

double *endA = &A[N];

while (A < endA)

*(B++) = *(A++);

}