找出一个二维数组的鞍点

为什么下面的代码会同时输出78而不是鞍点呢

#include <stdio.h>

int main()
{
int a[][2]={1,3,7,8};
    int i,k,max[2],min[2],t;
    
    for(k=0;k<2;k++)
    {
        for(max[k]=a[0][k],i=0;i<2;i++)
        {
            if(max[k]<a[i][k])
            {
                max[k]=a[i][k];
            }
        
        }
    }
    
    for(t=0;t<2;t++)
    {
        for(min[t]=a[t][0],i=0;i<2;i++)
        {
            if(min[t]>a[t][i])
            {
                min[t]=a[t][i];
            }
        
        }
    }
    
    for(k=0;k<2;k++)
    {
        if(min[k]==max[k])
        printf("%d",min[k]);
    }

    return 0;
}

你的程序应该根本没有输出

img

  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7738416
  • 这篇博客你也可以参考下:数据结构二叉树先序遍历,输出结点所在层次和某结点的双亲结点
  • 除此之外, 这篇博客: 【数据结构初阶】新学期带你领跑二叉树,二叉树的迭代遍历,递归遍历详解,建议收藏中的 2.1前序遍历 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • leetcode. 二叉树的前序遍历
    在这里插入图片描述
    前提提示:
    一.这里的NULL我们不用访问,访问在这里相当于入一个数组(vector),不懂的同学先把他当成数组!
    二. 以及这里所说的最左列为当前节点一直递归它的左子树,即上图的1 , 2,4

    在这里插入图片描述

    分析:我们想要利用栈对我们的二叉树进行前序遍历,我们可以观察前序遍历的时候会先遍历
    1–>2–>4,我们一边遍历一边将遍历的值放入栈中看看。发现这棵树的话只剩下4,2,1的右子树就可以走完了!!!!

    在这里插入图片描述
    如何遍历右子树呢? 实际上我们观察**(3)这颗子树我们可以发现什么,我们没有办法通过一次操作遍历完右子树,但是我们可以把3这颗子树进行拆分,我们入它的最左列节点访问再进行入栈**,就相当于遍历了(3)的左子树与每个节点的根(细品),这个时候我们遍历(7)是不是就是一次操作就能解决了?其实还可以再分一次,分到像(5)的时候,当节点的右子树为空树的时候,我们就访问他!!!


    重要:
    一棵树一定能分到没有右子树的时候,这时访问当前节点相当于访问上一个根节点的右子树
    一棵树一定能分到没有右子树的时候,这时访问当前节点相当于访问上一个根节点的右子树
    一棵树一定能分到没有右子树的时候,这时访问当前节点相当于访问上一个根节点的右子树
    就像访问5的时候是不是相当于访问了2的右子树?是的!


    💖💖💖💖💖💖
    上面没看懂,没关系,带大家再走一下每一个步骤
    💖💖💖💖💖💖
    这里再拆分一下每一个步骤

    刚开始在这里插入图片描述

    第一步:我们就访问每一个节点并且入栈(将1,2,4入栈并且放入数组),这时候我们要拿出栈顶的4,将它的右子树的最左列入栈(NULL不入栈),我们重复此操作,到2的时候,我们将它的右子树(5)及其最左列入栈并且访问,并且把2出栈,这时候的栈只有(5,1)在这里插入图片描述

    重复上述操作,取栈顶数据,将栈顶数据的右子树的最左列入栈之后将原栈顶数据出栈,这里5右子树为NULL不用入栈,我们栈里就只剩下1,接着入1的右子树的最左列,即3,6入栈
    在这里插入图片描述

    重复上述操作,取栈顶数据,将栈顶数据的右子树的最左列入栈之后将原栈顶数据出栈,6无右子树,就弹出了,到3的时候把3的右子树最左列带入(7),最后栈里面还有一个7在这里插入图片描述
    重复上述操作,取栈顶数据,将栈顶数据的右子树的最左列入栈之后将原栈顶数据出栈,把7出掉,结束!!!!

    class Solution {
    public:
        vector<int> preorderTraversal(TreeNode* root) {
            //利用栈进行迭代遍历
            //思路:每次遍历当前节点(cur)的左子树,再进行入栈,最后从栈中依次取出以相同的方式遍历右子树
            //可以先入最左的树
            TreeNode* cur =root;
            vector<int> retArr;//用来返回的答案
            stack<TreeNode*> s;//利用栈进行迭代遍历
            while(cur)
            {
                retArr.push_back(cur->val);
                s.push(cur);
                cur = cur->left;
            }
            //现在只要遍历栈当中的所有的右子树就遍历完所有树
            //当然遍历每个右子树也不是一次就能搞定的,我们分解成遍历每个右子树和他的左子树,...在遍历他的右子树,就类似我们的递归遍历
            while(!s.empty())
            {
                //我们可以对于栈当中的右子树一个一个处理
                cur = s.top();
                s.pop();
                cur = cur->right;
                //将右子树的最左列也都入栈
                while(cur)
                {
                    //每个右子树又会带出更多的右子树....
                    retArr.push_back(cur->val);
                    s.push(cur);
                    cur =cur->left;
                }
            }
            return retArr;
        }
    };
    

    在这里插入图片描述

    //分析子过程,这里是第一步,将root即右子树的最左列入栈
     while(cur)
    {
         //每个右子树又会带出更多的右子树....
         retArr.push_back(cur->val);
         s.push(cur);
         cur =cur->left;
     }
    

    总结,我们面对这种题都可以先入该节点及它的最左列节点,然后我们上面这一段代码再去带出右子树当中的最左列,当我们带出来的时候相当于所有的根与左子树已经遍历完了,我们只用对右子树处理。右子树又可以被继续拆分!!!

     while(!s.empty())
            {
                //我们可以对于栈当中的右子树一个一个处理
                cur = s.top();
                s.pop();
    //取出当前节点所有的右子树,没有就在后面的循环中拿出这个值(相当于访问上一个根的右子树)
                cur = cur->right;
                //将右子树的最左列也都入栈
                while(cur)
                {
                    //每个右子树又会带出更多的右子树....
                    retArr.push_back(cur->val);
                    s.push(cur);
                    cur =cur->left;
                }
            }
    

  • 您还可以看一下 朱有鹏老师的巫妖王51单片机开发板配套视频课程课程中的 测试确认开发板硬件完好2小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    问题回答: 要找出一个二维数组的鞍点,需要满足在该行上最大,在该列上最小,可以通过双重循环比对每一个元素,找到符合条件的元素即为鞍点。

    下面的代码输出78而不是鞍点,是因为只是打印了第三行,没有比对每一个元素找到符合条件的鞍点。需要在函数内部增加比对每一个元素的代码,以下是修改后的代码:

    int findSaddlePoint(int arr[][5], int rowSize, int colSize){
        int saddle = -1; // 记住鞍点
        for(int i = 0; i < rowSize; ++i){
            int minInRow = arr[i][0]; // 找到一行中的最小值
            int pos = 0; // 最小值在该行的列
            for(int col = 1; col < colSize; ++col){ // 找到该行中的最小数和列位置
                if(arr[i][col] < minInRow){
                    minInRow = arr[i][col];
                    pos = col;
                }
            }
            bool found = true; // 判断是否为鞍点
            for(int j = 0; j < rowSize; ++j){
                if(arr[j][pos] > minInRow){ // 不满足最小条件为非鞍点
                    found = false;
                    break;
                }
            }
            if(found){ // 如果是鞍点则返回
                saddle = minInRow;
                break;
            }
        }
        return saddle;
    }
    
    int main(){
        int arr[3][5] = { {1,2,3,4,5} ,{2,3,4,5,6}, {3,4,5,6,7} };
        int saddle = findSaddlePoint(arr, 3, 5);
        if(saddle == -1){
            cout << "该二维数组不存在鞍点" << endl;
        }else{
            cout << "该二维数组的鞍点为: " << saddle << endl;
        }
        return 0;
    }
    

    输出结果将会是 "该二维数组不存在鞍点",因为该数组不存在鞍点。

    解释:

    先在每行中找到最小值和其位置,如果存在某一行的最小值不是该列上的最大值,则不是鞍点。所有行都找完则没有鞍点。同时增加了找到鞍点后返回的代码,将鞍点值直接返回。