剑指Offer(面试题19~23)

来源:互联网 发布:电脑无法上淘宝网 编辑:程序博客网 时间:2024/06/04 21:15

面试题19:二叉树的镜像

题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。
二叉树结点的定义如下:

struct BinaryTreeNode{    int                m_nValue;    BinaryTreeNode*    m_pLeft;    BinaryTreeNode*    m_pRight;};

这里写图片描述
求一棵树的镜像的过程:先前序遍历这棵树的每个结点,如果遍历到的结点有子节点,就交换它的两个子结点。当交换完所有非叶子结点的左右子结点之后,就得到了树的镜像。

void MirrorRecursively(BinaryTreeNode *pNode){    if(pNode == NULL)        return;    if(pNode->m_pLeft == NULL && pNode->m_pRight == NULL)        return;    BinaryTreeNode *pTemp = pNode->m_pLeft;    pNode->m_pLeft = pNode->m_pRight;    pNode->m_pRight = pTemp;    if(pNode->m_pLeft)        MirrorRecursively(pNode->m_pLeft);    if(pNode->m_pRight)        MirrorRecursively(pNode->m_pRight);}

面试题20:顺时针打印矩阵
题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如:如果输入如下矩阵:

这里写图片描述

则依次打印出数字1、2、3、4、8、12、16、15、14、13、9、5、6、7、11、10。

void PrintMatrixClockwisely(int** numbers,int columns,int rows){    if(numbers == NULL || columns <= 0 ||rows <= 0)        return;    int start = 0;    while(columns > start*2 && rows >start*2)    {        PrintMatrixInCircle(numbers,columns,rows,start);        ++start;    }}void PrintMatrixInCircle(int** numbers,int columns,int rows,int start){    int endX = columns -1 -start;    int endX = rows -1 -start;    //从左到右打印一行    for(int i= start;i<endX;++i)    {        int number = numbers[start][i];        printNumber(number);    }    //从上到下打印一列    if(start<endY)    {        for(int i=start+1;i<=endY;++i)        {            int number = numbers[i][endX];            printNumber(number);        }    }    //从右到左打印一行    if(start<endX && start<endY)    {        for(int i = endX - 1;i>=start;--i)        {            int number = numbers[endY][i];            printNumber(number);        }    }    //从下往上打印一列    if(start<endX&& start<endY-1)    {        for(int i= endY-1;i>=start+1;--i)        {            int number = numbers[i][start];            printNumber(number);        }    }       }

面试题22:栈的压入、弹出序列
题目:输入两个整数序列,第一序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1、2、3、4、5是某栈的压栈序列,序列4、5、3、2、1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该栈序列的弹出序列。

判断一个序列是不是栈的弹出序列的规律:如果下一个弹出的数字刚好是栈顶数字,那么直接弹出。如果下一个弹出的数字不在栈顶,我们把压栈序列中还没有入栈的数字压入辅助栈,知道把下一个需要弹出的数字压入栈顶为止。如果所有的数字都压入栈了仍然没有找到下一个弹出的数字,那么该序列不可能是一个弹出序列。
代码如下:

bool IsPopOrder(const int* pPush,const int* pPop,int nLength){    bool bPossible = false;    if(pPush != NULL && pPop != NULL && nLength >0)    {        const int* pNextPush = pPush;        const int* pNextPop = pPop;        std::stack<int>stackData;        while(pNextPop - pPop < nLength)        {            while(stackData.empty()||stackData.top()!=*pNextPop)            {                if(pNextPush-pPush == nLength)                    break;                stackData.push(*pNextPush);                pNextPush++;            }            if(stackData.top() != *pNextPop)                break;            stackData.pop();            pNextPop ++;        }        if(stackData.empty() && pNextPop - pPop ==nLength)            bPossible = true;    }    return bPossible;}

面试题23:从上往下打印二叉树
题目:从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印。例如输入图4.5中的二叉树,则依次打印出8、6、10、5、7、9、11。
这里写图片描述

void PrintFromTopToBottom(BinaryTreeNode* pTreeRoot){    if(!pTreeRoot)        return;    std::deque<BinaryTreeNode *> dequeTreeNode;    dequeTreeNode.push_back(pTreeRoot);    while(dequeTreeNode.size())    {        BinaryTreeNode *pNode = dequeTreeNode.front();        dequeTreeNode.pop_front();        printf("%d",pNode->m_nValue);        if(pNode->m_pLeft)            dequeTreeNode.push_back(pNode->m_pLeft);        if(pNode->m_pRight)            dequeTreeNode.push_back(pNode->m_pRight);    }}

参考文献《剑指Offer》

0 0
原创粉丝点击