探索搜索算法:从顺序到启发式的多种搜索方法

探索搜索算法:从顺序到启发式的多种搜索方法

搜索算法在计算机科学中起着至关重要的作用,帮助我们在大量数据中查找目标值、解决问题,或者找到最优解。本文将深入介绍不同类型的搜索算法,包括顺序搜索、二分搜索、插值搜索、哈希搜索、深度优先搜索、广度优先搜索、A*搜索以及启发式搜索,每种算法都有相应的Java代码示例。

1. 顺序搜索(Sequential Search)

顺序搜索是一种简单的搜索算法,逐个遍历列表中的元素,直到找到目标值。

代码示例

public class SequentialSearch {

    public static int sequentialSearch(int[] array, int target) {
        for (int i = 0; i < array.length; i++) {
            if (array[i] == target) {
                return i;
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        int[] array = {3, 6, 8, 10, 15, 21, 25};
        int target = 15;
        int index = sequentialSearch(array, target);
        if (index != -1) {
            System.out.println("目标值 " + target + " 在索引 " + index + " 处找到。");
        } else {
            System.out.println("目标值 " + target + " 未找到。");
        }
    }
}

2. 二分搜索(Binary Search)

二分搜索适用于已排序的列表,通过重复地将列表一分为二,并判断目标值在哪一半中,从而快速找到目标值。

代码示例

public class BinarySearch {

    public static int binarySearch(int[] array, int target) {
        int left = 0;
        int right = array.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (array[mid] == target) {
                return mid;
            }
            if (array[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        int[] array = {3, 6, 8, 10, 15, 21, 25};
        int target = 15;
        int index = binarySearch(array, target);
        if (index != -1) {
            System.out.println("目标值 " + target + " 在索引 " + index + " 处找到。");
        } else {
            System.out.println("目标值 " + target + " 未找到。");
        }
    }
}

3. 插值搜索(Interpolation Search)

插值搜索是一种在已排序数组中定位目标值的搜索算法,它根据目标值在范围内的估计位置来决定搜索的方向。

代码示例

public class InterpolationSearch {

    public static int interpolationSearch(int[] array, int target) {
        int left = 0;
        int right = array.length - 1;
        while (left <= right && target >= array[left] && target <= array[right]) {
            int pos = left + ((target - array[left]) * (right - left)) / (array[right] - array[left]);
            if (array[pos] == target) {
                return pos;
            }
            if (array[pos] < target) {
                left = pos + 1;
            } else {
                right = pos - 1;
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        int[] array = {3, 6, 8, 10, 15, 21, 25};
        int target = 15;
        int index = interpolationSearch(array, target);
        if (index != -1) {
            System.out.println("目标值 " + target + " 在索引 " + index + " 处找到。");
        } else {
            System.out.println("目标值 " + target + " 未找到。");
        }
    }
}

4. 哈希搜索(Hash Search)

哈希搜索利用哈希表的特性,通过计算目标值的哈希值找到对应的位置,从而快速找到目标值。

代码示例

public class HashSearch {

    public static int hashSearch(int[] array, int target) {
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < array.length; i++) {
            map.put(array[i], i);
        }
        if (map.containsKey(target)) {
            return map.get(target);
        }
        return -1;
    }

    public static void main(String[] args) {
        int[] array = {3, 6, 8, 10, 15, 21, 25};
        int target = 15;
        int index = hashSearch(array, target);
        if (index != -1) {
            System.out.println("目标值 " + target + " 在索引 " + index + " 处找到。");
        } else {
            System.out.println("目标值 " + target + " 未找到。");
        }
    }
}

5. 深度优先搜索(DFS)

深度优先搜索是一种遍历图或树的算法,它从起始节点开始,沿着一条路径尽可能深入,直到无法继续为止,然后回退并尝试其他路径。

代码示例

import java.util.ArrayList;
import java.util.List;

public class DepthFirstSearch {

    static class Graph {
        private int vertices;
        private List<List<Integer>> adjacencyList;

        Graph(int vertices) {
            this.vertices = vertices;
            adjacencyList = new ArrayList<>(vertices);
            for (int i = 0; i < vertices; i++) {
                adjacencyList.add(new ArrayList<>());
            }
        }

        void addEdge(int source, int destination) {
            adjacencyList.get(source).add(destination);
        }

        void DFS(int startVertex) {
            boolean[] visited = new boolean[vertices];
            DFSRecursive(startVertex, visited);
        }

        void DFSRecursive(int vertex, boolean[] visited) {
            visited[vertex] = true;
            System.out.print(vertex + " ");

            List<Integer> neighbors = adjacencyList.get(vertex);
            for (int neighbor : neighbors) {
                if (!visited[neighbor]) {
                    DFSRecursive(neighbor, visited);
                }
            }
        }
    }

    public static void main(String[] args) {
        Graph graph = new Graph(5);
        graph.addEdge(0, 1);
        graph.addEdge(0, 2);
        graph.addEdge(1, 3);
        graph.addEdge(2, 4);

        System.out.println("深度优先搜索结果:");
        graph.DFS(0);
    }
}

6. 广度优先搜索(BFS)

广度优先搜索也是一种遍历图或树的算法,它从起始节点开始,逐层扩展,先访问距离起始节点近的节点。

代码示例

import java.util.LinkedList;
import java.util.Queue;

public class BreadthFirstSearch {

    static class Graph {
        private int vertices;
        private LinkedList<Integer>[] adjacencyList;

        Graph(int vertices) {
            this.vertices = vertices;
            adjacencyList = new LinkedList[vertices];
            for (int i = 0; i < vertices; i++) {
                adjacencyList[i] = new LinkedList<>();
            }
        }

        void addEdge(int source, int destination) {
            adjacencyList[source].add(destination);
        }

        void BFS(int startVertex) {
            boolean[] visited = new boolean[vertices];
            Queue<Integer> queue = new LinkedList<>();
            visited[startVertex] = true;
            queue.offer(startVertex);

            while (!queue.isEmpty()) {
                int vertex = queue.poll();
                System.out.print(vertex + " ");

                for (int neighbor : adjacencyList[vertex]) {
                    if (!visited[neighbor]) {
                        visited[neighbor] = true;
                        queue.offer(neighbor);
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        Graph graph = new Graph(5);
        graph.addEdge(0, 1);
        graph.addEdge(0, 2);
        graph.addEdge(1, 3);
        graph.addEdge(2, 4);

        System.out.println("广度优先搜索结果:");
        graph.BFS(0);
    }
}

7. A*搜索算法

A*搜索算法是一种启发式搜索算法,用于在图中找到最短路径。它同时考虑路径的代价和启发式估计值,以找到一个较优的路径。

代码示例

import java.util.*;

public class AStarSearch {

    static class Node implements Comparable<Node> {
        int vertex;
        int distance;
        int heuristic;

        Node(int vertex, int distance, int heuristic) {
            this.vertex = vertex;
            this.distance = distance;
            this.heuristic = heuristic;
        }

        @Override
        public int compareTo(Node other) {
            return Integer.compare(distance + heuristic, other.distance + other.heuristic);
        }
    }

    static class Graph {
        private int vertices;
        private List<List<Node>> adjacencyList;

        Graph(int vertices) {
            this.vertices = vertices;
            adjacencyList = new ArrayList<>(vertices);
            for (int i = 0; i < vertices; i++) {
                adjacencyList.add(new ArrayList<>());
            }
        }

        void addEdge(int source, int destination, int weight) {
            adjacencyList.get(source).add(new Node(destination, weight, 0));
        }

        int AStar(int startVertex, int goalVertex) {
            PriorityQueue<Node> priorityQueue = new PriorityQueue<>();
            int[] distances = new int[vertices];
            Arrays.fill(distances, Integer.MAX_VALUE);
            distances[startVertex] = 0;

            priorityQueue.offer(new Node(startVertex, 0, heuristic(startVertex, goalVertex)));

            while (!priorityQueue.isEmpty()) {
                Node current = priorityQueue.poll();

                if (current.vertex == goalVertex) {
                    return current.distance;
                }

                for (Node neighbor : adjacencyList.get(current.vertex)) {
                    int tentativeDistance = distances[current.vertex] + neighbor.distance;
                    if (tentativeDistance < distances[neighbor.vertex]) {
                        distances[neighbor.vertex] = tentativeDistance;
                        priorityQueue.offer(new Node(neighbor.vertex, tentativeDistance, heuristic(neighbor.vertex, goalVertex)));
                    }
                }
            }

            return -1; // No path found
        }

        int heuristic(int currentVertex, int goalVertex) {
            // Replace with appropriate heuristic function
            return 0;
        }
    }

    public static void main(String[] args) {
        Graph graph = new Graph(5);
        graph.addEdge(0, 1, 4);
        graph.addEdge(0, 2, 1);
        graph.addEdge(1, 3, 1);
        graph.addEdge(2, 3, 5);
        graph.addEdge(2, 4, 3);
        graph.addEdge(3, 4, 2);

        int startVertex = 0;
        int goalVertex = 4;
        int distance = graph.AStar(startVertex, goalVertex);

        if (distance != -1) {
            System.out.println("A*搜索结果:从节点 " + startVertex + " 到节点 " + goalVertex + " 的最短路径距离为 " + distance);
        } else {
            System.out.println("无法找到从节点 " + startVertex + " 到节点 " + goalVertex + " 的路径。");
        }
    }
}

8. 启发式搜索算法

启发式搜索算法通过启发式函数(heuristic function)来指导搜索方向,以期望更快地找到目标状态或解。

代码示例(以A*搜索为例):

// 请参考前面的A*搜索算法示例

总结

搜索算法在计算机科学和人工智能

领域中具有重要作用。本文深入介绍了不同类型的搜索算法,包括顺序搜索、二分搜索、插值搜索、哈希搜索、深度优先搜索、广度优先搜索、A*搜索以及启发式搜索。通过理解这些算法的工作原理和示例代码,您可以更好地应用它们来解决各种问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不一样的老墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值