第六十七题:
把字符串转换成整数
解题程序:
#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;
}