二叉树:广度优先遍历

/*
    广度优先遍历的实现:

    与深度优先遍历比较,将栈换成了队列。同时,修改了部分bug:增加函数返回值的判断操作
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define QElemType unsigned int

typedef struct __ElemType
{
    int y;
    int x;
}ElemType;

typedef struct __queueInfo{
    ElemType *pData;
    QElemType front;
    QElemType rear;
    unsigned int capacity;
}queueInfo;

/* 初始化 */
int initQueue(queueInfo **ppQ, unsigned int size)
{
    if (NULL == ppQ)
    {
        printf("Queue point address is not exist,error\n");
        return -1;
    }

    if (1 > size)
    {
        printf("initQueue length: %d, error\n", size);
        return -1;
    }
    
    queueInfo *pNewQueue = (queueInfo *)malloc(sizeof(queueInfo));
    if (NULL == pNewQueue)
    {
        printf("initQueue malloc error\n");
        return -1;
    }
    
    pNewQueue->pData = (ElemType *)malloc(sizeof(ElemType)*size);
    if (NULL == pNewQueue->pData)
    {
        printf("initQueue pData malloc error\n");
        free(pNewQueue);
        return -1;
    }
    pNewQueue->capacity = size;
    pNewQueue->front = pNewQueue->rear = 0;
    *ppQ = pNewQueue;
    
    return 0;
}

/* 入队列 */
int pushQueue(queueInfo *pQ, ElemType *val)
{
    if (NULL == pQ)
    {
        printf("Queue is NULL\n");
        return -1;
    }

    if ((pQ->rear + 1)%pQ->capacity == pQ->front)
    {
        printf("Queue Full\n");
        return -1;
    }
    memcpy(&pQ->pData[pQ->rear], val, sizeof(ElemType));
    pQ->rear = (pQ->rear +1)%pQ->capacity;
    
    return 0;
}

/* 出队列 */
int popQueue(queueInfo *pQ, ElemType *val)
{
    if (NULL == pQ)
    {
        printf("Queue NULL\n");
        return -1;
    }

    if (pQ->rear == pQ->front)
    {
        printf("Queue empty\n");
        return -1;
    }
    
    memcpy(val, &pQ->pData[pQ->front], sizeof(ElemType));
    pQ->front = (pQ->front + 1)%pQ->capacity;
    
    return 0;
}

/* 取队列头数据 */
int queueFront(queueInfo *pQ, ElemType *val)
{
    if (NULL == pQ)
    {
        printf("Queue is NULL\n");
        return -1;
    }
    
    memcpy(val, &pQ->pData[pQ->front], sizeof(ElemType));

    return 0;
}

/* 计算队列有效数据长度 */
int queueCapacity(queueInfo *pQ, unsigned int *size)
{
    if (NULL == pQ)
    {
        printf("Queue is NULL\n");
        return -1;
    }
    
    if (pQ->front <= pQ->rear)
    {
        *size = pQ->rear - pQ->front;
    }
    else
    {
        *size = pQ->capacity - pQ->front + pQ->rear;
    }
    
    return 0;
}

/* 入口 */
ElemType currAddr = {0, 0};
/* 下一步 */
ElemType nextAddr = {0, 0};
/* 出口 */
ElemType escapeAddr = {4, 4};
/* 最大路标 */
ElemType maxWayAddr = {5, 5};
/* 最小路标 */
ElemType minWayAddr = {0, 0};
/* 迷宫:1为墙壁,0为路 */
int maze[5][5]=
{
    {0, 1, 0, 0, 0},
    {0, 1, 0, 1, 0},
    {0, 0, 0, 0, 0},
    {0, 1, 1, 1, 0},
    {0, 0, 0, 1, 0},
};
ElemType preDecessor[5][5] =
{
    {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}},
    {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}},
    {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}},
    {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}},
    {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}},
};
/* 更新一步 */
int visit(queueInfo *pQ, ElemType *pCurrAddr, ElemType *pNextAddr)
{
    int ret = -1;
    maze[pNextAddr->y][pNextAddr->x] = 2;
    preDecessor[pNextAddr->y][pNextAddr->x].x = pCurrAddr->x;
    preDecessor[pNextAddr->y][pNextAddr->x].y = pCurrAddr->y;
    ret = pushQueue(pQ, pNextAddr);

    return ret;
}
/* 测试入口 */
int main(void)
{
    int ret = -1;
    queueInfo *pNewQueue = NULL;

    ret = initQueue(&pNewQueue, 100);
    if (-1 == ret)
    {
        return -1;
    }

    maze[currAddr.x][currAddr.y] = 2;
    ret = pushQueue(pNewQueue, &currAddr);

    /* 保存每一步路径,有空闲空间可保存 */
    while(-1 != ret)
    {
        ret = popQueue(pNewQueue, &currAddr);
        if (-1 == ret)
        {
            break;
        }

        if (   currAddr.x == escapeAddr.x
            && currAddr.y == escapeAddr.y)
        {
            ret = 0;
            break;
        }
        if (   currAddr.x + 1 < maxWayAddr.x
            && maze[currAddr.y][currAddr.x + 1] == 0)
        {
            nextAddr.x = currAddr.x + 1;
            nextAddr.y = currAddr.y;
            ret = visit(pNewQueue, &currAddr, &nextAddr);
            if (-1 == ret)
            {
                break;
            }
        }
        if (   currAddr.y + 1 < maxWayAddr.y
            && maze[currAddr.y + 1][currAddr.x] == 0)
        {
            nextAddr.x = currAddr.x;
            nextAddr.y = currAddr.y + 1;
            ret = visit(pNewQueue, &currAddr, &nextAddr);
            if (-1 == ret)
            {
                break;
            }
        }
        if (   currAddr.x - 1 >= minWayAddr.x
            && maze[currAddr.y][currAddr.x - 1] == 0)
        {
            nextAddr.x = currAddr.x - 1;
            nextAddr.y = currAddr.y;
            ret = visit(pNewQueue, &currAddr, &nextAddr);
            if (-1 == ret)
            {
                break;
            }
        }
        if (   currAddr.y - 1 >= minWayAddr.y
            && maze[currAddr.y - 1][currAddr.x] == 0)
        {
            nextAddr.x = currAddr.x;
            nextAddr.y = currAddr.y - 1;
            ret = visit(pNewQueue, &currAddr, &nextAddr);
            if (-1 == ret)
            {
                break;
            }
        }
        
        printf("print current position\n");
    }

    if (-1 == ret)
    {
        printf("there is someWrong\n");
        return -1;
    }

    if (   currAddr.x == escapeAddr.x
        && currAddr.y == escapeAddr.y)
    {
        printf("(%d, %d)\n", currAddr.y, currAddr.x);
        while(preDecessor[currAddr.y][currAddr.x].y != -1)
        {
            currAddr = preDecessor[currAddr.y][currAddr.x];
            printf("(%d, %d)\n", currAddr.y, currAddr.x);
        }
    }
    else
    {
        printf("no find way\n");
    }

    return 0;    
}

posted @ 2018-11-20 18:38  thinking......  阅读(296)  评论(0)    收藏  举报