您的位置:首页 > Web前端

【剑指offer】第三十四题(二叉树中和尾某一值的路径) 和 第三十五题(复杂链表的复制)

2018-03-30 17:04 429 查看
第三十四题:二叉树中和为某一值的路径

题目:

输入一颗二叉树和一个整数,打印出二叉树中结点值 的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的结点形成一条路径。二叉树的结点定义如下:

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

};
解题程序如下:

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

using namespace std;

struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode * m_pLeft;
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);
}
}

void FindPath(BinaryTreeNode *pRoot,int exceptedSum,vector<int> &path,int currentSum)
{
// 给当前路径长度加上结点值
currentSum += pRoot->m_nValue;

// 把结点的值放入容器中
path.push_back(pRoot->m_nValue);

bool isLeaf;
// 判断当前结点是否为叶节点
isLeaf = (pRoot->m_pLeft == NULL) && (pRoot->m_pRight == NULL);

// 如果是叶节点,并且路径上结点的值的和等于输入的值
// 打印这条路径
if(currentSum == exceptedSum && isLeaf)
{
printf("A path is found:\n");
vector<int>::iterator it = path.begin();

for(;it != path.end();++it)
{
printf("%d\t",*it);
}
printf("\n");
}

// 如果不是叶节点,则遍历它的子节点
if(pRoot->m_pLeft != NULL)
FindPath(pRoot->m_pLeft,exceptedSum,path,currentSum);
if(pRoot->m_pRight != NULL)
FindPath(pRoot->m_pRight,exceptedSum,path,currentSum);

// 在返回父节点前,在路径上删除当前结点
path.pop_back();
}

// 二叉树中和尾某一值的路径

void FindPath(BinaryTreeNode *pRoot,int expectedSum)
{
if(pRoot == NULL)
return;

// 使用 vector 来保存路径
vector<int> path;

// 当前的路径长度
int currentSum = 0;
FindPath(pRoot,expectedSum,path,currentSum);
}

// 测试用例

void test()
{
//创建二叉树结点
BinaryTreeNode *pNode10 = CreateBinaryNode(10);
BinaryTreeNode *pNode5 = CreateBinaryNode(5);
BinaryTreeNode *pNode12 = CreateBinaryNode(12);
BinaryTreeNode *pNode4 = CreateBinaryNode(4);
BinaryTreeNode *pNode7 = CreateBinaryNode(7);

// 连接二叉树的各个节点
ConnectTreeNodes(pNode10,pNode5,pNode12);
ConnectTreeNodes(pNode5,pNode4,pNode7);

int exceptedSum = 0;
scanf("%d",&exceptedSum);
// 打印二叉树中值为某一和的路径
FindPath(pNode10,exceptedSum);

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

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



第三十五题:复杂链表的复制
题目:

请实现函数 ComplexListNode *Clone(ComplexListNode *pHead),复制一个复杂链表。在复杂链表中,每个结点除了有一个 m_pNext 指针指向下一个结点,还有一个

m_pSibling 指针指向链表中的任意结点或者 NULL。结点定义如下:

struct ListNode
{
int m_nVale;
ListNode* m_pNext;
ListNode* m_pSibling;
};
解题程序如下:

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

struct ListNode
{
int m_nVale;
ListNode* m_pNext;
ListNode* m_pSibling;
};

// 给链表创建结点
ListNode *CreateListNode(int val)
{
ListNode * pNew = (ListNode*)malloc(sizeof(ListNode));
if(pNew == NULL)
{
printf("pNew malloc failed!\n");
return NULL;
}
pNew->m_pNext = NULL;
pNew->m_nVale = val;
pNew->m_pSibling = NULL;

return pNew;
}

// 连接链表

void ConnectListNode(ListNode* pNode,ListNode* pNext,ListNode* pSibling)
{
if(pNode != NULL)
{
pNode->m_pNext = pNext;
pNode->m_pSibling = pSibling;
}
}

// 打印链表

void printListNode(ListNode *pNode)
{
while(pNode)
{
printf("The value of this node is :%d\n",pNode->m_nVale);
if(pNode->m_pSibling)
printf("The value of its sibling is : %d\n",pNode->m_pSibling->m_nVale);
else
printf("This node does not have a sibling\n");

printf("\n");
pNode = pNode->m_pNext;
}
printf("\n");
}

void print(ListNode *pHead)
{
while( NULL != pHead )
{
printf("%d\t",pHead->m_nVale);
pHead = pHead->m_pNext;
}
printf("\n");
}

// 销毁链表

void DestroyListNode(ListNode* pHead)
{
while(pHead)
{
ListNode *temp = pHead;
pHead = pHead->m_pNext;

free(temp);
temp = NULL;
}
}

// 复杂链表复制:第一步
// 复制原始链表结点,并把复制的结点连接在当前结点的后面

void CloneNodes(ListNode* pHead)
{
ListNode* pNode = pHead;

while(pNode != NULL)
{
ListNode *pCloned = (ListNode*) malloc(sizeof(ListNode));
if( pCloned == NULL )
{
printf("pCloned malloc failed!\n");
return;
}
pCloned->m_nVale = pNode->m_nVale;
pCloned->m_pNext = pNode->m_pNext;
pCloned->m_pSibling = NULL;
pNode->m_pNext = pCloned;

pNode = pCloned->m_pNext;
}

}

// 复杂链表复制:第二步
// 设置复制出来的结点的 m_pSibling
// 假设原始链表上的 N 的 m_pSibling 指向结点 S ,那么对其复制出来的 N' 是 N 的 m_pNext 指向的结点
// 同样,S' 也是 S 的 m_pNext 指向的 结点。

void ConnectSiblingNodes(ListNode *pHead)
{
ListNode *pNode = pHead;

while(pNode != NULL)
{
ListNode* pCloned = pNode->m_pNext;
if(pNode->m_pSibling != NULL)
{
pCloned->m_pSibling = pNode->m_pSibling->m_pNext;
}
pNode = pCloned->m_pNext;
}
}

// 复杂链表复制:第三步
// 把第二部得到的链表拆分成两个链表,奇数位置上的结点组成原始链表,偶数位置上的结点组成复制出来的链表

ListNode* RecoonectNodes(ListNode *pHead)
{
ListNode* pNode = pHead;
ListNode* pClonedHead = NULL;
ListNode * pClonedNode = NULL;

if(pNode != NULL)
{
pClonedHead = pClonedNode = pNode->m_pNext;
pNode->m_pNext = pClonedNode->m_pNext;
pNode = pNode->m_pNext;
}

while(pNode != NULL)
{
pClonedNode->m_pNext = pNode->m_pNext;
pClonedNode = pClonedNode->m_pNext;
pNode->m_pNext = pClonedNode->m_pNext;
pNode = pNode->m_pNext;
}

return pClonedHead;
}

// 合并上面三步过程,就是复杂链表的复制过程

ListNode *Clone(ListNode* pHead)
{
CloneNodes(pHead);
ConnectSiblingNodes(pHead);
return RecoonectNodes(pHead);
}

// 测试用例
void test()
{
// 创建链表的结点
ListNode *pNode1 = CreateListNode(1);
ListNode *pNode2 = CreateListNode(2);
ListNode *pNode3 = CreateListNode(3);
ListNode *pNode4 = CreateListNode(4);
ListNode *pNode5 = CreateListNode(5);

// 连接链表的结点
ConnectListNode(pNode1,pNode2,pNode3);
ConnectListNode(pNode2,pNode3,pNode5);
ConnectListNode(pNode3,pNode4,NULL);
ConnectListNode(pNode4,pNode5,pNode2);

// 打印链表结点
// printListNode(pNode1);

print(pNode1);
ListNode* temp = Clone(pNode1);
if(NULL == temp)
{
printf("copy falied!\n");
}
else
{
print(temp);
}

// 销毁链表
DestroyListNode(pNode1);
DestroyListNode(temp);

}
int main(void)
{
test();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: