【剑指offer】第六十七题(把字符串转换成整数) 和 第六十八题(树中两个结点的最低公共祖先)

第六十七题:

把字符串转换成整数

解题程序:

#include<iostream>
#include<stdlib.h>
#include<stdio.h>
using namespace std;

// 使用枚举类型,来区分是空字符串是否有效
enum status {kValid=0,KInValid};

// 使用全局变量来区分字符串数组是否有效
int g_Status = kValid;

int StringToIntCore(const char *str,bool minus)
{
    long long num = 0;

    while(*str != '\0')
    {
       if(*str >= '0' && *str <= '9') 
        {
            int flag = minus ? -1:1; 

            num = num*10+flag*(*str - '0');
            
            // 考虑是否会溢出
            if( (!minus && num > 0x7FFFFFFF) || (minus && (signed int)num < 0x80000000))
            {
                num = 0;
                break;
            }
            str++;
        }
        else
        {
           num = 0;
            break;
        }

    }
    
    if(*str == '\0')
    {
        g_Status = kValid;
    }
   
    return num;
}


int StringToInt(const char* str)
{
    g_Status = KInValid;
    // 用来保存字符串转换成数字的结果
   long long num = 0; 
    
    if( str != NULL && *str != '\0' )
    {
        // 使用 Bool 变量来确认是否有负号或者正号
        bool minus = false;        
        if( *str == '+' )
            str++;
        else if( *str == '-' )
        {
            str++;
            minus = true;
        }
        if(*str != '\0')
        {
           num = StringToIntCore(str,minus); 
        }
    
    }
    return (int)num;
}

// 测试用例

void test()
{
    int ret = StringToInt("");    
    if( g_Status == KInValid && ret == 0)
        printf("无效的输入\n");
    else
        printf("%d\n",ret);

    g_Status =  kValid;
    ret = StringToInt(NULL);    
    if( g_Status == KInValid && ret == 0)
        printf("无效的输入\n");
    else
        printf("%d\n",ret);

    ret = StringToInt("123");    
    if( g_Status == KInValid && ret == 0)
        printf("无效的输入\n");
    else
        printf("%d\n",ret);

    g_Status =  kValid;
    ret = StringToInt("123");    
    if( g_Status == KInValid && ret == 0)
        printf("无效的输入\n");
    else
        printf("%d\n",ret);

    g_Status =  kValid;
    ret = StringToInt("-123456");    
    if( g_Status == KInValid && ret == 0)
        printf("无效的输入\n");
    else
        printf("%d\n",ret);

    g_Status =  kValid;
    ret = StringToInt("123456");    
    if( g_Status == KInValid && ret == 0)
        printf("无效的输入\n");
    else
        printf("%d\n",ret);

    g_Status =  kValid;
    if( g_Status == KInValid && ret == 0)
        printf("无效的输入\n");
    else
        printf("%d\n",ret);

    g_Status =  kValid;
    ret = StringToInt("dasda1234");    
    if( g_Status == KInValid && ret == 0)
        printf("无效的输入\n");
    else
        printf("%d\n",ret);
}

int main()
{
   // int ret = StringToInt("-123");
    //printf("%d\n",ret);
    test();
    return 0; 
}

第六十八题:树中两个结点的最低公共祖先

1、树为二拆排序树。

解题程序:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;

// 二叉树的存储结构

struct BinaryTreeNode
{ 
    int m_nValue;
    struct BinaryTreeNode *m_pLeft;                                                                             
    struct BinaryTreeNode *m_pRight;
};
  
// 二叉树结点的创建
BinaryTreeNode* CreateBinaryNode(int val)
{                   
    BinaryTreeNode *pBinaryTreeNode = (BinaryTreeNode*)malloc(sizeof(BinaryTreeNode));
    if( pBinaryTreeNode == NULL )
    {               
             printf("pBinaryTreeNode malloc failed!\n"); 
             return NULL;
    }               
    pBinaryTreeNode->m_nValue = val;
    pBinaryTreeNode->m_pLeft = NULL;
    pBinaryTreeNode->m_pRight = NULL;
                
    return pBinaryTreeNode;
}        
  
// 连接二叉树的结点
void ConnectTreeNodes(BinaryTreeNode *pParent,BinaryTreeNode *pLeft,BinaryTreeNode *pRight)
{                   
    if( pParent != NULL )
    {               
        pParent->m_pLeft = pLeft;
        pParent->m_pRight = pRight;
    }               
}   
  
// 销毁二叉树 
 
 void DestroyTree(BinaryTreeNode *pRoot)
 {                  
     if(pRoot != NULL)
     {              
             BinaryTreeNode *pLeft = pRoot->m_pLeft;
             BinaryTreeNode *pRight = pRoot->m_pRight;
                      
              free(pRoot);
              pRoot = NULL;
                     
              DestroyTree(pLeft);
              DestroyTree(pRight);
                     
            }              
 }         


//题目:树中两个结点的最低公共祖先

// 要求:树为二叉排序树

BinaryTreeNode *GetLastCommonParent(BinaryTreeNode *pRoot,BinaryTreeNode *pNode1,BinaryTreeNode *pNode2)
{
   if(pRoot == NULL || pNode1 == NULL || pNode2 == NULL) 
        return NULL;
   
    if(pRoot->m_nValue >pNode1->m_nValue && pRoot->m_nValue>pNode2->m_nValue)
        return GetLastCommonParent(pRoot->m_pLeft,pNode1,pNode2);
    else if(pRoot->m_nValue < pNode1->m_nValue && pRoot->m_nValue<pNode2->m_nValue)
        return GetLastCommonParent(pRoot->m_pRight,pNode1,pNode2);
    else if(pRoot->m_nValue > pNode1->m_nValue && pRoot->m_nValue < pNode2->m_nValue) 
        return  pRoot;
    return pRoot;
}

// 二叉排序树测试用例

void test1()
{
    // 创建结点
    BinaryTreeNode *pNode10 = CreateBinaryNode(10);
    BinaryTreeNode *pNode9 = CreateBinaryNode(9);
    BinaryTreeNode *pNode8 = CreateBinaryNode(8);
    BinaryTreeNode *pNode7= CreateBinaryNode(7);
    BinaryTreeNode *pNode6 = CreateBinaryNode(6);
    BinaryTreeNode *pNode5 = CreateBinaryNode(5);
    BinaryTreeNode *pNode4 = CreateBinaryNode(4);
    BinaryTreeNode *pNode3 = CreateBinaryNode(3);
    BinaryTreeNode *pNode2 = CreateBinaryNode(2);
    BinaryTreeNode *pNode1 = CreateBinaryNode(1);

    // 连接排序二叉树的结点

    ConnectTreeNodes(pNode5,pNode3,pNode8);
    ConnectTreeNodes(pNode3,pNode2,pNode4);
    ConnectTreeNodes(pNode8,pNode6,pNode9);
    ConnectTreeNodes(pNode2,pNode1,NULL);
    ConnectTreeNodes(pNode6,pNode7,pNode10);

    // 获取二叉排序树的最低公共祖先
    BinaryTreeNode *LastCommonParent = GetLastCommonParent(pNode5,pNode1,pNode6);
    if( LastCommonParent == NULL )
        printf("不存在最低公共结点或出错!\n");
    else
        printf("%d 和 %d 在排序二叉树中的最低公共结点是:%d\n",pNode1->m_nValue,pNode6->m_nValue,LastCommonParent->m_nValue); 

    // 销毁二叉排序树
    DestroyTree(pNode5);
}


int main(void)
{
    test1();
    return 0;
}

2、树中的左右孩子都含有指向父节点的指针。

解题程序:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;

// 二叉树的存储结构

struct BinaryTreeNode
{ 
    int m_nValue;
    struct BinaryTreeNode *m_pLeft;                                                                             
    struct BinaryTreeNode *m_pRight;
    struct BinaryTreeNode *m_pParent;
};
  
// 二叉树结点的创建
BinaryTreeNode* CreateBinaryNode(int val)
{                   
    BinaryTreeNode *pBinaryTreeNode = (BinaryTreeNode*)malloc(sizeof(BinaryTreeNode));
    if( pBinaryTreeNode == NULL )
    {               
             printf("pBinaryTreeNode malloc failed!\n"); 
             return NULL;
    }               
    pBinaryTreeNode->m_nValue = val;
    pBinaryTreeNode->m_pLeft = NULL;
    pBinaryTreeNode->m_pRight = NULL;
    pBinaryTreeNode->m_pParent = NULL;
                
    return pBinaryTreeNode;
}        
  
// 连接二叉树的结点
void ConnectTreeNodes(BinaryTreeNode *pParent,BinaryTreeNode *pLeft,BinaryTreeNode *pRight)
{                   
    if( pParent != NULL )
    {               
        pParent->m_pLeft = pLeft;
        pParent->m_pRight = pRight;
        pLeft->m_pParent = pParent;
        pRight->m_pParent = pParent;
    }               
}   
  
// 销毁二叉树 
 
 void DestroyTree(BinaryTreeNode *pRoot)
 {                  
     if(pRoot != NULL)
     {              
             BinaryTreeNode *pLeft = pRoot->m_pLeft;
             BinaryTreeNode *pRight = pRoot->m_pRight;
                      
              free(pRoot);
              pRoot = NULL;
                     
              DestroyTree(pLeft);
              DestroyTree(pRight);
                     
            }              
 }         


//题目:树中两个结点的最低公共祖先

// 要求:树中包含指向父节点的指针

BinaryTreeNode *GetLastCommonParent(BinaryTreeNode *pNode1,BinaryTreeNode *pNode2)
{
    if( pNode1 != NULL && pNode2 != NULL )
    {
        BinaryTreeNode *p1 = pNode1;
        BinaryTreeNode *p2 = pNode2;

        while(p1 != NULL && p2 != NULL )
        {
            if( p1->m_nValue != p2->m_nValue )
            {
                p1 = p1->m_pParent;
                p2 = p2->m_pParent;
            }
            else
                return p1;
        }

    }
    return NULL;
}
// 二叉树测试用例

void test1()
{
    // 创建结点
    BinaryTreeNode *pNode7= CreateBinaryNode(7);
    BinaryTreeNode *pNode6 = CreateBinaryNode(6);
    BinaryTreeNode *pNode5 = CreateBinaryNode(5);
    BinaryTreeNode *pNode4 = CreateBinaryNode(4);
    BinaryTreeNode *pNode3 = CreateBinaryNode(3);
    BinaryTreeNode *pNode2 = CreateBinaryNode(2);
    BinaryTreeNode *pNode1 = CreateBinaryNode(1);

    // 连接二叉树的结点

    ConnectTreeNodes(pNode1,pNode2,pNode3);
    ConnectTreeNodes(pNode2,pNode4,pNode5);
    ConnectTreeNodes(pNode3,pNode6,pNode7);

    // 获取二叉树的最低公共祖先
    BinaryTreeNode *LastCommonParent = GetLastCommonParent(pNode4,pNode7);
    if( LastCommonParent == NULL )
        printf("不存在最低公共结点或出错!\n");
    else
        printf("%d 和 %d 在排序二叉树中的最低公共结点是:%d\n",pNode4->m_nValue,pNode7->m_nValue,LastCommonParent->m_nValue); 

    LastCommonParent = GetLastCommonParent(pNode6,pNode7);
    if( LastCommonParent == NULL )
        printf("不存在最低公共结点或出错!\n");
    else
        printf("%d 和 %d 在排序二叉树中的最低公共结点是:%d\n",pNode6->m_nValue,pNode7->m_nValue,LastCommonParent->m_nValue); 
    // 销毁二叉树
    DestroyTree(pNode1);
}


int main(void)
{
    test1();
    return 0;
}

3、树为一颗普通的树,没有其他条件

解题程序:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<list>

using namespace std;


// 二叉树的存储结构

struct BinaryTreeNode
{ 
    int m_nValue;
    struct BinaryTreeNode *m_pLeft;                                                                             
    struct BinaryTreeNode *m_pRight;
};
  
list<BinaryTreeNode*> path1;
list<BinaryTreeNode*> path2;

bool isExistsData1 =true;
bool isExistsData2 =true;


// 二叉树结点的创建
BinaryTreeNode* CreateBinaryNode(int val)
{                   
    BinaryTreeNode *pBinaryTreeNode = (BinaryTreeNode*)malloc(sizeof(BinaryTreeNode));
    if( pBinaryTreeNode == NULL )
    {               
             printf("pBinaryTreeNode malloc failed!\n"); 
             return NULL;
    }               
    pBinaryTreeNode->m_nValue = val;
    pBinaryTreeNode->m_pLeft = NULL;
    pBinaryTreeNode->m_pRight = NULL;
                
    return pBinaryTreeNode;
}        
  
// 连接二叉树的结点
void ConnectTreeNodes(BinaryTreeNode *pParent,BinaryTreeNode *pLeft,BinaryTreeNode *pRight)
{                   
    if( pParent != NULL )
    {               
        pParent->m_pLeft = pLeft;
        pParent->m_pRight = pRight;
    }               
}   
  
// 销毁二叉树 
 
 void DestroyTree(BinaryTreeNode *pRoot)
 {                  
     if(pRoot != NULL)
     {              
             BinaryTreeNode *pLeft = pRoot->m_pLeft;
             BinaryTreeNode *pRight = pRoot->m_pRight;
                      
              free(pRoot);
              pRoot = NULL;
                     
              DestroyTree(pLeft);
              DestroyTree(pRight);
                     
            }              
 }         


//题目:树中两个结点的最低公共祖先

// 要求:一颗普通的二叉树

bool GetNodePath(BinaryTreeNode *pRoot,BinaryTreeNode* pNode,list<BinaryTreeNode*> &path)
{
    if(pRoot == NULL)
        return false;

    path.push_back(pRoot);
    if( pRoot == pNode )
         return true;
    else
    {
        bool found = false;
        found = GetNodePath(pRoot->m_pLeft,pNode,path); 
        
        if(!found)
            found = GetNodePath(pRoot->m_pRight,pNode,path);

        if(!found)
            path.pop_back();
       
        return found;
    }
}

BinaryTreeNode *GetLastCommonNode(list<BinaryTreeNode*> &path1,list<BinaryTreeNode*> &path2)
{
    list<BinaryTreeNode*>::iterator it1 = path1.begin();
    list<BinaryTreeNode*>::iterator it2 = path2.begin();

    BinaryTreeNode *pLast = NULL;
    
    while(it1 != path1.end() && it2 != path2.end())
    {
        if( *it1 == *it2 )
            pLast = *it1;
        it1++;
        it2++;
    }
    
    return pLast;
}


// 获取二叉排序树的最低公共祖先

BinaryTreeNode *GetLastCommonParent(BinaryTreeNode *pRoot,BinaryTreeNode *pNode1,BinaryTreeNode *pNode2)
{
   if(pRoot == NULL || pNode1 == NULL || pNode2 == NULL) 
        return NULL;
    
    if( !GetNodePath(pRoot,pNode1,path1) )
    {
        isExistsData1 = false;
        return NULL;
    }

    if( !GetNodePath(pRoot,pNode2,path2) )
    {
       isExistsData2 = false;
        return NULL;
    }
    
    return GetLastCommonNode(path1,path2);
}



// 普通二叉树测试用例

void test1()
{
    // 创建结点
    BinaryTreeNode *pNode15 = CreateBinaryNode(15);
    BinaryTreeNode *pNode14 = CreateBinaryNode(14);
    BinaryTreeNode *pNode13 = CreateBinaryNode(13);
    BinaryTreeNode *pNode12 = CreateBinaryNode(12);
    BinaryTreeNode *pNode11 = CreateBinaryNode(11);
    BinaryTreeNode *pNode10 = CreateBinaryNode(10);
    BinaryTreeNode *pNode9 = CreateBinaryNode(9);
    BinaryTreeNode *pNode8 = CreateBinaryNode(8);
    BinaryTreeNode *pNode7= CreateBinaryNode(7);
    BinaryTreeNode *pNode6 = CreateBinaryNode(6);
    BinaryTreeNode *pNode5 = CreateBinaryNode(5);
    BinaryTreeNode *pNode4 = CreateBinaryNode(4);
    BinaryTreeNode *pNode3 = CreateBinaryNode(3);
    BinaryTreeNode *pNode2 = CreateBinaryNode(2);
    BinaryTreeNode *pNode1 = CreateBinaryNode(1);

    // 连接二叉树的结点

    ConnectTreeNodes(pNode1,pNode2,pNode3);
    ConnectTreeNodes(pNode2,pNode4,pNode5);
    ConnectTreeNodes(pNode4,pNode8,pNode9);
    ConnectTreeNodes(pNode5,pNode10,pNode11);
    ConnectTreeNodes(pNode6,pNode12,pNode13);
    ConnectTreeNodes(pNode7,pNode14,pNode15);

    // 获取二叉树的最低公共祖先
    BinaryTreeNode *LastCommonParent = GetLastCommonParent(pNode1,pNode10,pNode11);
    if( LastCommonParent == NULL )
        printf("不存在最低公共结点或出错!\n");
    else
        printf("%d 和 %d 在排序二叉树中的最低公共结点是:%d\n",pNode10->m_nValue,pNode11->m_nValue,LastCommonParent->m_nValue); 

    // 销毁二叉树
    DestroyTree(pNode5);
}


int main(void)
{
    test1();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35396127/article/details/80078534