tree.h
#ifndef TREE_H
#define TREE_H
#include <assert.h>
typedef int element;
/*定义二叉树*/
typedef struct Node{
element data;
Node* leftChild;
Node* rightChild;
}TreeNode;
void PreOrder(TreeNode *root);//递归前序遍历
void InOrder(TreeNode *root);//递归中序遍历
void PostOrder(TreeNode *root);//递归后序遍历
void IterationPreOrder(TreeNode *root);//迭代前序遍历
void IterationInOrder(TreeNode *root);//迭代中序遍历
void IterationPostOrder(TreeNode *root);//迭代后序遍历(方法一):具体思路见cpp中解释
void IterationPostOrder2(TreeNode *root);//迭代后序遍历(方法二)
void IterationPostOrder3(TreeNode *root);//迭代后序遍历(方法三,设置标志位)
void LevelOrder(TreeNode *root);//层序遍历
int PrintTreeAtLevel(TreeNode *root,int level);//打印树的第level(根节点为第0层)层所有结点,成功返回1
int TreeDepth(TreeNode *root);//返回二叉树的深度,空树深度为0;
void ReleaseTree(TreeNode* root);//递归释放整个树
//void PrintTreeBYLevel(TreeNode *root);//按层序遍历,每层之后
/*B树的查找,查找成功返回1,查找失败返回0,类似于二分查找分为递归和非递归*/
int SearchBiTree(TreeNode *root, element key);//非递归
int SearchBiTree2(TreeNode *root, element key);//递归
//查找B树最小结点
TreeNode * BiTreeMinimum(TreeNode *root);
//查找B树最大结点
TreeNode* BiTreeMaximum(TreeNode *root);
/*在B树root中查找元素item是否存在,若存在返回0,若不存在,
把item结点插入到当前结点的左指针或右指针上,并返回1*/
int InsertBiTree(TreeNode ** root,element item);
//B树的删除操作
void DeleteBitree(TreeNode* root,element key);
bool DeleteBST(TreeNode *root, element key);
bool Delete(TreeNode* p);
//★★★★★★★递归的本质是编译器生成一个函数调用的栈
#endif
tree.cpp
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
#include "Tree.h"
int SearchBiTree(TreeNode *root, element key)
{
//非递归调用
TreeNode* p=root;
if(p==NULL)
return 0;//空树返回0
while(p!=NULL)
{
if(p->data == key)
{
return 1;
}else if(p->data < key){
p=p->rightChild;
}else{
p=p->leftChild;
}
}
return 0;
}
int SearchBiTree2(TreeNode *root, element key)
{
//递归调用
//《编程之美》p242 关于递归用法的3点注意
TreeNode* p=root;
if(p==NULL)
return 0;//空树返回0
if(p->data == key)
{
return 1;
}else if(p->data < key){
return SearchBiTree(p->rightChild, key);
}else{
return SearchBiTree(p->leftChild, key);
}
}
TreeNode * BiTreeMinimum(TreeNode *root)
{
TreeNode* p=root;
while(p->leftChild != NULL)
p = p->leftChild;
return p;
}
TreeNode* BiTreeMaximum(TreeNode *root)
{
TreeNode* p=root;
while(p->rightChild != NULL)
p = p->rightChild;
return p;
}
int InsertBiTree(TreeNode ** root,element item)
{
TreeNode* current = *root;//
TreeNode* parent=NULL;
TreeNode* p;
//查找
while(current!=NULL)
{
if(current->data == item)
{
return 0;//查找到则返回0
}
parent =current;//记录查找到的最后结点,新结点作为该结点的儿子结点
if(current->data < item){
current=current->rightChild;
}else{
current=current->leftChild;
}
}
//查找失败,插入
p=(TreeNode*)malloc(sizeof(TreeNode));//无free
if(p==NULL){//空间不足
exit(0);
}
p->data=item;
p->leftChild=NULL;
p->rightChild=NULL;
if(parent==NULL)
*root = p;
else if(parent->data > item){
parent->leftChild = p;
}else{
parent->rightChild = p;
}
return 1;
}
void DeleteBitree(TreeNode* root,element key)//测试有误
{
TreeNode* p=root;
if(p==NULL)
{
return ;
}
if(p->data > key)
DeleteBitree(p->leftChild,key);
else if(p->data < key)
DeleteBitree(p->rightChild,key);
else{
if(p->leftChild != NULL && p->rightChild!=NULL)
{
//p->data=BiTreeMaximum(p->leftChild)->data;
//DeleteBitree(p->leftChild,p->data);
/**或者*/
p->data=BiTreeMinimum(p->rightChild)->data;
DeleteBitree(p->rightChild,p->data);
}else{
TreeNode* t=p;
p= (p->leftChild != NULL) ? p->leftChild : p->rightChild;
delete t;
}
}
}
void PreOrder(TreeNode *root)
{
if(root != NULL)
{
std::cout << root->data << ",";
PreOrder(root->leftChild);
PreOrder(root->rightChild);
}
}
void InOrder(TreeNode *root)
{
if(root != NULL)
{
InOrder(root->leftChild);
std::cout << root->data << ",";
InOrder(root->rightChild);
}
}
void PostOrder(TreeNode *root)
{
if(root != NULL)
{
PostOrder(root->leftChild);
PostOrder(root->rightChild);
std::cout << root->data << ",";
}
}
void IterationPreOrder(TreeNode *root)
{
stack<TreeNode*> stk;
TreeNode* p= root;
if(p != NULL)
stk.push(p);
while(!stk.empty())//栈不为空
{
p=stk.top();
stk.pop();
cout << p->data << ",";
if(p->rightChild != NULL)
stk.push(p->rightChild);
if(p->leftChild != NULL)
stk.push(p->leftChild);
}
}
void IterationInOrder(TreeNode *root)
{
stack<TreeNode*> stk;
TreeNode* p= root;
while(true)
{
while(p != NULL)
{
stk.push(p);
p=p->leftChild;
}
if(!stk.empty())//栈不为空
{
p=stk.top();
stk.pop();
if(p == NULL)
break;
cout << p->data << ",";
p=p->rightChild;
}else{
break;
}
}
}
void IterationPostOrder(TreeNode *root)//继续学习
{
/*
要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。
如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。
若非上述两种情况,则将P的右孩子和左孩子依次入栈,
这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
*/
stack<TreeNode*> stk;
TreeNode *cur; //当前结点
TreeNode *pre=NULL; //前一次访问的结点
stk.push(root);
while(!stk.empty())
{
cur=stk.top();
if((cur->leftChild==NULL&&cur->rightChild==NULL)||
(pre!=NULL&&(pre==cur->leftChild||pre==cur->rightChild)))
{
cout<<cur->data<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过
stk.pop();
pre=cur;
}
else
{
if(cur->rightChild!=NULL)
stk.push(cur->rightChild);
if(cur->leftChild!=NULL)
stk.push(cur->leftChild);
}
}
}
void IterationPostOrder2(TreeNode *root)//继续学习
{
stack<TreeNode*> stk;
TreeNode* p= root;
TreeNode* pre= NULL;//pre表示最近一次访问的结点
while(p||!stk.empty())
{
if(p)
{
stk.push(p);
p=p->leftChild;
}else{
p=stk.top();
if(p->rightChild && p->rightChild!=pre)
{
p = p->rightChild;
stk.push(p);
p = p->leftChild;
}else
{
stk.pop();
cout<<p->data<<",";
pre = p;
p = NULL;
}
}
}
}
void IterationPostOrder3(TreeNode *root)//设置标志位
{
}
void LevelOrder(TreeNode *root)
{
queue<TreeNode*> que;//队列
TreeNode* p=root;
if(p != NULL)
{
que.push(p);
}
while(!que.empty())
{
p=que.front();
que.pop();//不要忘记删除栈顶元素
cout << p->data << ",";
if(p->leftChild != NULL)
que.push(p->leftChild);
if(p->rightChild != NULL)
que.push(p->rightChild);
}
}
int PrintTreeAtLevel(TreeNode *root,int level)
{
TreeNode* p=root;
if(p == NULL || level < 0)
return 0;
if(level==0)
{
cout << p->data << ",";
}
return PrintTreeAtLevel(p->leftChild,level-1) + PrintTreeAtLevel(p->rightChild,level-1);
}
int TreeDepth(TreeNode *root)
{
TreeNode* p=root;
if(p==NULL)
return 0;
return TreeDepth(p->leftChild)>TreeDepth(p->rightChild) ? TreeDepth(p->leftChild)+1:TreeDepth(p->rightChild)+1;
}
void ReleaseTree(TreeNode* root)
{//before free root,must free root->left and root->right
//所以这是一种后序遍历
if(root != NULL)
{
ReleaseTree(root->leftChild);
ReleaseTree(root->rightChild);
free(root);
root=NULL;
}
}
bool DeleteBST(TreeNode *root, element key){
//若二叉排序树T中存在关键字等于key的数据元素时,则删除该数据元素,并返回
//TRUE;否则返回FALSE
if(root==NULL)
return false; //不存在关键字等于key的数据元素
else{
if(key == root->data) { // 找到关键字等于key的数据元素
return Delete(root);
}
else if(key < root->data)
return DeleteBST(root->leftChild, key);
else
return DeleteBST(root->rightChild, key);
}
}
bool Delete(TreeNode* p)
{
TreeNode* q;
TreeNode* s;
//从二叉排序树中删除结点p,并重接它的左或右子树
if(p->rightChild == NULL){ //右子树空则只需重接它的左子树
q=p;
p=p->leftChild;
delete q;
}
else if(p->leftChild == NULL){ //左子树空只需重接它的右子树
q=p;
p=p->rightChild;
delete q;
}
else{ //左右子树均不空
q=p;
s=p->leftChild;
while(s->rightChild){ //转左,然后向右到尽头,找到左子树中最大元素,记录为s,q为s的父节点
q=s;
s=s->rightChild;
}
p->data = s->data; //s指向被删结点的“前驱”
/*s->rightChild为空,s->leftChild可能为空也可能不为空,
p=q说明s是p(即q)的左子节点,q->leftChild = s->leftChild;
p!=q说明s是q的右子节点,q->rightChild = s->leftChild;
*/
if(q!=p)
q->rightChild = s->leftChild; //重接*q的右子树,q为s的父节点
else
q->leftChild = s->leftChild; //重接*q的左子树,q为s的父节点
delete s;
}
return true;
}