ALGORITMIZACE 2010/03 STROMY, BINÁRNÍ STROMY VZTAH STROMŮ A REKURZE ZÁSOBNÍK IMPLEMENTUJE REKURZI PROHLEDÁVÁNÍ S NÁVRATEM (BACKTRACK)

Podobné dokumenty
ALGORITMIZACE 2010/03 STROMY, BINÁRNÍ STROMY VZTAH STROMŮ A REKURZE ZÁSOBNÍK IMPLEMENTUJE REKURZI PROHLEDÁVÁNÍ S NÁVRATEM (BACKTRACK)

Stromy. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta a kol.

Stromy. Strom: souvislý graf bez kružnic využití: počítačová grafika seznam objektů efektivní vyhledávání výpočetní stromy rozhodovací stromy

Stromy. Příklady. Rekurzivní datové struktury. Základní pojmy

ALG 04. Zásobník Fronta Operace Enqueue, Dequeue, Front, Empty... Cyklická implementace fronty. Průchod stromem do šířky

Základy algoritmizace c2005, 2007 Michal Krátký, Jiří Dvorský1/39

5 Rekurze a zásobník. Rekurzivní volání metody

Rekurzivní algoritmy

Algoritmy a datové struktury

Volné stromy. Úvod do programování. Kořenové stromy a seřazené stromy. Volné stromy

BINARY SEARCH TREE

Rozptylování, stromy - zákl. vlastnosti

BINARY SEARCH TREE

Programování v C++ 1, 16. cvičení

Dynamické datové struktury II.

Datové struktury obsah přednášky 1. Úvod 2. Třídy Type-wrapper (obalový typ) pro primitivní typy automatické převody 3. Automatické převody mezi

Rekurze a zásobník. Jak se vypočítá rekurzivní program? volání metody. vyšší adresy. main(){... fa(); //push ret1... } ret1

RECURSION

Pokud zadání nerozumíte nebo se vám zdá nejednoznačné, zeptejte se. Pište čitelně, nečitelná řešení nebudeme uznávat.

R zné algoritmy mají r znou složitost

Datové struktury obsah přednášky 1. Úvod 2. Třídy Type-wrapper (obalový typ) pro primitivní typy automatické převody 3. Automatické převody mezi

Dynamické programování. Optimální binární vyhledávací strom

Pokud zadání nerozumíte nebo se vám zdá nejednoznačné, zeptejte se. Pište čitelně, nečitelná řešení nebudeme uznávat.

Stromy, haldy, prioritní fronty

součet cvičení celkem. známka. Úloha č.: max. bodů: skut. bodů:

Základní datové struktury III: Stromy, haldy

Stromy. Jan Kybic.

Reprezentace aritmetického výrazu - binární strom reprezentující aritmetický výraz

Dynamické struktury a Abstraktní Datový Typy (ADT)

Část 1 Spojové struktury (stromy) Dynamické struktury a Abstraktní Datový Typy (ADT) Část 2 Abstraktní datový typ. Část 3 Příklad ADT Prioritní fronta

Programování 3. hodina. RNDr. Jan Lánský, Ph.D. Katedra informatiky a matematiky Fakulta ekonomických studií Vysoká škola finanční a správní 2015

bfs, dfs, fronta, zásobník, prioritní fronta, halda

2 Datové struktury. Pole Seznam Zásobník Fronty FIFO Haldy a prioritní fronty Stromy Hash tabulky Slovníky

bfs, dfs, fronta, zásobník, prioritní fronta, halda

prohled av an ı graf u Karel Hor ak, Petr Ryˇsav y 16. bˇrezna 2016 Katedra poˇ c ıtaˇ c u, FEL, ˇ CVUT

pak celou úlohu. ani Jako obvykle je static int M, N; [] key, L, R; NIL = -1; cost; roota, rootb; throws IOExceptio // tree roots on { static void

Abstraktní datové typy

STACK

Abstraktní datové typy: zásobník

2. Mřížky / Záplavové vyplňování

Dynamické datové struktury IV.

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Dynamic programming. Optimal binary search tree

Dynamické programování

Programování v C++ 2, 4. cvičení

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

A4B33ALG 2010/05 ALG 07. Selection sort (Select sort) Insertion sort (Insert sort) Bubble sort deprecated. Quicksort.

Stromy. Jan Faigl. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze. Přednáška 10 B0B36PRP Procedurální programování

Reprezentace dat v informačních systémech. Jaroslav Šmarda

Datové struktury. alg12 1

PŘETĚŽOVÁNÍ OPERÁTORŮ

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Dynamické datové struktury I.

Konstruktory a destruktory

Dynamické datové struktury III.

Algoritmizace prostorových úloh

Spojové struktury. Spojová struktura (linked structure):

Stromy. Jan Faigl. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze. Přednáška 10 B0B36PRP Procedurální programování

Stromy. Jan Hnilica Počítačové modelování 14

DSA, První krok: máme dokázat, že pro left = right vrátí volání f(array, elem, left, right)

Implementace LL(1) překladů

Část 2 Příklad načítání grafu, kompilace a projekt s více soubory. Část 3 Zadání 9. domácího úkolu (HW09)

Dynamicky vázané metody. Pozdní vazba, virtuální metody

Datové struktury Úvod

Hledání k-tého nejmenšího prvku

Binární vyhledávací stromy II

Red Black strom (Red Black Tree) Úvod do programování. Rotace. Red Black strom. Rotace. Rotace

TGH07 - Chytré stromové datové struktury

Algoritmizace prostorových úloh

ALG 14. Vícedimenzionální data. Řazení vícedimenzionálních dat. Experimentální porovnání řadících algoritmů na vícedimenzionálních datech

Fronta (Queue) Úvod do programování. Fronta implementace. Fronta implementace pomocí pole 1/4. Fronta implementace pomocí pole 3/4

Lineární datové struktury

Protože pi každém volání funkce ff se zavolá funkce abc() práv jednou, je poet volání funkce abc() práv 7. Platí varianta d).

Pokud zadání nerozumíte nebo se vám zdá nejednoznačné, zeptejte se. Pište čitelně, nečitelná řešení nebudeme uznávat.

TGH07 - Chytré stromové datové struktury

Základní datové struktury

Správa paměti. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta, 2016

Jméno:... St. Sk.:. Cvičící:.. Bodů ze cv.: (Tučná čísla indikují počet neuspěvších (z 50) v jednotlivých otázkách) 1.

STACK

1. Převeďte dané číslo do dvojkové, osmičkové a šestnáctkové soustavy: a) b)

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Zdůvodněte, proč funkce n lg(n) roste alespoň stejně rychle nebo rychleji než než funkce lg(n!). Symbolem lg značíme logaritmus o základu 2.

Implementace binárního stromu směrníky

ALG 09. Radix sort (přihrádkové řazení) Counting sort. Přehled asymptotických rychlostí jednotlivých řazení. Ilustrační experiment řazení

Kolekce, cyklus foreach

Úvod do programovacích jazyků (Java)

IB108 Sada 1, Příklad 1 Vypracovali: Tomáš Krajča (255676), Martin Milata (256615)

Programování v C++ 2, 7. cvičení

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

STROMY A KOSTRY. Doc. RNDr. Josef Kolář, CSc. Katedra teoretické informatiky, FIT České vysoké učení technické v Praze. BI-GRA, LS 2010/2011, Lekce 6

Zadání k 2. programovacímu testu

DobSort. Úvod do programování. DobSort Implementace 1/3. DobSort Implementace 2/3. DobSort - Příklad. DobSort Implementace 3/3

Algoritmizace a programování

bin arn ı vyhled av an ı a bst Karel Hor ak, Petr Ryˇsav y 23. bˇrezna 2016 Katedra poˇ c ıtaˇ c u, FEL, ˇ CVUT

bfs, dfs, fronta, zásobník

Seznamy a iterátory. Kolekce obecně. Rozhraní kolekce. Procházení kolekcí

Programovanie v jazyku C stromy

6. Tahy / Kostry / Nejkratší cesty

VYSOKÉ UČENÍ TECHNICKÉ V BRNĚ

Select sort: krok 1: krok 2: krok 3: atd. celkem porovnání. výběr nejmenšího klíče z n prvků vyžaduje 1 porovnání

Transkript:

ALGORITMIZACE 2010/03 STROMY, BINÁRNÍ STROMY VZTAH STROMŮ A REKURZE ZÁSOBNÍK IMPLEMENTUJE REKURZI PROHLEDÁVÁNÍ S NÁVRATEM (BACKTRACK) Strom / tree uzel, vrchol / node, vertex hrana / edge vnitřní uzel / internal node list / leaf (pl. leaves) 1

Příklady stromů A4B33ALG 2010 b) c) d) e) a) Vlastnosti stromů 1. Strom je souvislý, tj. mezi každými dvěma jeho uzly vede cesta. 2. Mezi každými dvěma uzly ve stromu vede jen jediná cesta. 3. Po odstranění libovolné hrany se strom rozpadá na dvě části. 4. Počet hran ve stromu je vždy o 1 menší než počet uzlů. 2

Kořenový strom / rooted tree A4B33ALG 2010 h k j g m i a l b R n f c d e Kořen / root m a k l h j i g R b n e c d f Názvosloví j i Předchůdce, rodič / predecessor, parent Následník, potomek / successor, child 3

Hloubka / depth R 0 a b c 1 m j i n d 2 k l h e f 3 g Hloubka uzlu / node depth 4 4 Hloubka stromu / tree depth 4

Binární (kořenový!!) strom / binary (rooted!!) tree Počet potomků každého uzlu je 0,1, nebo 2. Levý a pravý podstrom / left and right subtree x Podstrom uzlu x... levý... pravý 5

Pravidelný binární strom / regular binary tree Počet potomků každého uzlu je jen 0 nebo 2. Vyvážený strom / balanced tree Hloubky všech listů jsou (víceméně) stejné. 6

Hloubka vyváženého (binárního a pravidelného!) stromu hloubka 0 1 2 3 4 A4B33ALG 2010 uzlů 1 2 4 8 16 k 2 k 2 k+1-1 (2 (hloubka vyváženého stromu)+1 1) ~ uzlů hloubka vyváženého stromu ~ log 2 (uzlů+1) 1 ~ log 2 (uzlů) 7

Implementace binárního stromu -- C Strom Uzel Reprezentace uzlu left key right 73501 9968 497 typedef struct node { int key; struct node *left; struct node *right; } NODE; 8

Implementace binárního stromu -- Java Strom 6084 Uzel 335 22107 public class Node { public Node left; public Node right; public int key; public Node(int k) { key = k; left = null; right = null; } } public class Tree { public Node root; public Tree() { root = null; } } 9

Vybudování náhodného binárního stromu -- C NODE *randtree(int depth) { NODE *pnode; if ((depth <= 0) (random(10) > 7)) return (NULL); //stop recursion pnode = (NODE *) malloc(sizeof(node)); // create node if (pnode == NULL) { printf("%s", "No memory."); return NULL; } pnode->left = randtree(depth-1); // make left subtree pnode->key = random(100); // some value pnode->right = randtree(depth-1); // make right subtree return pnode; // all done } Příklad volání funkce NODE *root; root = randtree(4); Poznámka. Volání random(n) vrací náhodné celé číslo od 0 do n-1. Zde neimplementováno. 10

Vybudování náhodného binárního stromu -- Java public Node randtree(int depth) { Node node; if ((depth <= 0) ((int) Math.random()*10 > 7)) return null; // create node with a key value node = new Node((int)(Math.random()*100)); } node.left = randtree(depth-1); // create left subtree node.right = randtree(depth-1); // create right subtree return node; // all done Příklad volání funkce Node root; root = randtree(4); 11

Náhodný binární strom 13 39 83 84 58 28 98 71 5 Reprezentace stromu 13 39 83 84 58 28 98 71 5 12

Průchod (binárním) stromem v pořadí Inorder 13 Strom 84 39 58 83 28 98 71 5 Průchod stromem v pořadí INORDER void listinorder( NODE *ptr) { if (ptr == NULL) return; listinorder(ptr->left); printf("%d ", ptr->key); listinorder(ptr->right); } Výstup 98 84 71 39 13 58 5 83 28 13

Pohyb ve stromu v průchodu Inorder Okamžik tisku Směr pohybu listinorder(ptr->left); printf("%d ", ptr->key); listinorder(ptr->right); A B C D E F G H I J K L M N O Výstup H D I B J E K A L F M C N G O 14

Průchod (binárním) stromem v pořadí Preorder 13 Strom 84 39 58 83 28 98 71 5 Průchod stromem v pořadí PREORDER void listpreorder( NODE *ptr) { if (ptr == NULL) return; printf("%d ", ptr->key); listpreorder(ptr->left); listpreorder(ptr->right); } Výstup 13 39 84 98 71 83 58 5 28 15

Pohyb ve stromu v průchodu Preorder Okamžik tisku Směr pohybu printf("%d ", ptr->key); listpreorder(ptr->left); listpreorder(ptr->right); A B C D E F G H I J K L M N O Výstup A B D H I E J K C F L M G N O 16

Průchod (binárním) stromem v pořadí Postorder 13 Strom 84 39 58 83 28 98 71 5 Průchod stromem v pořadí POSTORDER void listpostorder( NODE *ptr) { if (ptr == NULL) return; listpostorder(ptr->left); listpostorder(ptr->right); printf("%d ", ptr->key); } Výstup 98 71 84 39 5 58 28 83 13 17

Pohyb ve stromu v průchodu Postorder Okamžik tisku Směr pohybu listpostorder(ptr->left); listpostorder(ptr->right); printf("%d ", ptr->key); A B C D E F G H I J K L M N O Výstup H I D J K E B L M F N O G C A 18

Velikost stromu (= počet uzlů) rekurzivně Strom nebo podstrom 9 Příklad 13 4 4 3 39 2 83 1 m uzlů n uzlů 1 84 1 98 71 58 1 5 28 celkem... m+n+1 uzlů int count(node *ptr) { if (ptr == NULL) return (0); return (count(ptr->left) + count(ptr->right)+1); } 19

Hloubka stromu (= max hloubka uzlu) rekurzivně Strom nebo podstrom 0 Příklad 1 84 0 98 71 39 3 13 2 2 1 58 0 5 83 0 28 m n max(m,n)+1 int depth(node *ptr) { if (ptr == NULL) return (-1); return ( max(depth(ptr->left), depth(ptr->right) )+1 ); } 20

Jednoduchý příklad rekurze Binární pravítko Rysky pravítka Délky rysek Kód vypíše délky rysek pravítka 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 void ruler(int val) { if (val < 1) return; } ruler(val-1); print(val); ruler(val-1); Call: ruler(4); Domácí úkol: Ternárně!: 21

Binární pravítko vs. průchod inorder Jednoduchý příklad rekurze void ruler(int val) { if (val < 1) return; } Pravítko ruler(val-1); print(val); ruler(val-1); } Inorder kód vypisující délky rysek pravítka void listinorder( NODE *ptr) { if (ptr == NULL) return; listinorder(ptr->left); printf("%d ", ptr->key); listinorder(ptr->right); Strukturní podobnost, shoda! Výstup pravítka 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 22

Jednoduchý příklad rekurze Činnost binárního pravítka ruler(2); print(3); ruler(2); ruler(3); print(4); ruler(3); 4 if (val < 1) return; ruler(val-1); print(val); ruler(val-1); Start 3 3 Kód 2 2 2 2 1 1 1 1 1 1 1 1 ruler(1); print(2); ruler(1); ruler(0); print(1); ruler(0); return; 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 23

Binární pravítko bez rekurze Zásobník implementuje rekurzi Detail stromu rekurze Uzel A navštíven 1x Uzel A navštíven 0x 1 A 1 2 0 2 0 3 Postup výpočtu Strom rekurze 4 3 3 2 2 2 2 1 1 1 1 1 1 1 1 1 2 1 1 2 2 2 Uzel A navštíven 2x 24

Zásobník implementuje rekurzi Standardní strategie Při používání zásobníku: Je-li to možné, zpracovávej jen data ze zásobníku. Standardní postup Ulož první uzel (první zpracovávaný prvek) do zásobníku. Každý další uzel (zpracovávaný prvek) ulož také na zásobník. Zpracovávej vždy pouze uzel na vrcholu zásobníku. Když jsi s uzlem (prvkem) hotov, ze zásobníku ho odstraň. Skonči, když je zásobník prázdný. 25

Zásobník implementuje rekurzi Každý záběr v následující sekvenci předvádí situaci PŘED zpracováním uzlu. Aktuální pozice Start: Vstup do kořene 4 Zásobník hodnota návštěv 4 0 push(4,0) 3 2 2 1 1 1 1 Výstup 26

Zásobník implementuje rekurzi Průchod stromem rekurze Zásobník Opouštíme 4 a blížíme se k 3 3 4 hodnota návštěv 4 1 3 0 push(3,0) 2 2 1 1 1 1 Výstup 27

Zásobník implementuje rekurzi Průchod stromem rekurze Opouštíme 3 a blížíme se k 2 3 2 2 4 Zásobník hodnota návštěv 4 1 3 1 2 0 push(2,0) 1 1 1 1 Výstup 28

Zásobník implementuje rekurzi Průchod stromem rekurze Zásobník hodnota návštěv 4 4 1 Opouštíme 2 a blížíme 3 se k 1 2 2 1 1 1 1 3 1 2 1 1 0 push(1,0) Výstup 29

Zásobník implementuje rekurzi Průchod stromem rekurze Zásobník hodnota návštěv 4 4 1 Opouštíme 1 a blížíme 3 se k 0 2 2 1 1 1 1 3 1 2 1 1 1 0 0 push(0,0) Výstup 30

Zásobník implementuje rekurzi Průchod stromem rekurze Zásobník hodnota návštěv 4 4 1 Opouštíme 0 a blížíme 3 se k 1 2 2 1 1 1 1 3 1 2 1 1 1 0 0 pop() Výstup 31

Zásobník implementuje rekurzi Průchod stromem rekurze Zásobník hodnota návštěv 4 4 1 Opouštíme 1 a blížíme 3 se k 0 2 2 1 1 1 1 3 1 2 1 1 2 0 0 push(0,0) 1 Výstup 32

Zásobník implementuje rekurzi Průchod stromem rekurze Zásobník hodnota návštěv 4 4 1 Opouštíme 0 a blížíme 3 se k 1 2 2 1 1 1 1 3 1 2 1 1 2 0 0 pop() 1 Výstup 33

Zásobník implementuje rekurzi Průchod stromem rekurze Zásobník hodnota návštěv 4 4 1 Opouštíme 1 a blížíme 3 se k 2 2 2 1 1 1 1 3 1 2 1 1 2 pop() 1 Výstup 34

Zásobník implementuje rekurzi Průchod stromem rekurze Zásobník hodnota návštěv 4 4 1 Opouštíme 2 a blížíme 3 se k 1 2 2 3 2 1 2 push(1,0) 1 1 1 1 1 0 1 2 Výstup atd 35

po chvíli Zásobník implementuje rekurzi Průchod stromem rekurze Zásobník hodnota návštěv Opouštíme 2 a blížíme se k 3 3 4 4 1 3 1 2 2 2 2 pop() 1 1 1 1 1 2 1 Výstup 36

Zásobník implementuje rekurzi Průchod stromem rekurze Zásobník hodnota návštěv Opouštíme 3 a blížíme se k 2 3 2 2 4 4 1 3 2 2 0 push(2,0) 1 1 1 1 1 2 1 3 Výstup atd 37

a je hotovo Zásobník implementuje rekurzi Průchod stromem rekurze 4 Zásobník hodnota návštěv 4 2 (empty == true) pop() 3 2 1 1 1 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 Výstup 38

Rekurzivní pravítko bez rekurzivního volání Pseudokód (skoro kód :-)) pro objektový přístup A4B33ALG 2010 Zásobník implementuje rekurzi stack.init(); stack.top.value = N; stack.top.visits = 0; while (!stack.empty()) { if (stack.top.value == 0) stack.pop(); if (stack.top.visits == 0) { stack.top.visits++; stack.push(stack.top.value-1,0); } if (stack.top.visits == 1) { print(stack.top.value); stack.top.visits++; stack.push(stack.top.value-1,0); } if (stack.top.visits == 2) stack.pop(); } 39

Rekurzivní pravítko bez rekurzivního volání, jednoduchá implementace polem A4B33ALG 2010 Zásobník implementuje rekurzi int stackval[10]; int stackvis[10]; void ruler2(int N) { int SP = 0; // stack pointer stackval[sp] = N; stackvis[sp] = 0; // init while (SP >= 0) { // while unempty if (stackval[sp] == 0) SP--; // pop: in leaf if (stackvis[sp] == 0) { // first visit stackvis[sp]++; SP++; stackval[sp] = stackval[sp-1]-1; // go left stackvis[sp] = 0; } } } if (stackvis[sp] == 1) { // second visit printf("%d ", stackval[sp]); // process the node stackvis[sp]++; SP++; stackval[sp] = stackval[sp-1]-1; // go right stackvis[sp] = 0; } if (stackvis[sp] == 2) SP--; // pop: node done 40

Rekurzivní pravítko bez rekurzivního volání, jednoduchá implementace polem A4B33ALG 2010 Zásobník implementuje rekurzi Poněkud kompaktnější kód int stackval[10]; int stackvis[10]; void ruler2(int N) { int SP = 0; // stack pointer stackval[sp] = N; stackvis[sp] = 0; // init while (SP >= 0) { // while unempty if (stackval[sp] == 0) SP--; // pop: in leaf if (stackvis[sp] == 2) SP--; // pop: node done if (stackvis[sp] == 1) // if second visit printf("%d ", stackval[sp]); // process the node stackvis[sp]++; SP++; // otherwise stackval[sp] = stackval[sp-1]-1; // go deeper stackvis[sp] = 0; } } 41

Snadné prohledávání s návratem (Backtrack) Problém osmi dam na šachovnici Některá řešení 0 1 2 3 4 5 6 7 column 0 column 1 2 3 4 5 6 7 0 4 1 6 2 1 3 3 4 7 5 0 6 2 7 5 0 1 2 3 4 5 6 7 0 4 7 5 2 6 1 3 row row Jediná datová struktura: pole queencol[ ] (viz kód) 42

Snadné prohledávání s návratem (Backtrack) Strom testovaných pozic (kořen a několik potomků) Kam lze položit dámu 43

Snadné prohledávání s návratem (Backtrack) Strom testovaných pozic (výřez) 44

Snadné prohledávání s návratem (Backtrack) Strom testovaných pozic (výřez) Stop! 45

Snadné prohledávání s návratem (Backtrack) N dam na šachovnici N x N N poč. dam Počet Počet testovaných pozic dámy řešení Hrubá síla (N N ) Backtrack Zrychlení 4 2 256 240 5 10 3 125 1 100 6 4 46 656 5 364 7 40 823 543 25 088 8 92 16 777 216 125 760 9 352 387 420 489 651 402 10 724 10 000 000 000 3 481 500 11 2 680 285 311 670 611 19 873 766 12 14 200 8 916 100 448 256 121 246 416 1.07 2.84 8.70 32.83 133.41 594.75 2 872.33 14 356.20 73 537.00 Tab 3.1 Rychlosti řešení problému osmi dam 46

Snadné prohledávání s návratem, 8 dam (Backtrack) boolean positionok(int r, int c) { // r: row, c: column for (int i = 0; i < r; i++) if ((queencol[i] == c) // same column or (abs(r-i) == abs(queencol[i]-c))) // same diagonal return false; return true; } void putqueen(int row, int col) { queencol[row] = col; // put a queen there if (++row == N) // if solved print(queencol); // output solution else for(col = 0; col < N; col++) // test all columns if (positionok(row, col)) // if free putqueen(row, col); // next row recursion } Call: for(int col = 0; col < 8; col++) putqueen(0, col); 47