程序员常用的算法(13种)

目录

1. 冒泡排序(Bubble Sort)

2. 选择排序(Selection Sort)

3. 插入排序(Insertion Sort)

4. 快速排序(Quick Sort)

5. 归并排序(Merge Sort)

6. 堆排序(Heap Sort)

7. 顺序搜索(Sequential Search)

8. 二分搜索(Binary Search)

9. 动态规划(Dynamic Programming)

10. 贪心算法(Greedy Algorithm)

找零钱问题 

11. 分治法(Divide and Conquer)

12. 广度优先搜索(Breadth-First Search,BFS)

13. 深度优先搜索(Depth-First Search,DFS)


程序员常用的算法包括但不限于以下几种:

1) 排序算法:

  1. 冒泡排序
  2. 选择排序
  3. 插入排序
  4. 快速排序
  5. 归并排序
  6. 堆排序

2) 搜索算法:

  1. 顺序搜索
  2. 二分搜索

3) 动态规划算法
4) 贪心算法
5) 分治算法
6) 图算法:

  • 广度优先搜索(BFS)
  • 深度优先搜索(DFS)

下面将对每种算法进行详细讲解,并给出一个实例和对应的 C 语言实现代码。

结合自己近 8 年对数据结构的研究,我原创了一整套数据结构和算法教程(xiexuewu.github.io),它通俗易懂、不学院派,没有晦涩难懂的学术用语,教程提供了完整、可运行的 C 语言程序,非常适合有 C 语言基础、想系统学习数据结构和算法的人。

1. 冒泡排序(Bubble Sort)

冒泡排序是一种简单的排序算法,它重复地遍历要排序的列表,一次比较两个元素,如果它们的顺序错误就把它们交换过来。

【示例】假设要排序的数组为:[5, 3, 8, 4, 2]

步骤:

第一次遍历:比较相邻的两个元素,如果前面的比后面的大,则交换它们。

[3, 5, 4, 2, 8]

第二次遍历:继续比较相邻的两个元素并交换。

[3, 4, 2, 5, 8]

继续这个过程,直到没有任何一对数字需要比较。C 语言实现代码:

#include <stdio.h>

void bubbleSort(int arr[], int n) {
    int i, j, temp;
    for (i = 0; i < n - 1; i++) {
        for (j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                // Swap arr[j] and arr[j+1]
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

int main() {
    int arr[] = {5, 3, 8, 4, 2};
    int n = sizeof(arr) / sizeof(arr[0]);
    bubbleSort(arr, n);
    printf("Sorted array: \n");
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    return 0;
}

输出结果为:Sorted array: 2 3 4 5 8

这段代码实现了冒泡排序算法,并对示例数组进行了排序。

2. 选择排序(Selection Sort)

选择排序是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。

【示例】假设要排序的数组为:[5, 3, 8, 4, 2]

步骤:

第一次遍历:找到最小的元素2,与第一个元素5交换位置。

[2, 3, 8, 4, 5]

第二次遍历:在剩余的元素中找到最小的元素3,与第二个元素3交换位置(即自身)。

[2, 3, 8, 4, 5]

以此类推,直到所有元素都排好序。

C 语言实现代码:

#include <stdio.h>

void selectionSort(int arr[], int n) {
    int i, j, min_idx;
    // One by one move boundary of unsorted subarray
    for (i = 0; i < n - 1; i++) {
        // Find the minimum element in unsorted array
        min_idx = i;
        for (j = i + 1; j < n; j++)
            if (arr[j] < arr[min_idx])
                min_idx = j;
        // Swap the found minimum element with the first element
        int temp = arr[min_idx];
        arr[min_idx] = arr[i];
        arr[i] = temp;
    }
}

int main() {
    int arr[] = {5, 3, 8, 4, 2};
    int n = sizeof(arr) / sizeof(arr[0]);
    selectionSort(arr, n);
    printf("Sorted array: \n");
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    return 0;
}

输出结果为:Sorted array: 2 3 4 5 8

这段代码实现了选择排序算法,并对示例数组进行了排序。

3. 插入排序(Insertion Sort)

插入排序是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

【示例】假设要排序的数组为:[5, 3, 8, 4, 2]

步骤:

第一次遍历:首先将数组的第一个元素视为有序序列,然后依次将后面的元素插入到有序序列中的适当位置。

[3, 5, 8, 4, 2]

继续进行这个过程,直到所有元素都插入到正确的位置。C 语言实现代码:

#include <stdio.h>

void insertionSort(int arr[], int n) {
    int i, key, j;
    for (i = 1; i < n; i++) {
        key = arr[i];
        j = i - 1;
        // Move elements of arr[0..i-1], that are greater than key,
        // to one position ahead of their current position
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j = j - 1;
        }
        arr[j + 1] = key;
    }
}

int main() {
    int arr[] = {5, 3, 8, 4, 2};
    int n = sizeof(arr) / sizeof(arr[0]);
    insertionSort(arr, n);
    printf("Sorted array: \n");
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    return 0;
}

输出结果为:Sorted array: 2 3 4 5 8

这段代码实现了插入排序算法,并对示例数组进行了排序。

4. 快速排序(Quick Sort)

快速排序是一种常用的排序算法,它是一种分治的排序方法。它的工作原理是通过一趟排序将待排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

【示例】假设要排序的数组为:[5, 3, 8, 4, 2]

步骤:

  1. 选择数组中的一个元素作为基准(通常选择第一个元素)。
  2. 将数组中小于基准的元素移动到基准的左边,大于基准的元素移动到基准的右边。
  3. 对基准左右两边的子数组递归地进行快速排序。

C 语言实现代码:

#include <stdio.h>

// Function to swap two elements
void swap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// Function to partition the array
int partition(int arr[], int low, int high) {
    int pivot = arr[high]; // pivot
    int i = (low - 1); // Index of smaller element

    for (int j = low; j <= high - 1; j++) {
        // If current element is smaller than the pivot
        if (arr[j] < pivot) {
            i++; // increment index of smaller element
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return (i + 1);
}

// Function to implement Quick sort
void quickSort(int arr[], int low, int high) {
    if (low < high) {
        // pi is partitioning index, arr[p] is now at right place
        int pi = partition(arr, low, high);

        // Separately sort elements before partition and after partition
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}

int main() {
    int arr[] = {5, 3, 8, 4, 2};
    int n = sizeof(arr) / sizeof(arr[0]);
    quickSort(arr, 0, n - 1);
    printf("Sorted array: \n");
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    return 0;
}

输出结果为:Sorted array: 2 3 4 5 8

这段代码实现了快速排序算法,并对示例数组进行了排序。

5. 归并排序(Merge Sort)

归并排序是一种分治算法,它将待排序的数组分成两个子数组,分别对这两个子数组进行排序,然后将排好序的子数组合并成一个最终的排序数组。

【示例】假设要排序的数组为:[5, 3, 8, 4, 2]

步骤:

  1. 将数组分成两个子数组:[5, 3] 和 [8, 4, 2]。
  2. 对每个子数组进行归并排序。
  3. 将排好序的子数组合并成一个有序数组。

C 语言实现代码:

#include <stdio.h>
#include <stdlib.h>

// Function to merge two subarrays arr[low...mid] and arr[mid+1...high]
void merge(int arr[], int low, int mid, int high) {
    int n1 = mid - low + 1;
    int n2 = high - mid;

    // Create temporary arrays
    int *L = (int *)malloc(sizeof(int) * n1);
    int *R = (int *)malloc(sizeof(int) * n2);

    // Copy data to temporary arrays L[] and R[]
    for (int i = 0; i < n1; i++)
        L[i] = arr[low + i];
    for (int j = 0; j < n2; j++)
        R[j] = arr[mid + 1 + j];

    // Merge the temporary arrays back into arr[low...high]
    int i = 0, j = 0, k = low;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            i++;
        } else {
            arr[k] = R[j];
            j++;
        }
        k++;
    }

    // Copy the remaining elements of L[], if there are any
    while (i < n1) {
        arr[k] = L[i];
        i++;
        k++;
    }

    // Copy the remaining elements of R[], if there are any
    while (j < n2) {
        arr[k] = R[j];
        j++;
        k++;
    }

    // Free temporary arrays
    free(L);
    free(R);
}

// Function to implement merge sort
void mergeSort(int arr[], int low, int high) {
    if (low < high) {
        int mid = low + (high - low) / 2;
        // Sort first and second halves
        mergeSort(arr, low, mid);
        mergeSort(arr, mid + 1, high);
        // Merge the sorted halves
        merge(arr, low, mid, high);
    }
}

int main() {
    int arr[] = {5, 3, 8, 4, 2};
    int n = sizeof(arr) / sizeof(arr[0]);
    mergeSort(arr, 0, n - 1);
    printf("Sorted array: \n");
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    return 0;
}

输出结果为:Sorted array: 2 3 4 5 8

这段代码实现了归并排序算法,并对示例数组进行了排序。

6. 堆排序(Heap Sort)

堆排序是一种选择排序,它利用了堆这种数据结构的性质。堆是一个完全二叉树,它可以分为最大堆和最小堆。在堆排序中,我们使用最大堆来进行升序排序。

【示例】假设要排序的数组为:[5, 3, 8, 4, 2]

步骤:

  1. 将数组构建成最大堆。
  2. 交换堆顶元素(最大元素)和堆的最后一个元素,然后将剩余元素重新构建成最大堆。
  3. 重复步骤 2,直到堆中的所有元素都已排序。

C 语言实现代码:

#include <stdio.h>

// To heapify a subtree rooted with node i which is an index in arr[]
void heapify(int arr[], int n, int i) {
    int largest = i; // Initialize largest as root
    int left = 2 * i + 1; // left = 2*i + 1
    int right = 2 * i + 2; // right = 2*i + 2

    // If left child is larger than root
    if (left < n && arr[left] > arr[largest])
        largest = left;

    // If right child is larger than largest so far
    if (right < n && arr[right] > arr[largest])
        largest = right;

    // If largest is not root
    if (largest != i) {
        int temp = arr[i];
        arr[i] = arr[largest];
        arr[largest] = temp;

        // Recursively heapify the affected sub-tree
        heapify(arr, n, largest);
    }
}

// Main function to do heap sort
void heapSort(int arr[], int n) {
    // Build heap (rearrange array)
    for (int i = n / 2 - 1; i >= 0; i--)
        heapify(arr, n, i);

    // One by one extract an element from heap
    for (int i = n - 1; i > 0; i--) {
        // Move current root to end
        int temp = arr[0];
        arr[0] = arr[i];
        arr[i] = temp;

        // call max heapify on the reduced heap
        heapify(arr, i, 0);
    }
}

int main() {
    int arr[] = {5, 3, 8, 4, 2};
    int n = sizeof(arr) / sizeof(arr[0]);
    heapSort(arr, n);
    printf("Sorted array: \n");
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    return 0;
}

输出结果为:Sorted array: 2 3 4 5 8

这段代码实现了堆排序算法,并对示例数组进行了排序。

7. 顺序搜索(Sequential Search)

顺序搜索是一种简单直观的搜索算法,也称为线性搜索。它从数组的第一个元素开始逐个检查,直到找到目标元素或遍历完整个数组。

【示例】假设要在数组 [5, 3, 8, 4, 2] 中搜索元素 4。

步骤:

  1. 从数组的第一个元素开始逐个检查。
  2. 找到目标元素 4,并返回其索引。

C 语言实现代码:

#include <stdio.h>

int sequentialSearch(int arr[], int n, int target) {
    for (int i = 0; i < n; i++) {
        if (arr[i] == target)
            return i; // Return the index of the target element
    }
    return -1; // Return -1 if the target element is not found
}

int main() {
    int arr[] = {5, 3, 8, 4, 2};
    int n = sizeof(arr) / sizeof(arr[0]);
    int target = 4;
    int index = sequentialSearch(arr, n, target);
    if (index != -1)
        printf("Element %d found at index %d\n", target, index);
    else
        printf("Element %d not found in the array\n", target);
    return 0;
}

输出结果为:Element 4 found at index 3

这段代码实现了顺序搜索算法,并在示例数组中搜索元素 4。

8. 二分搜索(Binary Search)

二分搜索是一种高效的搜索算法,但它要求待搜索的数组必须是有序的。它通过反复将待搜索区间划分为两部分,并在每次迭代中选择与目标元素相比较的中间元素来减小搜索范围。

【示例】假设要在有序数组 [2, 3, 4, 5, 8] 中搜索元素 4。

步骤:

  1. 确定搜索区间的左右边界(初始时为数组的第一个和最后一个元素)。
  2. 计算中间元素的索引并与目标元素进行比较。
  3. 根据比较结果,更新搜索区间的左右边界。
  4. 重复步骤 2 和步骤 3,直到找到目标元素或搜索区间为空。

C 语言实现代码:

#include <stdio.h>

int binarySearch(int arr[], int left, int right, int target) {
    while (left <= right) {
        int mid = left + (right - left) / 2;
        // Check if target is present at mid
        if (arr[mid] == target)
            return mid;
        // If target greater, ignore left half
        if (arr[mid] < target)
            left = mid + 1;
        // If target is smaller, ignore right half
        else
            right = mid - 1;
    }
    // If we reach here, then element was not present
    return -1;
}

int main() {
    int arr[] = {2, 3, 4, 5, 8};
    int n = sizeof(arr) / sizeof(arr[0]);
    int target = 4;
    int index = binarySearch(arr, 0, n - 1, target);
    if (index != -1)
        printf("Element %d found at index %d\n", target, index);
    else
        printf("Element %d not found in the array\n", target);
    return 0;
}

输出结果为:Element 4 found at index 2

这段代码实现了二分搜索算法,并在有序数组中搜索元素 4。

9. 动态规划(Dynamic Programming)

动态规划是一种通过将问题分解成更小的子问题来解决复杂问题的方法,然后将子问题的解组合起来得到原问题的解。它通常用于解决优化问题,例如最长公共子序列、背包问题等。

最长公共子序列问题是指找到两个序列中的最长公共子序列的长度。子序列是可以通过删除某些元素(包括零个)而不改变其余元标题二素相对位置的序列。

【示例】假设有两个序列 "ABCBDAB" 和 "BDCAB",它们的最长公共子序列是 "BCAB",长度为 4。

动态规划解法:

  1. 初始化一个二维数组 dp,其中 dp[i][j] 表示序列 s1 的前 i 个字符和序列 s2 的前 j 个字符的最长公共子序列的长度。
  2. 如果 s1[i-1] 和 s2[j-1] 相等,则 dp[i][j] = dp[i-1][j-1] + 1。
  3. 否则,dp[i][j] 取 dp[i-1][j] 和 dp[i][j-1] 中的较大值。
  4. 最终结果保存在 dp[m][n],其中 m 和 n 分别是序列 s1 和 s2 的长度。

C 语言实现代码:

#include <stdio.h>
#include <string.h>

#define MAX_LEN 100

int max(int a, int b) {
    return (a > b) ? a : b;
}

int longestCommonSubsequence(char *s1, char *s2) {
    int m = strlen(s1);
    int n = strlen(s2);
    int dp[MAX_LEN][MAX_LEN];

    // Initialize the dp array
    for (int i = 0; i <= m; i++)
        dp[i][0] = 0;
    for (int j = 0; j <= n; j++)
        dp[0][j] = 0;

    // Fill the dp array
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (s1[i - 1] == s2[j - 1])
                dp[i][j] = dp[i - 1][j - 1] + 1;
            else
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
        }
    }

    return dp[m][n];
}

int main() {
    char s1[] = "ABCBDAB";
    char s2[] = "BDCAB";
    int result = longestCommonSubsequence(s1, s2);
    printf("Length of Longest Common Subsequence: %d\n", result);
    return 0;
}

输出结果为:Length of Longest Common Subsequence: 4

这段代码实现了动态规划解法,并计算了两个序列的最长公共子序列的长度。

这只是动态规划的一个例子,该技术还可以应用于许多其他类型的问题。

10. 贪心算法(Greedy Algorithm)

贪心算法是一种优化算法,它在每一步都选择当前状态下的最优解,而不考虑后续步骤可能导致的影响。尽管贪心算法不能保证获得全局最优解,但它通常能够产生一个接近最优解的解。

找零钱问题

找零钱问题是一个经典的贪心算法应用场景。假设有一定数量的不同面额的货币,要找零 amount 元,如何选择最少数量的硬币?

【示例】假设货币的面额为 [1, 2, 5, 10, 20, 50, 100],要找零 amount = 36 元。

贪心算法解法:

  1. 从面额最大的货币开始,尽可能多地使用该面额的货币,直到找零数额减少为零。
  2. 如果找零数额大于当前面额的货币,继续使用当前面额的货币,直到找零数额减少为零或当前面额的货币无法再使用。

C 语言实现代码:

#include <stdio.h>

int minCoins(int coins[], int n, int amount) {
    int count = 0;

    // Start from the highest denomination
    for (int i = n - 1; i >= 0; i--) {
        // Keep using the current coin denomination while it can be used
        while (amount >= coins[i]) {
            amount -= coins[i];
            count++;
        }
    }

    return count;
}

int main() {
    int coins[] = {1, 2, 5, 10, 20, 50, 100};
    int n = sizeof(coins) / sizeof(coins[0]);
    int amount = 36;
    int min_count = minCoins(coins, n, amount);
    printf("Minimum number of coins needed: %d\n", min_count);
    return 0;
}

输出结果为:Minimum number of coins needed: 4

这段代码实现了贪心算法解决找零钱问题,并计算了找零 36 元所需的最少硬币数量。

虽然贪心算法在这个问题中得到了最优解,但并不是所有问题都适合贪心算法。在某些情况下,贪心算法可能会产生次优解或甚至无法得到正确解。因此,在应用贪心算法时,需要仔细考虑问题的特性。

11. 分治法(Divide and Conquer)

分治法是一种将问题分解成更小的子问题来解决复杂问题的方法,然后将子问题的解合并起来得到原问题的解。它通常涉及三个步骤:分解、解决和合并。

归并排序(Merge Sort)

归并排序是一种经典的排序算法,它采用分治法的思想。它将待排序的数组分成两个子数组,分别对子数组进行排序,然后将排好序的子数组合并成一个有序数组。

算法步骤:

  1. 分解:将数组分解成两个子数组,直到每个子数组的长度为 1。
  2. 解决:对每个子数组进行排序。
  3. 合并:合并两个已排序的子数组,形成一个新的有序数组。

【示例】考虑待排序数组 [38, 27, 43, 3, 9, 82, 10],使用归并排序进行排序。C 语言实现代码:

#include <stdio.h>

// Function to merge two sorted subarrays arr[l..m] and arr[m+1..r]
void merge(int arr[], int l, int m, int r) {
    int i, j, k;
    int n1 = m - l + 1;
    int n2 = r - m;

    // Create temporary arrays
    int L[n1], R[n2];

    // Copy data to temporary arrays L[] and R[]
    for (i = 0; i < n1; i++)
        L[i] = arr[l + i];
    for (j = 0; j < n2; j++)
        R[j] = arr[m + 1 + j];

    // Merge the temporary arrays back into arr[l..r]
    i = 0; // Initial index of first subarray
    j = 0; // Initial index of second subarray
    k = l; // Initial index of merged subarray
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            i++;
        } else {
            arr[k] = R[j];
            j++;
        }
        k++;
    }

    // Copy the remaining elements of L[], if any
    while (i < n1) {
        arr[k] = L[i];
        i++;
        k++;
    }

    // Copy the remaining elements of R[], if any
    while (j < n2) {
        arr[k] = R[j];
        j++;
        k++;
    }
}

// Function to perform merge sort on array arr[l..r]
void mergeSort(int arr[], int l, int r) {
    if (l < r) {
        // Find the middle point
        int m = l + (r - l) / 2;

        // Sort first and second halves
        mergeSort(arr, l, m);
        mergeSort(arr, m + 1, r);

        // Merge the sorted halves
        merge(arr, l, m, r);
    }
}

// Function to print an array
void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++)
        printf("%d ", arr[i]);
    printf("\n");
}

int main() {
    int arr[] = {38, 27, 43, 3, 9, 82, 10};
    int n = sizeof(arr) / sizeof(arr[0]);

    printf("Original array: \n");
    printArray(arr, n);

    mergeSort(arr, 0, n - 1);

    printf("\nSorted array: \n");
    printArray(arr, n);
    return 0;
}

输出结果为:
Original array: 
38 27 43 3 9 82 10 

Sorted array: 
3 9 10 27 38 43 82
这段代码实现了归并排序算法,并对示例数组进行了排序。归并排序的时间复杂度为 O(nlogn)。

12. 广度优先搜索(Breadth-First Search,BFS)

广度优先搜索是一种用于图和树的遍历或搜索的算法。它从指定的起始顶点开始,逐层遍历图或树的节点,直到找到目标节点为止。

示例:

考虑以下无向图:

   0 -- 1
  / \   |
 2---3--4

假设起始顶点为 0,目标顶点为 4。使用 BFS 可以找到从顶点 0 到顶点 4 的最短路径。

步骤:

  1. 从起始顶点开始,将其加入到队列中。
  2. 从队列中取出一个顶点,并将其所有未访问过的邻居加入到队列中。
  3. 标记已访问的顶点,以避免重复访问。
  4. 重复步骤 2 和步骤 3,直到队列为空或找到目标顶点。

C 语言实现代码:

#include <stdio.h>
#include <stdbool.h>

#define MAX_VERTICES 5

// Graph represented as an adjacency matrix
int graph[MAX_VERTICES][MAX_VERTICES] = {
    {0, 1, 1, 0, 0},
    {1, 0, 0, 1, 0},
    {1, 0, 0, 1, 1},
    {0, 1, 1, 0, 1},
    {0, 0, 1, 1, 0}
};

bool visited[MAX_VERTICES]; // Array to keep track of visited vertices

// Queue implementation
int queue[MAX_VERTICES];
int front = -1, rear = -1;

void enqueue(int vertex) {
    if (rear == MAX_VERTICES - 1)
        printf("Queue is full\n");
    else {
        if (front == -1)
            front = 0;
        rear++;
        queue[rear] = vertex;
    }
}

int dequeue() {
    if (front == -1 || front > rear) {
        printf("Queue is empty\n");
        return -1;
    } else {
        int vertex = queue[front];
        front++;
        return vertex;
    }
}

bool isEmpty() {
    return front == -1 || front > rear;
}

// BFS algorithm
void BFS(int start, int target) {
    enqueue(start);
    visited[start] = true;

    while (!isEmpty()) {
        int current = dequeue();
        printf("%d ", current); // Print the current vertex

        if (current == target) {
            printf("\nTarget vertex found\n");
            return;
        }

        for (int i = 0; i < MAX_VERTICES; i++) {
            if (graph[current][i] == 1 && !visited[i]) {
                enqueue(i);
                visited[i] = true;
            }
        }
    }

    printf("\nTarget vertex not found\n");
}

int main() {
    int start = 0; // Starting vertex
    int target = 4; // Target vertex
    printf("BFS traversal: ");
    BFS(start, target);
    return 0;
}

输出结果为:
BFS traversal: 0 1 2 3 4 
Target vertex found
这段代码实现了广度优先搜索算法,并在示例图中找到了从顶点 0 到顶点 4 的最短路径。

13. 深度优先搜索(Depth-First Search,DFS)

深度优先搜索是一种用于图和树的遍历或搜索的算法。它从指定的起始顶点开始,沿着一条路径尽可能深地访问图的顶点,直到到达最深的顶点,然后回溯并继续遍历其他路径。

示例:

考虑以下无向图:

  0 -- 1
  / \   |
 2---3--4

假设起始顶点为 0,目标顶点为 4。使用 DFS 可以找到从顶点 0 到顶点 4 的路径之一。

步骤:

  1. 从起始顶点开始递归地访问相邻顶点,并标记已访问的顶点。
  2. 对于每个相邻顶点,重复步骤 1,直到找到目标顶点或无法继续访问。

C 语言实现代码:

#include <stdio.h>
#include <stdbool.h>

#define MAX_VERTICES 5

// Graph represented as an adjacency matrix
int graph[MAX_VERTICES][MAX_VERTICES] = {
    {0, 1, 1, 0, 0},
    {1, 0, 0, 1, 0},
    {1, 0, 0, 1, 1},
    {0, 1, 1, 0, 1},
    {0, 0, 1, 1, 0}
};

bool visited[MAX_VERTICES]; // Array to keep track of visited vertices

// DFS algorithm
void DFS(int current, int target) {
    visited[current] = true;
    printf("%d ", current); // Print the current vertex

    if (current == target) {
        printf("\nTarget vertex found\n");
        return;
    }

    for (int i = 0; i < MAX_VERTICES; i++) {
        if (graph[current][i] == 1 && !visited[i])
            DFS(i, target);
    }
}

int main() {
    int start = 0; // Starting vertex
    int target = 4; // Target vertex
    printf("DFS traversal: ");
    DFS(start, target);
    return 0;
}

输出结果为:
DFS traversal: 0 1 3 2 4 
Target vertex found
这段代码实现了深度优先搜索算法,

并在示例图中找到了从顶点 0 到顶点 4 的路径之一。

  • 27
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值