{"id":22308229,"url":"https://github.com/levieyal/algorithms-2-course","last_synced_at":"2026-01-05T08:46:20.926Z","repository":{"id":189090034,"uuid":"381918469","full_name":"LeviEyal/Algorithms-2-Course","owner":"LeviEyal","description":"A collection of pseudo-codes of all the algorithms studied in the Algorithms-2 2021 course","archived":false,"fork":false,"pushed_at":"2021-07-04T09:34:33.000Z","size":13,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-18T01:37:42.036Z","etag":null,"topics":["bfs-algorithm","dfs-algorithm","diameter-of-graph","dijkstra-algorithm","dynamic-programming","floyd-warshall-algorithm","huffman-coding-algorithm","minimum-spanning-trees"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LeviEyal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-07-01T05:20:15.000Z","updated_at":"2022-07-06T17:09:21.000Z","dependencies_parsed_at":"2023-08-18T08:26:10.773Z","dependency_job_id":null,"html_url":"https://github.com/LeviEyal/Algorithms-2-Course","commit_stats":null,"previous_names":["levieyal/algorithms-2-course"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LeviEyal%2FAlgorithms-2-Course","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LeviEyal%2FAlgorithms-2-Course/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LeviEyal%2FAlgorithms-2-Course/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LeviEyal%2FAlgorithms-2-Course/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LeviEyal","download_url":"https://codeload.github.com/LeviEyal/Algorithms-2-Course/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245570711,"owners_count":20637213,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bfs-algorithm","dfs-algorithm","diameter-of-graph","dijkstra-algorithm","dynamic-programming","floyd-warshall-algorithm","huffman-coding-algorithm","minimum-spanning-trees"],"created_at":"2024-12-03T20:13:24.390Z","updated_at":"2026-01-05T08:46:20.882Z","avatar_url":"https://github.com/LeviEyal.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv dir='rtl' lang='he'\u003e \n\n\u003ch1 align=\"center\"\u003eפסאודו קודים - קורס אלגוריתמים 2 סמסטר ב' 2021\u003c/h1\u003e\n\n- ## [תוכן עניינים](#------------)\n    - [פלויד וורשאל - Floyd Warshall](#Floyd-Warshall)\n    - [בעיית הבקבוקים](#בעיית-הבקבוקים)\n    - [תת מערך עם סכום תאים מקסימלי](#תת-מערך-עם-סכום-תאים-מקסימלי)\n        - [בעיית תחנות הדלק](#תת-מערך-עם-סכום-תאים-מקסימלי)\n    - [תת מטריצה עם סכום תאים מקסימלי](#תת-מטריצה-עם-סכום-תאים-מקסימלי)\n    - [עץ פורש מינימלי](#עץ-פורש-מינימלי)\n        - [קרוסקל](#עץ-פורש-מינימלי)\n        - [קרוסקל הפוך](#עץ-פורש-מינימלי)\n        - [פרים](#עץ-פורש-מינימלי)\n        - [בורובקה](#עץ-פורש-מינימלי)\n    - [מעבר על גרפים](#מעבר-על-גרפים)\n        - [BFS](#מעבר-על-גרפים)\n        - [DFS](#מעבר-על-גרפים)\n        - [מציאת מספר רכיבי קשירות בגרף](#מעבר-על-גרפים)\n        - [בדיקת קיום מעגל בגרף](#מעבר-על-גרפים)\n        - [בדיקת קיום מעגל אויילר בגרף](#מעבר-על-גרפים)\n        - [מציאת מעגל אויילר בגרף](#מעבר-על-גרפים)\n    - [קוטר ורדיוס בעצים](#קוטר-ורדיוס-בעצים)\n        - [מציאת קוטר, רדיוס ומרכזים של עץ ע\"י אלגוריתם שריפת עלים](#קוטר-ורדיוס-בעצים)\n        - [מציאת קוטר של עץ ע\"י אלגוריתם סריקה לעומק](#קוטר-ורדיוס-בעצים)\n        - [מציאת המסלול של קוטר בעץ ע\"י אלגוריתם סריקה לעומק\n](#קוטר-ורדיוס-בעצים)\n        - [בדיקה האם קודקוד נתון נמצא על קוטר בעץ\n](#קוטר-ורדיוס-בעצים)\n    - [קוד האפמן - Huffman code](#קוד-האפמן)\n        - [בניית עץ](#קוד-האפמן)\n        - [הוצאת הייצוגים הבינאריים של כל תו מהעץ](#קוד-האפמן)\n        - [קוד האפמן - כאשר מערך התוים כבר ממוין](#קוד-האפמן)\n    - [דייקסטרה Dijkstra](#דייקסטרה)\n    - [בניית עץ מרשימת דרגות](#בניית-עץ-מרשימת-דרגות)\n    - [איזומורפיזם של עצים](#איזומורפיזם-של-עצים)\n\n\n# Floyd Warshall\nגרף לא ממושקל: מפעילים כדי לבדוק אם קיים מסלול כלשהו בין קודקוד מסוייים לקודקוד אחר \n* סיבוכיות: `O(n^3)`\n\u003c/div\u003e\n\n```python\nFW-UnWheighted(g[N,N]) :\n    for k=0 to N :\n        for i=0 to N :\n            for j=0 to N :\n           \t\tg[i,j] = g[i,j] || (g[i,k] AND g[k,j])\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n    \nגרף ממושקל - מציאת כל המרחקים הקצרים ביותר בגרף בין כל זוג קודקודים:\n* סיבוכיות: `O(n^3)`\n\u003c/div\u003e\n\n```python\nFW-wheighted(g[N,N]) :\n    for k=0 to N :\n        for i=0 to N :\n            for j=0 to N :\n                if  g[i,j] \u003e g[i,k] + g[k,j] :\n                    g[i,j] = g[i,k] + g[k,j]\n```\n\u003cdiv dir='rtl' lang='he'\u003e\nגרף ממושקל - מציאת כל המסלולים הקצרים ביותר בגרף בין כל זוג קודקודים מיוצגים ע\"י מחרוזות:\n\n* סיבוכיות: `O(n^3)`\n\u003c/div\u003e\n\n```python\nFW-wheighted-paths(g[N,N]) :\n    New empty-string paths[N,N]\n    for i=0 to N :\n        for j=0 to N :\n            paths[i,j] = i + \"-\u003e\" + j\n\n    for k=0 to N :\n        for i=0 to N :\n            for j=0 to N :\n                if  g[i,j] \u003e g[i,k] + g[k,j] :\n                    g[i,j] = g[i,k] + g[k,j]\n                    paths[i,j] = paths[i,k] + \"-\u003e\" + paths[k,j]\n    return paths\n```\n\n\u003cdiv dir='rtl' lang='he'\u003e\n\nגרף לא מכוון - בדיקת קשירות:\n* מספיק להפעיל פלוייד וורשל על הגרף ואז לבדוק את השורה הראשונה. כי אם מהקודקוד הראשון יש מסלול לכולם אז אפשר ישר להגיד שהגרף קשיר \n* סיבוכיות: `O(n^3)`\n\u003c/div\u003e\n\n```python\nisConnected-UnDirected-graphs(g[N,N]) :\n    FW(g)\n    for i=1 to N :\n        if g[0,i] = false :\n            return false\n    return true\n\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\nבדיקת קשירות של גרפים לא מכוונים:\n* סיבוכיות: `O(n^3)`\n\u003c/div\u003e\n\t\n```python\nisConnected-Directed-graphs(g[N,N]) :\n    FW(g)\n    for i=0 to N :\n        if g[0,i] = ∞ :\n            return false\n    return true\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\nבדיקה האם קיים מעגל שלילי בגרף מכוון:\n\n* מספיק להסתכל על האלכסון הראשי אחרי הפעלת `Floyd-Washall` \n* סיבוכיות: `O(n^3)`\n\u003c/div\u003e\n\t\n```python\nHas-Negative-Cycles-Directed(g[N,N]) :\n    FW(g)\n    for i=0 to N :\n        if g[i,i] \u003c 0 :\n            return true\n    return false\n```\n\u003cdiv dir='rtl' lang='he'\u003e\nבדיקה האם קיים מעגל שלילי בגרף לא מכוון:\n\n* אין צורך להפעיל `Floyd-Washall`\n* אם קיימת צלע עם משקל שלילי אז קיים מעגל שלילי בגרף לא מכוון\n* סיבוכיות: `O(n^2)`\n\u003c/div\u003e\n\t\n```python\nHas-Negative-Cycles-UnDirected(g[N,N]) : \n    for i=0 to N :\n        for j=0 to N :\n            if g[i,j] \u003c 0:\n                return true\n    return false\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\nחישוב דרגות קודקודים ממטריצת מרחקים בגרף ממושקל ולא מכוון:\n* סיבוכיות: `O(n^2)`\n\u003c/div\u003e\n\n```python\nDegrees-of-vertices(g[N,N]) :\n    New D[N] = {0,0,..,0}\n    for i=0 to N :\n        for j=0 to N :\n            if i ≠ j AND g[i,j] ≠ ∞:\n                D[i]++\n                D[j]++\n    sort(D)\n    return D\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\nחישוב דרגות קודקודים ממטריצת שכנויות בגרף לא ממושקל ולא מכוון:\n* סיבוכיות: `O(n^2)`\n\u003c/div\u003e\n\n```python\nDegrees-of-vertices(g[N,N]) :\n    New D[N] = {0,0,..,0}\n    for i=0 to N :\n        for j=0 to N :\n            if g[i,j] = true:\n                D[i]++\n                D[j]++\n    sort(D)\n    return D\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\n# בעיית הבקבוקים\n* סיבוכיות: `O(n^3)`\n\u003c/div\u003e\n\n```python\nBottles-Problem(b1, b2) :\n    mat = Bottles-Problem-Create-Matrix(b1, b2)\n    return Bottles-Problem-Get-Paths(mat, max(b1, b2))\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\nשלב ראשון -  בניית מטריצת המעברים ממצב למצב:\n* סיבוכיות: `O(n^2)`\n\u003c/div\u003e\n\n```python\nBottles-Problem-Create-Matrix(b1, b2) :\n    size = (b1+1)*(b2+1)\n    max = max(b1, b2)\n    new mat[size, size]\n\n    for i=0 to b1 :\n        for j=0 to b2 :\n            index = getindex(max, i, j)\n\n            1. mat[index, getIndex(max, 0, j)] = 1\n            2. mat[index, getIndex(max, i, 0)] = 1\n            3. mat[index, getIndex(max, b1, j)] = 1\n            4. mat[index, getIndex(max, i, b2)] = 1\n            5. mat[index, getIndex(max, min(b1, i+j), i+j-min(b1, i+j))] = 1\n            6. mat[index, getIndex(max, i+j-min(b2, i+j) , min(b2, i+j))] = 1\n    return mat\n\ngetIndex(n, i, j) :\n    return (n+1) * i + j\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\nשלב שני - יצירת מטריצת מסלולים ממצב למצב:\n* סיבוכיות: `O(n^2)`\n\u003c/div\u003e\n\n```python\nBottles-Problem-Get-Paths(mat[size, size], n) :\n    New paths[size, size]\n    for i=0 to size :\n        x1, y1 = getPairFromIndex(n, i)\n        for j=0 to size :\n            x2, y2 = getPairFromIndex(n, i)\n            if mat[i, j] ≠ ∞ :\n                paths[i, j] = \"(\"+x1+\",\"+y1+\") → (\"+x2+\",\"+y2+\")\"\n    for k=0 to size :\n        for i=0 to size :\n            for j=0 to size :\n                if mat[i,j] \u003e mat[i,k] + mat[k,j] :\n                   mat[i,j] = mat[i,k] + mat[k,j]\n                   paths[i,j] = paths[i,k] + \"→\" + paths[k,j]\n    return paths\n    \ngetPairFromIndex(n, i) :\n    return { i/(n+1), i%(n+1) }\n```\n\n\u003cdiv dir='rtl' lang='he'\u003e\n\n# תת מערך עם סכום תאים מקסימלי\t\n\nגרסה מקוצרת כשצריך רק את הסכום ללא אינדקסים\n* סיבוכיות: `O(n)`\n\u003c/div\u003e\n\t\n```python\nBest-basic(A[N]) :\n    maxSum = tempSum = -∞\n\n    for i=0 to N :\n        tempSum += A[i]\n        maxSum = max(maxSum, tempSum)\n        tempSum = max(tempSum, 0)\n    return maxSum\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\nגרסה רגילה כשצריך את הסכום ואת האינדקסים של תת המערך\n* סיבוכיות: `O(n)`\n\u003c/div\u003e\n\n```python\nBest(A[N]) :\n    maxSum = tempSum = -∞\n    start = end = 0\n\n    for i=0 to N :\n        tempSum += A[i]\n        if maxSum \u003c tempSum :\n            maxSum = tempSum\n            end = i\n        if tempSum \u003c 0:\n            tempSum = 0\n            start = i+1\n    return {maxSum, start, end}\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\nגרסה מעגלית כשלא צריך אינדקסים:\n* סיבוכיות: `O(n)`\n\u003c/div\u003e\n\n```python\nBest-Cycle(A[N]) :\n    totalSum = sum(A)\n    return max(Best(A), totalSum - Best(-A))\n``` \n\n\u003cdiv dir='rtl' lang='he'\u003e\n\nגרסה מעגלית כולל אינדקסים:\n* סיבוכיות: `O(n)`\n\u003c/div\u003e\n\n```python\nBest-Cycle(A[N]) :\n    totalSum = sum(A)\n    max1, start1, end1 = Best(A)\n    max2, start2, end2 = Best(-A)\n    \n    if max1 \u003e totalSum + max2 :\n        return {max1, start1, end1}\n    else\n        return {totalSum + max2, end2 + 1, start2 - 1}\n``` \n\n\u003cdiv dir='rtl' lang='he'\u003e\n\nבעיית תחנות הדלק:\n* מטרה למצוא תחנה ממנה אפשר ליסוע ולעשות סיבוב שלם.\n* המערך A מייצג את כמות הדלק בכל תחנהת המערך B מייצג את עלות הנסיעה בדלק מתחנה לתחנה.\n* סיבוכיות: `O(n)`\n\u003c/div\u003e\n\n```python\nGas-Stations-Problem(A[N], B[N]) :\n    C[N]\n    sum = 0\n    for i=0 to N :\n        C[i] = A[i] - B[i]\n        sum += C[i]\n    \n    if sum \u003c 0 :\n        return \"No solution\"\n    return Best-Cycle(C)\n``` \n\n\u003cdiv dir='rtl' lang='he'\u003e\n\t\n# תת מטריצה עם סכום תאים מקסימלי\n\t\nגרסה מקוצרת כשצריך רק את הסכום ללא אינדקסים:\n* סיבוכיות: `O(n^3)`\n\u003c/div\u003e\n\n```python\nSuper-Best-basic(A[rows,cols]):\n    maxSum = 0\n    for i=0 to rows :\n        New help[cols]\n        for j=i to rows :\n            for k=0 to cols :\n                help[k] += A[j,k]\n            maxSum = max(maxSum, Best-basic(help))\n    return maxSum\n\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\nגרסה רגילה כשצריך את הסכום ואת האינדקסים של תת המטריצה:\n* סיבוכיות: `O(n^3)`\n\u003c/div\u003e\n\n```python\nSuper-Best(A[rows,cols]) :\n    maxSum, start_x, start_y ,end_x, end_y = 0\n\n    for i=0 to rows :\n        New help[cols]\n        for j=i to rows :\n            for k=0 to cols :\n                help[k] += A[j,k]\n            tempSum, tempStart, tempEnd = best(help)\n            if maxSum \u003c tempSum :\n                maxSum = tempSum\n                start_x = tempStart\n                end_x = tempEnd\n                start_y = i\n                end_y = j\n    return {maxSum, start_x, start_y, end_x, end_y}\n\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\n# קוד האפמן\n\nשלב ראשון בניית העץ:\n* סיבוכיות: `O(n*log(n))`\t\n\u003c/div\u003e\n\n```python\nHuffman(C) :\n    Q = C\n    while |Q| \u003e 1 :\n        New node z\n        z.left = x = q.extractMin()\n        z.right = y = q.extractMin()\n        z.freq = x.freq + y.freq\n        Q.insert(z)\n    return Q.extrctMin()\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\nשלב שני - הוצאת הייצוגים הבינאריים של כל תו מהעץ:\n* סיבוכיות: `O(n)`\t\n\u003c/div\u003e\n\t\n```python\nHuffman-process(root = Huffman(C)) :\n    if(root.left == null AND root.right == null) :\n        print(root.char)\n    else:\n        print('0' + Huffman-process(root.left)\n        print('1' + Huffman-process(root.right)\n\n```\n\n\u003cdiv dir='rtl' lang='he'\u003e\n\t\nקוד האפמן - כאשר מערך התוים ממוין לפי שכיחויות:\n* סיבוכיות: `O(n)`\t\n\u003c/div\u003e\n\t\n```python\nHuffman-sorted(C) :\n    Q1 = C\n    Q2 = ∅\n    while |Q1| + |Q2| \u003e 1 :\n        New node z\n        z.left = x = getMin(Q1,Q2)\n        z.right = y = getMin(Q1,Q2)\n        z.freq = x.freq + y.freq\n        Q2.insert(z)\n    return getMin(Q1, Q2)\n\ngetMin(Q1,Q2):\n    if Q1 = ∅ :\n        return Q2.dequeue()\n    if Q2 = ∅ :\n        return Q1.dequeue()\n    if Q1.front \u003c Q2.front :\n        return Q1.dequeue()\n    else return Q2.dequeue()\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\t\n# עץ פורש מינימלי\n\nיצירת עץ פורש מינימלי - קרוסקל:\n* סיבוכיות: `O(|E|log|E|)`\n\t\n\u003c/div\u003e\n\t\n```python\nMST-Kruskal(G) :\n    T = ∅\n    for each v in V : makeSet(v)\n    sort E by weights\n    for each (u,v) in E :\n        if findSet(u) ≠ findSet(v) :\n            T.add((u,v))\n            union(u, v)\n    return T\n\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\t\nיצירת עץ פורש מינימלי - קרוסקל הפוך:\n* הרעיון הוא להתחיל עם \"עץ\" שיש בו את כל הצלעות של G. נעבור על הצלעות מהגדולות לקטנות ונשאל על כל צלע האם אפשר לנתק אותה מהגרף והוא עדיין יישאר קשיר. אם כן נמחק את הצלע מהעץ, ככה באותו האופן עד שנגיע לעץ בגודל תקין.\n* סיבוכיות: `O(|E|(|E|+|V|))`\n\t\n\u003c/div\u003e\n\t\n```python\nMST-Reversed-Kruskal(G) :\n    T = E\n    Q = E\n    while |T| \u003e |V|-1 :\n        e = Q.extractMax()\n        G.removeEdge(e)\n        if isConnected = false :\n            G.addEdge(e)\n    return T\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\t\nיצירת עץ פורש מינימלי - פרים:\n* סיבוכיות: `O(|V|+|E|log|V|)`\n\t\n\u003c/div\u003e\n\n```python\nMST-Prim(G) :\n    T = ∅\n    for each v in V :\n        v.key = ∞\n        v.prev = null\n    V[0].key = 0\n    Q = V\n    while Q ≠ ∅ :\n        u = Q.extractMin()\n        if u.prev ≠ null :\n            T.add((u, u.prev))\n        for each v in adj[u] :\n            if v in Q AND v.key \u003e w(u,v) :\n                v.key = w(u,v)\n                v.prev = u\n    return T\n\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\t\nיצירת עץ פורש מינימלי - בורובקה:\n* סיבוכיות: `O(|E|log|V|)`\n\t\n\u003c/div\u003e\n\n```python\nMST-Boruvka(G) :\n    T = ∅\n    for each v in V : makeSet(v)\n\n    while |T| \u003c |V|-1 :\n        New cheapest[|V|] := array of edges\n        for (u,v) in E :\n            g1 = findSet(u)\n            g2 = findSet(v)\n            if g1 ≠ g2 :\n                if w(cheapest[g1]) \u003e w(u,v) :\n                    w(cheapest[g1]) = w(u,v)\n                if w(cheapest[g2]) \u003e w(u,v) :\n                    w(cheapest[g2]) = w(u,v)\n        for i=0 to |v| :\n            if cheapest[i] ≠ null :\n                T.add(cheapest[i])\n                union(cheapest[i].u, cheapest[i].v)\n    return T\n\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\t\n# מעבר על גרפים\n## BFS\nמעבר על גרף באמצעות סריקה לרוחב:\n* סיבוכיות: `O(|V|+|E|)`\n\u003c/div\u003e\n\t\n```python\nBFS(G, s) :\n    for each v in V :\n        v.color = WHITE, v.dist = ∞, v.prev = null\n\n    s.color = GRAY, s.dist = 0, s.prev = -1\n    Q = {s}\n    while Q ≠ ∅ :\n        u = Q.dequeue()\n        for each v in adj[u] :\n            if v.color = WHITE :\n                v.color = GRAY\n                v.dist = u.dist + 1\n                v.prev = u\n                Q.enqueue(v)\n        u.color = BLACK\n```\n\n\u003cdiv dir='rtl' lang='he'\u003e\n\n## DFS\nמעבר על גרף באמצעות סריקה לעומק:\n* סיבוכיות: `O(|V|+|E|)`\n\u003c/div\u003e\n\t\n```python\nDFS(G) :\n    for each v in V : v.color = WHITE\n    for each v in V :\n        if v.color = WHITE :\n            DFS-VISIT(G, v)\n\nDFS-VISIT(G, n) :\n    n.color = GRAY\n    for each v in adj[n] :\n        if v.color = WHITE :\n            DFS-VISIT(G, v)\n    n.color = BLACK\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\t\nבדיקה האם צלע נתונה נמצאת על מעגל:\n* סיבוכיות: `O(|V|+|E|)`\n\u003c/div\u003e\n\n```python\nIs-Edge-On-Cycle(G, e) :\n    u = e.u\n    v = e.v\n    G.removeEdge(e)\n    BFS(v)\n    return (u.color ≠ WHITE)\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\t\nמציאת מספר רכיבי קשירות בגרף:\n* סיבוכיות: `O(|V|+|E|)`\n\u003c/div\u003e\n\n```python\nDFS-Number-Of-Connected-Components(G) :\n    counter = 0\n    for each v in V : v.color = WHITE\n    for each v in V :\n        if v.color = WHITE :\n            counter++\n            DFS-VISIT(G, v)\n    return counter\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\t\nבדיקה האם קיים מעגל בגרף:\n* סיבוכיות: `O(|V|+|E|)`\n\u003c/div\u003e\n\t\n```python\nDFS-Has-Cycle(G) :\n    for each v in V : v.color = WHITE\n    for each v in V :\n        if v.color = WHITE :\n            if DFS-VISIT(G, v) = true :\n                return true\n    return false\n```\n\n\t\n```python\nDFS-VISIT(G, n) :\n    n.color = GRAY\n    for each v in adj[n] :\n        if v.color = GRAY : \n            return true\n        if v.color = WHITE :\n            if DFS-VISIT(G, v) = true :\n                return true\n    n.color = BLACK\n    return false\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\t\nבדיקה האם קיים מעגל אויילר בגרף:\n* סיבוכיות: `O(|V|+|E|)`\n\u003c/div\u003e\n\t\n```python\nHas-Euler-Cycle(G) :\n    for each v in V :\n        if v.degree % 2 ≠ 0 :\n            return \"No euler Cycle detected\"\n    if isConnected(G) :\n        return Euler-Cycle(G)\n```\n\n\u003cdiv dir='rtl' lang='he'\u003e\n\t\nמציאת מעגל אויילר בגרף:\n* סיבוכיות: `O(|V|+|E|)`\n\u003c/div\u003e\n\t\n```python\nEuler-Cycle(G) :\n    select some vertex s from G \n    list C = ∅\n    stack = {s}\n    while stack ≠ ∅ :\n        v = stack.peek()\n        if v.degree = 0 :\n            C.add(stack.pop())\n        else :\n            u = first of adj[v]\n            stack.push(u)\n            G.remove(u,v)\n            G.remove(v,u)\n    return C        \n```\n\n\u003cdiv dir='rtl' lang='he'\u003e\n\t\nבדיקת קשירות בגרף ע\"י סריקה לרוחב:\n* סיבוכיות: `O(|V|+|E|)`\n\u003c/div\u003e\n\t\n```python\nBFS-isConnected(G) :\n    select some vertex s from G \n    BFS(G, s)\n    for each v in V :\n        if v.color ≠ BLACK :\n            return false\n    return true \n```\n\n\u003cdiv dir='rtl' lang='he'\u003e\n\t\nבדיקה האם קיים מסלול אויילר בגרף:\n* סיבוכיות: `O(|V|+|E|)`\n\u003c/div\u003e\n\n```python\nEuler-HasEuler-path(G) :\n    counter = 0\n    for each v in V :\n        if v.degree % 2 ≠ 0 :\n            counter++\n    return isConnected(G) = true AND counter = 2\n\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\n# קוטר ורדיוס בעצים\nמציאת קוטר, רדיוס ומרכזים של עץ ע\"י אלגוריתם שריפת עלים:\n* סיבוכיות: `O(|V|+|E|)`\n\t\n\u003c/div\u003e\n\n```python\nDiameter-Fire(T) :\n    n = |V|, radius = 0, leaves = ∅\n    for each v in V :\n        if v.deg = 1 :\n            leaves.add(v)\n    \n    while n \u003e 2 :\n        future = ∅\n        for each leaf in leaves :\n            leaf.deg = 0\n            n--\n            for each v in adj[leaf] :\n                if --v.deg = 1 :\n                    future.add(v)\n        radius++\n        leaves = future\n\n    diameter = radius*2 + |leaves|-1\n    centers[] = leaves\n    return {centers, radius, diameter}\n```\n\n\u003cdiv dir='rtl' lang='he'\u003e\n\nמציאת קוטר של עץ ע\"י אלגוריתם סריקה לעומק:\n* סיבוכיות: `O(|V|+|E|)`\n\t\n\u003c/div\u003e\n\n```python\nDiameter-DFS(T) :\n    maxDist = 0, MaxDistVertex = 0 \n    DFS(T, 0)\n    for each v in V:\n        if maxDist \u003c v.dist :\n            maxDist = v.dist\n            MaxDistVertex = v \n\n    DFS(T, MaxDistVertex)\n\n    for each v in V:\n        if maxDist \u003c v.dist :\n            maxDist = v.dist\n            \n    return maxDist\n```\n\n\u003cdiv dir='rtl' lang='he'\u003e\n\nמציאת המסלול של קוטר בעץ ע\"י אלגוריתם סריקה לעומק DFS:\n* סיבוכיות: `O(|V|+|E|)`\n\t\n\u003c/div\u003e\n\n```python\nDiameter-Path-DFS(T) :\n    maxDist = 0, MaxDistVertex = 0 \n    DFS(T, 0)\n    for each v in V:\n        if maxDist \u003c v.dist :\n            maxDist = v.dist\n            MaxDistVertex = v \n\n    DFS(T, MaxDistVertex)\n\n    for each v in V:\n        if maxDist \u003c v.dist :\n            maxDist = v.dist\n            MaxDistVertex = v\n\n    path = ∅\n    while MaxDistVertex != -1 :\n        path.add(MaxDistVertex)\n        MaxDistVertex = MaxDistVertex.prev\n\n    return path\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\nבדיקה האם קודקוד נתון נמצא על קוטר בעץ:\n* הבעיה דומה לבדיקה האם נקודה נמצאת על צלע מסוים.\n* שלב ראשון: נמצא את הקוטר (ע\"י אלגוריתם שריפה או באמצעות `DFS`) \n* שלב שני: נמצא את הקודקוד הכי רחוק מקודקוד `v` - מובטח שהוא קצה אחד של הקוטר. \n* שלב שלישי: נמצא את הצלע הראשונה מקודקוד `v` במסלול לעבר הקודקוד שמצאנו בשלב הקודם. נשמור את המרחק.\n* שלב רביעי: נסיר את הצלע הזאת מה שבעצם מסיר את כל הענף\n* שלב חמישי: נעשה שוב את שלב 2. מובטח שהפעם הקודקוד הכי רחוק מ `v` הוא הקצה השני של הקוטר.\n* שלב אחרון: אם הקוטר שווה למרחק של `v` מהקצה הראשון של הקוטר ועוד מרחקו מהקצה השני - אזי הקודקוד נמצא על הקוטר (אחד מהם במידה ויש כמה)\n* סיבוכיות: `O(|V|+|E|)`\n\t\n\u003c/div\u003e\n\n```python\nis-Vertex-on-Diameter(T, v) :\n    diameter = Diameter(T)\n    BFS(v)\n    maxDist1 = maxDistIndex = 0\n    for each v in V :\n        if maxDist1 \u003c v.dist :\n            maxDist1 = v.dist\n            maxDistIndex = v\n\n    while maxDistIndex.prev ≠ v :\n        maxDistIndex = maxDistIndex.prev\n\n    remove((v, maxDistIndex))\n    BFS(v)\n    maxDist2 = 0\n    for each v in V :\n        if maxDist2 \u003c v.dist :\n            maxDist2 = v.dist\n    \n    return (diameter == maxDist1 + maxDist2)\n\n```\n\n\u003cdiv dir='rtl' lang='he'\u003e\n\n# דייקסטרה\nמציאת המרחקים הקצרים ביותר בגרף מקודקוד נתון:\n* סיבוכיות: `O((V+E)logV)`  (כאשר משתמשים בערימה בינארית)\n\t\n\u003c/div\u003e\n\n```python\nDijkstra(G, s) :\n    for v in V : v.dist = ∞\n\n    s.dist = 0\n    Q = V\n    while Q ≠ ∅ :\n        u = Q.extractMin() //by dists\n        for v in adj[u] :\n            if v.dist \u003e u.dist + w(u,v) :\n                v.dist = u.dist + w(u,v)\n                v.prev = u\n\n```\n\u003cdiv dir='rtl' lang='he'\u003e\n\n# בניית עץ מרשימת דרגות\n* צריך לבדוק קודם שאכן מתקיים  `Sum(degs) = 2*(|V|-1)`  לפני שמתחילים את האלגוריתם.\n* סיבוכיות: `O(VlogV)` אם המערך לא ממוין. `O(V)` אם המערך ממוין כבר.\n* הערה: האינדקס של האיבר הראשון במערך הוא 0, האינדקס של האיבר האחרון במערך הוא N-1.\n\t\n\u003c/div\u003e\n\n```python\nGenerateTreebyDegrees(deg[N]) :\n    sort(deg)\n\n    j = 0\n    while deg[j] = 1 : j++\n    \n    New Tree[N,N] = {false}\n    for i=0 to N-2 :\n        Tree[i,j] = true\n        Tree[j,i] = true\n        if --deg[j] = 1 :\n            j++\n    Tree[N-2,N-1] = true\n    Tree[N-1,N-2] = true\n    return Tree\n```\n\n\u003cdiv dir='rtl' lang='he'\u003e\n\n# איזומורפיזם של עצים\n* הרעיון הוא ליצור ייצוג בינארי כמחרוזת לכל עץ. אם המחרוזת של העץ הראשון זהה למחרוזת של העץ השני, אזי שני העצים איזומורפיים.\n* יצירת הייצוג הבינארי כמחרוזת לעץ מתחילה רקורסיבית מהשורש כלפי מטה, כאשר כל עלה מיוצג ע\"י \"01\" וכל אבא משרשר את הייצוגים של הילדים שלו בסדר ממוין כאשר משמאל יש \"0\" ומימין יש \"1\".\n* אם לא נתון מה השורש של העץ אז נשתמש באלגוריתם שריפה למציאת מרכז העץ והוא יהיה השורש.\n* אם לעץ הראשון יש מרכז אחד ולשני יש שני מרכזים, אזי העצים לא איזומורפיים.\n* אם יש 2 מרכזים לעץ, נבדוק אם המחרוזת של העץ הראשון שווה למחרוזת של העץ השני בחילופי תפקידים בין המרכזים שנמצאו.\n* סיבוכיות: `O(VlogV)`\n\t\n\u003c/div\u003e\n\n```python\nAHU-Tree-Isomorphism(T1, T2) :\n    r1 = T1.root\n    r2 = T2.root\n    if r1 = null AND r2 = null :\n        r1 = findCenter(T1)    // by Fire Algorithm\n        r2 = findCenter(T2)\n    New global List\u003cString\u003e childrenCodes[|V|]\n    code1 = findCode(r1)\n    code2 = findCode(r2)\n    return (code1 == code2)\n```\n\n```python\nfindCode(u)\n    u.color = BLACK\n    if u is a leaf :\n        return \"10\"\n\n    for each v in adj[u] :\n        if v.color = WHITE :    // then v is child of u\n            childrenCodes[u].add(findCode(v))\n    Sort(childrenCodes[u])\n    temp = \"\"\n    for each s in childrenCodes[u] :\n        temp += s\n    return \"1\"+temp+\"0\"\n```\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flevieyal%2Falgorithms-2-course","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flevieyal%2Falgorithms-2-course","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flevieyal%2Falgorithms-2-course/lists"}