“二叉树查找算法&Floyd最短路径算法”解析

二叉树

二叉树算法简介

相较于二叉树查找算法,普通的循环查找算法的劣势在于:

 

二叉树算法采用二分法的思想,其操作原理如下:

二分查找的思想很简单,对一个“有序序列a(序列必须先进行排序操作)”,要查找某个元素x,则可以让x先和a的中

间元素比较:

① 如果相等,则成功;

② 如果小于中间元素.则在a的左半区间查找;

③ 如果大于或等于中间元素,则在a的右半区间查找。

图5-4是在一个有序序列中查找25的过程,其中I,、 H 、 Middle分别表不当前查找区间

的左、右和中间位置。

 

可用一个循环迭代过程,不断更新区间的左、右位置(L 、 H)和中间位置(Middle)三个指示器来查找。

二叉树算法代码原理解析

 

二叉树程序实现

#include <iostream>  
#include <algorithm>  
#include <functional>  
using namespace std;  
  
int main()  
{  
    int arr[] = { 1,2,3,4,5,6,7,8,9 };  
    int L = 0, H = sizeof(arr) / sizeof(int), x = 0;  
    cin >> x;  
  
    while (L <= H)  
    {  
        int Middle{ (L + H) / 2 };  
        if (arr[Middle] == x)  
        {  
            break;  
        }  
        else if (arr[Middle] > x)  
        {  
            H = Middle;  
        }  
        else if (arr[Middle] < x)  
        {  
            L = Middle;  
        }  
    }  
    if (L <= H)  
    {  
        cout << "找到了目标值" << endl;  
    }  
    else  
    {  
        cout << "未找到目标值" << endl;  
    }  
} 

 

Floyd算法

Floyd算法的原理解析

 

当我们想要求解①->⑤的最短路径时,我们进行如下操作:

① 先建立“用于存储两点之间的距离的5*5矩阵Distance”与“记录倒数第二个点的同维度矩阵Pointer”

② 我们先找到“是否以一点P使得Distance[①,P]+Distance[P,②]<Distance[①,②]”,如果有则更新Distance[①,②]= Distance[①,P]+Distance[P,②],并且更新Pointer[①,②]=P;

③ 找到这个中间节点,我们可以在用此方法查找“是否有一点E使得Distance[①,E] +Distance[E,P]<Distance[①,P]”,如果存在则更新Distance[①,P]= Distance[①,E] +Distance[E,P]且Pointer[①,P]=E;

④我们这样的逐步细分下去,直到“不存在一点Y使得Distance[①,Y]+Distance[Y,N]<Distance[①,N]”,由此我们得到了①->P之间的最短路径。

⑤ 将两个最短路径[①,P]与[P,②]进行拼接,我们可以得到①->②的最短路径,其实,当我们找出①->②中间的桥梁P,我们只需进一步分析①->P之间的最短路径即可。

如何根据路径矩阵Pointer查看x->y点的最短路径呢?

 

我们想要了解“1(始)->0(末)的最短路径”,首先Pointer[1,0]=3,说明1点,0点两点之间的桥梁为3点,我们再进一步分析1点到3点之间的最短距离,Pointer[1,3]=2说明1点,3点之间有一个桥梁(1->3路径的倒数第二个点)2点,然后我们进一步分析2点->1点之间的最短路径,Pointer[1,2]=1当我们看见1->2的倒数第二个点为1点(1->2路径的起点),就说明“不存在一个点使得1->2之间的距离比Distance[1,2]更小”。

最终,我们得到“一个逆向路径”:0(终点)->3->2->1(起点)。

Floyd算法代码示例

#include <iostream>  
#include <iomanip>  
#include <limits>  
using namespace std;  
  
int main()  
{  
    int n = 4;  
    int INFINITE = INT_MAX;  
    unsigned int Distance[][4] = { {0,2,6,4},{INFINITE,0,3,INFINITE},{7,INFINITE,0,1},{5,INFINITE,12,0} };  
    // 初始化路径矩阵  
    decltype(Distance) Pointer = { 0 };  
    for (int u = 0; u < n; u++)  
    {  
        for (int v = 0; v < n; v++)  
        {  
            Pointer[u][v] = u;  
        }  
    }  
  
    // 显示初始的uv之间的距离与uv路径之间中倒数第二个点  
    for (int u = 0; u < n; u++)  
    {  
        for (int v = 0; v < n; v++)  
        {  
            cout << setw(10) << setfill(' ') << Distance[u][v] << ' ';  
        }  
        cout << '\n';  
    }  
    for (int u = 0; u < n; u++)  
    {  
        for (int v = 0; v < n; v++)  
        {  
            cout << Pointer[u][v] << ' ';  
        }  
        cout << '\n';  
    }  
    // Floyd算法  
    for (int w = 0; w < n; w++)  
    {  
        for (int u = 0; u < n; u++)  
        {  
            for (int v = 0; v < n; v++)  
            {  
                if (w != u && w != v && Distance[u][w] + Distance[w][v] < Distance[u][v] && u != v)  
                {  
                    Pointer[u][v] = w;  
                    Distance[u][v] = Distance[u][w] + Distance[w][v];  
                }  
            }  
        }  
    }  
    // u->v的最短路径  
    for (int u = 0; u < n; u++)  
    {  
        for (int v = 0; v < n; v++)  
        {  
            if (u == v) continue;  
            cout << u << "到" << v << "的逆向路径是:" << v << ',';  
            for (int w = Pointer[u][v]; w != u; )  
            {  
                cout << w << ',';  
                w = Pointer[u][w];  
            }  
            cout << u << " ; " << "其最短距离为" << Distance[u][v] << endl;  
        }  
    }  
} 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

肥肥胖胖是太阳

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

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

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

打赏作者

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

抵扣说明:

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

余额充值