二叉树
一、二叉树简介
除根节点外每个节点都有一个父节点
每个结点可以有一个、两个或者没有子节点
从0开始的数组表示(适用于密集二叉树)中:左子节点 2 * i + 1 ,右子节点 2 * i + 2
struct treeNode
{
int data;
treeNode* leftSon;
treeNode* rightSon;
};
1、完全二叉树
设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边。
2、满二叉树
每一层上的所有结点都有两个子结点的二叉树,且最后一层无任何子节点。
二、二叉树创建
1、二叉树节点创建
treeNode* createTreeNode(int data)
{
treeNode* node=new treeNode;
node->data=data;
node->leftSon=NULL;
node->rightSon=NULL;
return node;
}
2、二叉树创建
treeNode* createTreeNodeFromArray(int arr[],int length)
{
if(length<1) //数组为空
{
return NULL;
}
treeNode** root = new treeNode*[length]{}; //设置根节点
root[0]=createTreeNode(arr[0]);
for(int i=0;i<length;i++)
{
int leftIdx=2*i+1,rightIdx=2*2+2;
if(leftIdx<length&&arr[leftIdx]>=0)
{
root[leftIdx]=createTreeNode(arr[leftIdx]);
root[i]->leftSon=root[leftIdx];
}
if(rightIdx<length&&arr[rightIdx]>=0)
{
root[rightIdx]=createTreeNode(arr[rightIdx]);
root[i]->rightSon=root[rightIdx];
}
}
return root[0];
}
三、二叉树遍历
1、先序遍历
1、父节点
2、左子节点
3、右子节点
递归
void preOrderErgodic(treeNode* root)
{
if(root==NULL) //空树
{
return;
}
cout<<root->data<<endl;
preOrderErgodic(root->leftSon);
preOrderErgodic(root->rightSon);
}
迭代
void preOrderErgodic(treeNode* root)
{
if(root==NULL) //空树
{
return;
}
stack<treeNode*>nodeStack;
nodeStack.push(root);
while(!nodeStack.empty())
{
treeNode*node=nodeStack.top();
cout<<node->data<<endl;
nodeStack.pop();
//先入后出
if(node->rightSon)
{
nodeStack.push(node->rightSon);
}
if(node->leftSon)
{
nodeStack.push(node->leftSon);
}
}
}
2、中序遍历
1、左子节点
3、父节点
2、右子节点
递归
void inOrderErgodic(treeNode* root)
{
if(root==NULL)
{
return;
}
inOrderErgodic(root->leftSon);
cout<<root->data<<endl;
inOrderErgodic(root->rightSon);
}
迭代
void inOrderErgodic(treeNode* root)
{
if(root==NULL) //空树
{
return;
}
stack<treeNode*>nodeStack;
treeNode* node=root;
//当前节点非空或栈非空时迭代处理
while(node||!nodeStack.empty())
{
while(node)
{
nodeStack.push(node);
node=node->leftSon;
}
//栈顶节点无左子数或依据访问完左子树
node=nodeStack.top();
cout<<node->data<<endl;
nodeStack.pop();
node=node->rightSon;
}
}
3、后序遍历
1、左子节点
2、右子节点
3、父节点
递归
void postOrderErgodic(treeNode* root)
{
if(root==NULL)
{
return;
}
postOrderErgodic(root->leftSon);
postOrderErgodic(root->rightSon);
cout<<root->data<<endl;
}
迭代
void postOrderErgodic(treeNode* root)
{
if(root==NULL)
{
return;
}
stack<treeNode*>nodeStack;
treeNode*currentNode =root;
treeNode*visitedNode =root;
while(currentNode||!nodeStack.empty())
{
while(currentNode)
{
nodeStack.push(currentNode);
currentNode=currentNode->leftSon;
}
currentNode=nodeStack.top();
if(currentNode->rightSon&¤tNode->rightSon!=visitedNode)
{
currentNode=currentNode->rightSon;
}
else
{
cout<<currentNode->data<<endl;
visitedNode=currentNode;
currentNode=NULL; //防止重复访问左子树
nodeStack.pop();
}
}
}
4、层次遍历
同一层次由左及右依次遍历
void levelOrderErgodic(treeNode*root)
{
if(NULL==root)
{
return;
}
queue<treeNode*>nodeQueue;
nodeQueue.push(root);
while(!nodeQueue.empty())
{
treeNode* node=nodeQueue.front();
cout<<node->data<<endl;
if(node->leftSon)
{
nodeQueue.push(node->leftSon);
}
if(node->rightSon)
{
nodeQueue.push(node->rightSon);
}
nodeQueue.pop();
}
}