검색 알고리즘(순차 검색, 이진 검색, 차이 검색, 피보나치 검색, 트리 테이블 검색, 블록 검색, 해시 검색)

1. 순차 검색: 대상 값을 찾거나 데이터 세트를 순회할 때까지 데이터 세트의 한쪽 끝에서 하나씩 검색하고 비교합니다. 소량 또는 주문되지 않은 수량에 유용합니다.

using System;

namespace SearchAlgorithm
{
    internal class Program
    {
        static int SequentialSearch(int[] arr,int key)
        {
            for(int i=0; i < arr.Length; i++)
            {
                if(arr[i] == key)
                {
                    return i;
                }
            }
            return -1;
        }
        static void Main(string[] args)
        {
            int[] arr = {4,3,-2,8,1};
            Console.WriteLine(arr[SequentialSearch(arr, 8)]);
        }
    }
}

2. 이진 검색: 데이터 순서(오름차순 또는 내림차순)로 검색합니다. 데이터 세트의 중간 요소에서 검색 비교를 시작하고 중간 요소의 인덱스를 반환합니다. 목표 값이 가운데 값보다 작으면 가운데 값의 왼쪽 끝(오름차순) 또는 오른쪽 끝(내림차순)을 새로운 데이터셋으로 사용하는 식으로 왔다 갔다 합니다.

using System;

namespace SearchAlgorithm
{
    internal class Program
    {
        static int BinarySearch(int[] arr,int key)
        {
            int left = 0;
            int right = arr.Length-1;
            while (left <= right)
            {
                int mid = (left + right) / 2;//计算中间值的索引
                if(arr[mid] == key)
                {
                    return mid;
                }
                else if (arr[mid]<key)
                {
                    left = mid+1;
                }
                else
                {
                    right = mid-1;
                }
            }
            return -1;
        }
        static void Main(string[] args)
        {
            int[] arr = {1,3,5,8,10,13};//有序的前提
            Console.WriteLine(arr[BinarySearch(arr, 8)]);
        }
    }
}

3. 차이 검색: 차이 비율에 따라 검색하는 이진 검색의 최적화입니다. 데이터 집합의 요소가 고르게 분포되어 있으면 차이 검색의 효율성이 상대적으로 높고, 반복 횟수가 많거나 불연속적인 분포와 같이 데이터의 요소가 고르지 않게 분포되어 있으면 검색 효율성이 상대적으로 낮습니다.

using System;

namespace SearchAlgorithm
{
    internal class Program
    {
        static int InterpolationSearch(int[] arr,int key)
        {
            int low = 0;
            int high = arr.Length-1;
            while (low <= high)
            {
                int pos = low + (key - arr[low]) / (arr[high] - arr[low])*(high-low);
                if(arr[pos] == key)
                {
                    return pos;
                }
                else if (arr[pos]<key)
                {
                    low = pos+1;
                }
                else
                {
                    high = pos-1;
                }
            }
            return -1;
        }
        static void Main(string[] args)
        {
            int[] arr = {1,3,5,8,10,13};//有序的前提
            Console.WriteLine(InterpolationSearch(arr, 8)]);
        }
    }
}

4. 피보나치 찾기

using System;

namespace SearchAlgorithm
{
    internal class Program
    {
        static int[] Fibonacci(int n)
        {
            int[] f = new int[n + 1];
            f[0] = 0;
            f[1] = 1;
            for (int i = 2; i <= n; i++)
            {
                f[i] = f[i - 1] + f[i - 2];
            }
            return f;
        }
        static int FibonacciSearch(int[] arr, int key)
        {
            int n = arr.Length;
            int[] f = Fibonacci(n);//获取斐波那契数列
            int k = 0;//表示斐波那契分割数值的下标
            //获取斐波那契分割数值的下标
            while (n > f[k] - 1)
            {
                k++;
            }
            int[] temp = new int[f[k] - 1];
            //因为f[k]-1的值可能大于arr的长度,所以将arr的值复制到新的数组中
            Array.Copy(arr, temp, n);
            //填充适用arr数组最后的数填充temp,使它保持有序
            for (int i = n; i < f[k] - 1; i++)
            {
                temp[i] = arr[n - 1];
            }
            int left = 0;
            int right = n - 1;
            //适用while来找key
            while (left <= right)
            {
                int mid = left + f[k - 1] - 1;
                if (key < temp[mid])
                {
                    right = mid - 1;//继续向左边的元素查找
                    k--;//f[k-1]=f[k-2](左边)+f[k-3](右边);
                }
                else if (key > temp[mid])
                {
                    left = mid + 1;//继续向右边的元素查找
                    k -= 2;
                }
                else
                {
                    if (mid < n)
                    {
                        return mid;
                    }
                    else
                    {
                        return n - 1;
                    }
                }
            }
            return -1;
        }
        static void Main(string[] args)
        {
            int[] arr = { 1, 3, 5, 8, 10, 13 };//有序的前提
            Console.WriteLine(arr[FibonacciSearch(arr, 13)]);
        }
    }
}

084-Silicon Valley-Graphic Java 데이터 구조 및 알고리즘-Fibonacci 검색 코드 구현.avi_哔哩哔哩_bilibili

5. 트리 테이블 조회

using System;

namespace SearchAlgorithm
{
    internal class Program
    {
        static TreeNode insert(TreeNode root, int data)//以递归的形式插入数据
        {
            if (root == null)
                return new TreeNode(data);
            if (data < root.data)
                root.left = insert(root.left, data);
            else if (data > root.data)
                root.right = insert(root.right, data);
            return root;
        }
        static bool TreeTableSearch(TreeNode root, int key)//递归查找
        {
            if (root == null)
                return false;
            if (root.data == key)
                return true;
            if (root.data > key)
                return TreeTableSearch(root.left, key);
            return TreeTableSearch(root.right, key);
        }
        static void Main(string[] args)
        {
            int[] arr = {1,3,5,8,10,13};
            TreeNode root = null;
            for(int i=0;i<arr.Length;i++)
            {
                root = insert(root, arr[i]);//向树中插入数据
            }
            if(TreeTableSearch(root,10))
            {
                Console.WriteLine("找到了");
            }
        }
    }
    class TreeNode
    {
        public int data;
        public TreeNode left, right;
        public TreeNode(int data)
        {
            this.data = data;
            left = right = null;
        }
    }
}

6. 블록 검색

using System;
using System.Collections.Generic;

namespace SearchAlgorithm
{
    internal class Program
    {
        static int blockSearch(int[] arr, int key, int blockSize)//基于块内无序,且块与块之间有序
        {
            int n = arr.Length;
            int blockCount = (int)Math.Ceiling((double)n / blockSize);//表示数组分块后的块的数量
            List<int[]> blocks = new List<int[]>();
            //将数组中的元素放入块数组中,再将块数组放入blocks链表中
            for (int i = 0; i < blockCount; i++)
            {
                int[] block = new int[blockSize];
                for (int j = 0; j < blockSize; j++)
                {
                    int index = i * blockSize + j;
                    if (index < n)
                        block[j] = arr[index];
                    else
                        break;
                }
                blocks.Add(block);
            }
            int blockIndex = -1;//记录key所在的块数组的索引
            //找到key所在的块数组
            for (int i = 0; i < blockCount; i++)
            {
                if (key <= blocks[i][blockSize - 1])
                {
                    blockIndex = i;
                    break;
                }
            }
            if (blockIndex == -1)
                return -1;
            int[] blockArr = blocks[blockIndex];//key所在的块数组
            //找到key再arr中的索引
            for (int i = 0; i < blockSize; i++)
            {
                if (blockArr[i] == key)
                    return blockIndex * blockSize + i;
            }
            return -1;
        }
        static void Main(string[] args)
        {
            int[] arr = {1,3,5,8,10,13};
            int blockSize = 3;
            Console.WriteLine(arr[blockSearch(arr, 10, blockSize)]);
        }
    }
}

【Tianqin PubMed】블록 검색_哔哩哔哩_bilibili

7. 해시 조회

using System;
using System.Collections.Generic;

namespace SearchAlgorithm
{
    internal class Program
    {
        static int HashValue(int x)//计算哈希值
        {
            return x % 10;
        }
        static void HashSearch(int[] arr,int key)
        {
            Dictionary<int, int> dict = new Dictionary<int, int>();//存储哈希值对应的数组元素
            //计算对应的数组元素的哈希值,并将哈希值和数组元素存储字典
            for (int i = 0; i < arr.Length; i++)
            {
                int index = HashValue(arr[i]);
                if (!dict.ContainsKey(index))
                    dict.Add(index, arr[i]);
                else // 如果该位置已经有元素,则使用开放地址法解决冲突
                {
                    while (dict.ContainsKey(index))
                        index = (index + 1) % 10;
                    dict.Add(index, arr[i]);
                }
            }
            int hash = HashValue(key); // 计算要查找的数组元素的哈希值
            if (dict.ContainsKey(hash))
            {
                if (dict[hash]==key)
                {
                    Console.WriteLine("找到了");
                }
            }
        }
        static void Main(string[] args)
        {
            int[] arr = {1,3,5,8,10,13};
            HashSearch(arr, 10);
        }
    }
}

 결론: 품는 나무는 머리카락 끝에서 태어나고, 구층대는 흙더미에서 시작되며, 천리 길도 한 걸음부터 시작된다.

Supongo que te gusta

Origin blog.csdn.net/falsedewuxin/article/details/130298001
Recomendado
Clasificación