二叉树的构建、层次打印、广度遍历、深度遍历、K值路径
2014-10-13 13:55
429 查看
程序主要是二叉树方面的,第二面被鄙视了。下面对二叉树的面试题做个总结。
[cpp] view
plaincopy
#include <iostream>
#include <deque>
#include <vector>
using namespace std;
struct BinaryTreeNode
{
int m_nVal;
BinaryTreeNode *m_pLeft;
BinaryTreeNode *m_pRight;
};
/*
根据前序遍历和中序遍历构造二叉树
*/
BinaryTreeNode* ConstructBinaryTreeCore(int *startPreOrder, int *endPreOrder, int *startInOrder, int *endInOrder)
{
BinaryTreeNode *pRoot = new BinaryTreeNode;
pRoot->m_nVal = startPreOrder[0];
pRoot->m_pLeft = pRoot->m_pRight = NULL;
if (startPreOrder == endPreOrder)
{
if (startInOrder == endInOrder && *startInOrder == *endInOrder)
{
return pRoot;
}
else
{
return NULL;
}
}
int *current = startInOrder;
while (*current != startPreOrder[0])
{
++current;
}
int len = current - startInOrder;
if (len > 0)
{
pRoot->m_pLeft = ConstructBinaryTreeCore(startPreOrder+1, startPreOrder+len, startInOrder, current-1);
}
if ((endInOrder-current) > 0)
{
pRoot->m_pRight = ConstructBinaryTreeCore(startPreOrder+len+1, endPreOrder, current+1, endInOrder);
}
return pRoot;
}
BinaryTreeNode* ConstructBinaryTree(int preOrder[], int inOrder[], int n)
{
if (preOrder==NULL || inOrder==NULL || n<=0)
{
return NULL;
}
return ConstructBinaryTreeCore(preOrder, preOrder+n-1, inOrder, inOrder+n-1);
}
//求二叉树的深度
int GetDepth(tagBiNode *pRoot)
{
if (pRoot == NULL)
{
return 0;
}
// int nLeftLength = GetDepth(pRoot->m_left);
// int nRigthLength = GetDepth(pRoot->m_right);
// return nLeftLength > nRigthLength ? (nLeftLength + 1) : (nRigthLength + 1);
return GetDepth(pRoot->left) > GetDepth(pRoot->right) ?
(GetDepth(pRoot->left) + 1) : (GetDepth(pRoot->right) + 1);
}
//求二叉树的宽度
int GetWidth(tagBiNode *pRoot)
{
if (pRoot == NULL)
{
return 0;
}
int nLastLevelWidth = 0;//记录上一层的宽度
int nTempLastLevelWidth = 0;
int nCurLevelWidth = 0;//记录当前层的宽度
int nWidth = 1;//二叉树的宽度
queue<BiNode *> myQueue;
myQueue.push(pRoot);//将根节点入队列
nLastLevelWidth = 1;
tagBiNode *pCur = NULL;
while (!myQueue.empty())//队列不空
{
nTempLastLevelWidth = nLastLevelWidth;
while (nTempLastLevelWidth != 0)
{
pCur = myQueue.front();//取出队列头元素
myQueue.pop();//将队列头元素出对
if (pCur->left != NULL)
{
myQueue.push(pCur->left);
}
if (pCur->right != NULL)
{
myQueue.push(pCur->right);
}
nTempLastLevelWidth--;
}
nCurLevelWidth = myQueue.size();
nWidth = nCurLevelWidth > nWidth ? nCurLevelWidth : nWidth;
nLastLevelWidth = nCurLevelWidth;
}
return nWidth;
}
/*
层次遍历二叉树
*/
void PrintByLevel(BinaryTreeNode *pRoot)
{
if (NULL == pRoot)
{
return ;
}
deque<BinaryTreeNode *> dq;
dq.push_back(pRoot);
while (dq.size() > 0)
{
BinaryTreeNode *pNode = dq.front();
dq.pop_front();
cout<<pNode->m_nVal<<endl;
if (pNode->m_pLeft != NULL)
{
dq.push_back(pNode->m_pLeft);
}
if (pNode->m_pRight != NULL)
{
dq.push_back(pNode->m_pRight);
}
}
}
/*
二叉树的映像
*/
void Mirror(BinaryTreeNode *pRoot)
{
if (pRoot == NULL || (pRoot->m_pLeft==NULL && pRoot->m_pRight==NULL))
{
return ;
}
BinaryTreeNode *pNode = pRoot->m_pLeft;
pRoot->m_pLeft = pRoot->m_pRight;
pRoot->m_pRight = pNode;
if (pRoot->m_pLeft != NULL)
{
Mirror(pRoot->m_pLeft);
}
if (pRoot->m_pRight != NULL)
{
Mirror(pRoot->m_pRight);
}
}
/*
打印二叉树中从根节点到叶子节点的节点值之和等于k的所有路径
*/
void FindPathCore(BinaryTreeNode *pRoot, int sum, vector<int> path, int &curSum)
{
curSum += pRoot->m_nVal;
path.push_back(pRoot->m_nVal);
bool isLeaf = (pRoot->m_pLeft == NULL && NULL == pRoot->m_pRight);
if (isLeaf && curSum == sum)
{
cout<<"The Path is:"<<endl;
for (vector<int>::iterator i=path.begin(); i!=path.end(); ++i)
{
cout<<*i<<endl;
}
cout<<endl;
}
if (pRoot->m_pLeft != NULL)
{
FindPathCore(pRoot->m_pLeft, sum, path, curSum);
}
if (pRoot->m_pRight != NULL)
{
FindPathCore(pRoot->m_pRight, sum, path, curSum);
}
curSum -= pRoot->m_nVal;
path.pop_back();
}
void FindPath(BinaryTreeNode *pRoot, int sum)
{
if (NULL == pRoot)
{
return ;
}
vector<int> path;
int curSum = 0;
FindPathCore(pRoot, sum, path, curSum);
}
int main()
{
int preOrder[] = {1, 2, 5, 4, 6};
int inOrder[] = {5, 2, 4, 1, 6};
BinaryTreeNode *pRoot = ConstructBinaryTree(preOrder, inOrder, 5);
PrintByLevel(pRoot);
cout<<endl;
Mirror(pRoot);
PrintByLevel(pRoot);
FindPath(pRoot, 7);
system("pause");
return 0;
}
翻转单词顺序
[cpp] view
plaincopy
#include <iostream>
using namespace std;
void swap(char *a, char *b)
{
char ch = *a;
*a = *b;
*b = ch;
}
void Reverse(char *pBegin, char *pEnd)
{
if (pBegin==NULL || NULL==pEnd)
{
return ;
}
while (pBegin < pEnd)
{
swap(pBegin++, pEnd--);
}
}
char* ReverseSentence(char *pStr)
{
if (pStr == NULL)
{
return NULL;
}
char *pBegin = pStr;
char *pEnd = pStr;
while (*pEnd != '\0')
{
pEnd++;
}
pEnd--;
Reverse(pBegin, pEnd);
pBegin = pEnd = pStr;
while (*pBegin != '\0')
{
if (*pBegin == ' ')
{
pBegin++;
pEnd++;
}
else if (*pEnd == ' ' || *pEnd == '\0')
{
Reverse(pBegin, --pEnd);
pBegin = ++pEnd;
}
else
{
pEnd++;
}
}
return pStr;
}
int main()
{
char pStr[] = "I am a huster.";
char *str = ReverseSentence(pStr);
cout<<str<<endl;
system("pause");
return 0;
}
[cpp] view
plaincopy
#include <iostream>
#include <deque>
#include <vector>
using namespace std;
struct BinaryTreeNode
{
int m_nVal;
BinaryTreeNode *m_pLeft;
BinaryTreeNode *m_pRight;
};
/*
根据前序遍历和中序遍历构造二叉树
*/
BinaryTreeNode* ConstructBinaryTreeCore(int *startPreOrder, int *endPreOrder, int *startInOrder, int *endInOrder)
{
BinaryTreeNode *pRoot = new BinaryTreeNode;
pRoot->m_nVal = startPreOrder[0];
pRoot->m_pLeft = pRoot->m_pRight = NULL;
if (startPreOrder == endPreOrder)
{
if (startInOrder == endInOrder && *startInOrder == *endInOrder)
{
return pRoot;
}
else
{
return NULL;
}
}
int *current = startInOrder;
while (*current != startPreOrder[0])
{
++current;
}
int len = current - startInOrder;
if (len > 0)
{
pRoot->m_pLeft = ConstructBinaryTreeCore(startPreOrder+1, startPreOrder+len, startInOrder, current-1);
}
if ((endInOrder-current) > 0)
{
pRoot->m_pRight = ConstructBinaryTreeCore(startPreOrder+len+1, endPreOrder, current+1, endInOrder);
}
return pRoot;
}
BinaryTreeNode* ConstructBinaryTree(int preOrder[], int inOrder[], int n)
{
if (preOrder==NULL || inOrder==NULL || n<=0)
{
return NULL;
}
return ConstructBinaryTreeCore(preOrder, preOrder+n-1, inOrder, inOrder+n-1);
}
//求二叉树的深度
int GetDepth(tagBiNode *pRoot)
{
if (pRoot == NULL)
{
return 0;
}
// int nLeftLength = GetDepth(pRoot->m_left);
// int nRigthLength = GetDepth(pRoot->m_right);
// return nLeftLength > nRigthLength ? (nLeftLength + 1) : (nRigthLength + 1);
return GetDepth(pRoot->left) > GetDepth(pRoot->right) ?
(GetDepth(pRoot->left) + 1) : (GetDepth(pRoot->right) + 1);
}
//求二叉树的宽度
int GetWidth(tagBiNode *pRoot)
{
if (pRoot == NULL)
{
return 0;
}
int nLastLevelWidth = 0;//记录上一层的宽度
int nTempLastLevelWidth = 0;
int nCurLevelWidth = 0;//记录当前层的宽度
int nWidth = 1;//二叉树的宽度
queue<BiNode *> myQueue;
myQueue.push(pRoot);//将根节点入队列
nLastLevelWidth = 1;
tagBiNode *pCur = NULL;
while (!myQueue.empty())//队列不空
{
nTempLastLevelWidth = nLastLevelWidth;
while (nTempLastLevelWidth != 0)
{
pCur = myQueue.front();//取出队列头元素
myQueue.pop();//将队列头元素出对
if (pCur->left != NULL)
{
myQueue.push(pCur->left);
}
if (pCur->right != NULL)
{
myQueue.push(pCur->right);
}
nTempLastLevelWidth--;
}
nCurLevelWidth = myQueue.size();
nWidth = nCurLevelWidth > nWidth ? nCurLevelWidth : nWidth;
nLastLevelWidth = nCurLevelWidth;
}
return nWidth;
}
/*
层次遍历二叉树
*/
void PrintByLevel(BinaryTreeNode *pRoot)
{
if (NULL == pRoot)
{
return ;
}
deque<BinaryTreeNode *> dq;
dq.push_back(pRoot);
while (dq.size() > 0)
{
BinaryTreeNode *pNode = dq.front();
dq.pop_front();
cout<<pNode->m_nVal<<endl;
if (pNode->m_pLeft != NULL)
{
dq.push_back(pNode->m_pLeft);
}
if (pNode->m_pRight != NULL)
{
dq.push_back(pNode->m_pRight);
}
}
}
/*
二叉树的映像
*/
void Mirror(BinaryTreeNode *pRoot)
{
if (pRoot == NULL || (pRoot->m_pLeft==NULL && pRoot->m_pRight==NULL))
{
return ;
}
BinaryTreeNode *pNode = pRoot->m_pLeft;
pRoot->m_pLeft = pRoot->m_pRight;
pRoot->m_pRight = pNode;
if (pRoot->m_pLeft != NULL)
{
Mirror(pRoot->m_pLeft);
}
if (pRoot->m_pRight != NULL)
{
Mirror(pRoot->m_pRight);
}
}
/*
打印二叉树中从根节点到叶子节点的节点值之和等于k的所有路径
*/
void FindPathCore(BinaryTreeNode *pRoot, int sum, vector<int> path, int &curSum)
{
curSum += pRoot->m_nVal;
path.push_back(pRoot->m_nVal);
bool isLeaf = (pRoot->m_pLeft == NULL && NULL == pRoot->m_pRight);
if (isLeaf && curSum == sum)
{
cout<<"The Path is:"<<endl;
for (vector<int>::iterator i=path.begin(); i!=path.end(); ++i)
{
cout<<*i<<endl;
}
cout<<endl;
}
if (pRoot->m_pLeft != NULL)
{
FindPathCore(pRoot->m_pLeft, sum, path, curSum);
}
if (pRoot->m_pRight != NULL)
{
FindPathCore(pRoot->m_pRight, sum, path, curSum);
}
curSum -= pRoot->m_nVal;
path.pop_back();
}
void FindPath(BinaryTreeNode *pRoot, int sum)
{
if (NULL == pRoot)
{
return ;
}
vector<int> path;
int curSum = 0;
FindPathCore(pRoot, sum, path, curSum);
}
int main()
{
int preOrder[] = {1, 2, 5, 4, 6};
int inOrder[] = {5, 2, 4, 1, 6};
BinaryTreeNode *pRoot = ConstructBinaryTree(preOrder, inOrder, 5);
PrintByLevel(pRoot);
cout<<endl;
Mirror(pRoot);
PrintByLevel(pRoot);
FindPath(pRoot, 7);
system("pause");
return 0;
}
翻转单词顺序
[cpp] view
plaincopy
#include <iostream>
using namespace std;
void swap(char *a, char *b)
{
char ch = *a;
*a = *b;
*b = ch;
}
void Reverse(char *pBegin, char *pEnd)
{
if (pBegin==NULL || NULL==pEnd)
{
return ;
}
while (pBegin < pEnd)
{
swap(pBegin++, pEnd--);
}
}
char* ReverseSentence(char *pStr)
{
if (pStr == NULL)
{
return NULL;
}
char *pBegin = pStr;
char *pEnd = pStr;
while (*pEnd != '\0')
{
pEnd++;
}
pEnd--;
Reverse(pBegin, pEnd);
pBegin = pEnd = pStr;
while (*pBegin != '\0')
{
if (*pBegin == ' ')
{
pBegin++;
pEnd++;
}
else if (*pEnd == ' ' || *pEnd == '\0')
{
Reverse(pBegin, --pEnd);
pBegin = ++pEnd;
}
else
{
pEnd++;
}
}
return pStr;
}
int main()
{
char pStr[] = "I am a huster.";
char *str = ReverseSentence(pStr);
cout<<str<<endl;
system("pause");
return 0;
}
相关文章推荐
- 【剑指 offer】(二十三)—— 从上往下打印二叉树(或曰层次遍历、广度优先遍历)
- 剑指offer--从上往下打印二叉树--层次遍历、广度优先搜索
- 构建二叉树、二叉树的深度、广度优先遍历
- C++二叉树的构建及求深度,叶子数量,层次遍历
- 二叉树的构建以及深度优先遍历 广度优先遍历
- 二叉树的深度优先,广度优先,以及层次遍历算法
- 二叉树的各种操作 先序 中序 后续 层次 遍历 求树高度 节点深度 知先序中序求后续 二叉排序树
- 二叉树按层次遍历广度优先算法--Debug日志
- 二叉树的层次遍历以及二叉树的深度
- 【概念】【二叉树】深度优先遍历、广度优先遍历和非递归遍历
- [转】二叉树与图的深度优先和广度优先遍历
- 二叉树先序后序递归建立,前中后序层次非递归遍历,以及统计叶子结点个数以及树的深度
- 二叉树的深度优先和广度优先遍历
- 按层次 4000 /广度遍历二叉树
- 树的非递归遍历(深度优先:前|中|后序遍历) & (广度优先:层次遍历)
- 二叉树 建立 && 遍历 && 深度 && 树形打印 (增强版)
- 数据结构-图-Java实现:有向图 图存储(邻接矩阵),最小生成树,广度深度遍历,图的连通性,最短路径
- 二叉树的深度优先和广度优先遍历
- 二叉树的深度优先和广度优先遍历
- 二叉树的层次遍历(相当于广度遍历) SJTU OJ 题目 1040二叉树层次遍历