C语言实现在随机杨氏矩阵中查找一个数

分析:

整体思路主要分为如下两部分:
这里写图片描述


主函数:
int main()
{
    int arr[N][N] = {0};
    int num = 0;
    int ret = 0;
    int sz = sizeof(arr)/sizeof(arr[0][0]);
    srand((unsigned int)time(NULL));
    InitArr(arr,sz); //初始化数组
    printf("请输入要查找的数字:\n");
    scanf("%d",&num);
    ret = Find(arr,num,sz); //在杨氏矩阵中查找数字
    if(ret == 1)
    {
        printf("找到了\n");
    }
    else
    {
        printf("没找到\n");
    }
    Print(arr); //输出杨氏矩阵
    return 0;
}

一、初始化数组

杨氏矩阵的特点是:这个矩阵中的数字从左到右是递增的,从上到下也是递增的。
如:
这里写图片描述
左边矩阵是对角线有规律的,右边矩阵是我们所要实现的递增量为随机值的杨氏矩阵。
在写代码前,应该了解到,数组在内存中的存储是链式存储,如下图所示:
这里写图片描述
调试程序,对数组进行初始化,通过查看内存,可以看到数组在内存中的存储确实为链式存储,如下图:
这里写图片描述
我们可以利用数组的这一优点来初始化数组,通过一个指针,改变它的指向并修改它所指向的内容,每次的增量为随机量,即为我们所要求的增量为随机量的杨氏矩阵。
函数代码如下:

void InitArr(int arr[][N], int sz)
{
    int i = 1;
    int *p = &arr[0][0];  //使指针指向数组的第一个元素
    *p = rand()%10+1;  //给第一个元素赋随机值,随机值的范围从1-10
    while(i<sz)
    {
        *(p+1) = *p + rand()%10+1; //给数组中的其余元素赋值,
                                   //其元素值是前一个元素值加上随机增量值得到
        p++;
        i++;
    }
}

二、查找元素

此阶段可以分为两种方法:

(一)二分查找法

同样根据数组的链式存储原理来寻找所要查的数字。
二分查找的思路如下:
left指针指向数组的开头元素,right指针指向数组的末尾元素,找到数组的中间位置为mid,如图:这里写图片描述
如果,元素大于中间位置元素,left指向中间元素后一位置,中间值发生改变;
如果,元素小于中间位置元素,right指向中间元素前一位置,中间值发生改变;
直至找到所找元素或left大于right时结束循环。
函数代码如下:

int Find(int arr[][N], int num, int sz)
{
    int *left = &arr[0][0];
    int *right = &arr[N-1][N-1];
    int mid = sz/2;
    int ret = 0;
    while(left<=right)
    {
        if(num<(*(left+mid)))
        {
            right = left+mid-1;
            mid /= 2;
        }
        else if(num>(*(left+mid)))
        {
            left = left+mid+1;
            mid += mid/2; 
        }
        else if(num == (*(left+mid)))
        {
            ret = 1;
            break;
        }
    }
    return ret;
}
(二)杨氏矩阵查找法

这种方法先确定一个参考位置(参考位置确定为矩阵右上角元素),若要查找元素大于参考位置元素的话,向下查找;若要查找元素小于参考位置元素的话,向左查找;反复执行上述过程,直到找到该元素或者矩阵中元素查找完毕没有找到后结束循环。
如:要在下图所示矩阵中找到数字45,参考位置元素为17,45大于17,参考位置向下走;来到41上,45大于41,参考位置再向下走;来到57,45小于57,参考位置向左走;来到48,45小于48,参考位置再向下走;来到45,45等于45,找到该元素。
这里写图片描述
函数代码如下:

int Find(int arr[][N], int num, int sz)
{
    int i = 0;
    int j = N-1;
    int ret = 0;
    while(i<N && j>0)
    {
        if(num > arr[i][j])
        {
            i++;
        }
        else if(num < arr[i][j])
        {
            j--;
        }
        else 
        {
            ret = 1;
            break;
        }
    }
    return ret;
}

整体代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 3
void InitArr(int arr[][N], int sz)
{
    int i = 1;
    int *p = &arr[0][0];
    *p = rand()%10+1;
    while(i<sz)
    {
        *(p+1) = *p + rand()%10+1; 
        p++;
        i++;
    }

}

void Print(int arr[][N])
{
    int i = 0;
    int j = 0;
    for(i=0; i<N; i++)
    {
        for(j=0; j<N; j++)
        {
            printf("%3d ",arr[i][j]);
        }
        printf("\n");
    }
}
//二分查找实现
int Find(int arr[][N], int num, int sz)
{
    int *left = &arr[0][0];
    int *right = &arr[N-1][N-1];
    int mid = sz/2;
    int ret = 0;
    while(left<=right)
    {
        if(num<(*(left+mid)))
        {
            right = left+mid-1;
            mid /= 2;
        }
        else if(num>(*(left+mid)))
        {
            left = left+mid+1;
            mid += mid/2; 
        }
        else if(num == (*(left+mid)))
        {
            ret = 1;
            break;
        }
    }
    return ret;
}

//杨氏矩阵查找实现
//int Find(int arr[][N], int num, int sz)
//{
//  int i = 0;
//  int j = N-1;
//  int ret = 0;
//  while(i<N && j>0)
//  {
//      if(num > arr[i][j])
//      {
//          i++;
//      }
//      else if(num < arr[i][j])
//      {
//          j--;
//      }
//      else 
//      {
//          ret = 1;
//          break;
//      }
//  }
//  return ret;
//}
//
int main()
{
    int arr[N][N] = {0};
    int num = 0;
    int ret = 0;
    int sz = sizeof(arr)/sizeof(arr[0][0]);
    srand((unsigned int)time(NULL));
    InitArr(arr,sz);
    printf("请输入要查找的数字:\n");
    scanf("%d",&num);
    ret = Find(arr,num,sz);
    if(ret == 1)
    {
        printf("找到了\n");
    }
    else
    {
        printf("没找到\n");
    }
    Print(arr);
    return 0;
}

运行结果

这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/cottonrose_orange/article/details/81190227