1、二叉树的数据结构(数据域+指向左/右孩子节点的指针)
typedef struct tree
{
int data;
struct tree *left;
struct tree *right;
}Tree,*pTree;
2、创建二叉查找树
//创建二叉树(二叉查找树),返回根节点
pTree createTree(int *data,int len)
{
if (len<1)
{
cout<<"创建的树为空树!"<<endl;
return NULL;
}
pTree root=(pTree)malloc(sizeof(Tree));
root->data=data[0];
root->left=NULL;
root->right=NULL;
pTree current,back;
for (int i=1;i<len;i++)
{
pTree newNode=(pTree)malloc(sizeof(Tree));
newNode->data=data[i];
newNode->left=NULL;
newNode->right=NULL;
current=root;//每次插入新的节点时,current都指向root
while(current!=NULL)
{
back=current;
if (current->data>data[i])
current=current->left;
else
current=current->right;
}
if(back->data>data[i])
back->left=newNode;
else
back->right=newNode;
}
return root;
}
3、二叉树节点个数(递归法)
//递归求树的节点个数(左子树节点个数+右子树节点个数+根节点个数)
int getNode(pTree root)
{
if (root==NULL)
return 0;
else if (root->left==NULL&&root->right==NULL)
return 1;
else
return getNode(root->left)+getNode(root->right)+1;
}
4、二叉树的高度(递归法)
//递归求树的高度(左子树和右子树高度中的较大的值+根节点高度1)
int getHeight(pTree root)
{
if (root==NULL)
return 0;
int lh=getHeight(root->left);
int rh=getHeight(root->right);
return lh>rh ? lh+1:rh+1;
}
5、递归遍历二叉树
//递归进行前序遍历
void preTraverse(pTree root)
{
if (root!=NULL)
{
cout<<root->data<<" ";
preTraverse(root->left);
preTraverse(root->right);
}
}
//递归进行中序遍历
void midTraverse(pTree root)
{
if (root!=NULL)
{
midTraverse(root->left);
cout<<root->data<<" ";
midTraverse(root->right);
}
}
//递归进行后序遍历
void postTraverse(pTree root)
{
if (root!=NULL)
{
postTraverse(root->left);
postTraverse(root->right);
cout<<root->data<<" ";
}
}
6、非递归遍历二叉树
/**************************************************************************
* 利用栈进行前序遍历
* 1、从根节点开始,遍历左子树,输出父节点的内容,并将父节点入栈(这里用数组代替)
* 2、遍历遇到节点为NULL时,取出栈顶元素,得到其右孩子节点
* 3、右孩子节点不为空时,此时将该右节点看作是根节点,重复1、2操作
* 4、右孩子节点为空时,继续出栈,得到右孩子节点,重复3、4操作
**************************************************************************/
void prePrint(pTree root)
{
pTree p=root;
int height=getHeight(root);
pTree *sk=new pTree[height+1];
int cnt=0;
while(p!=NULL||cnt!=0)
{
if (p!=NULL)
{
cout<<p->data<<" ";
sk[cnt++]=p;
p=p->left;
}
else
{
p=sk[--cnt];
p=p->right;
}
}
delete []sk;
}
/****************************************************************************
* 利用栈进行中序遍历
* 1、从根节点开始,遍历左子树,将父节点入栈(这里用数组代替)
* 2、遍历遇到节点为NULL时,取出栈顶元素,输出节点内容,得到其右孩子节点
* 3、右孩子节点不为空时,此时将该右节点看作是根节点,重复1、2操作
* 4、右孩子节点为空时,继续出栈,重复3、4操作
****************************************************************************/
void midPrint(pTree root)
{
pTree p=root;
int height=getHeight(root);
pTree *sk=new pTree[height+1];
int cnt=0;
while(p!=NULL||cnt!=0)
{
if (p!=NULL)
{
sk[cnt++]=p;
p=p->left;
}
else
{
p=sk[--cnt];
cout<<p->data<<" ";
p=p->right;
}
}
delete []sk;
}
/**********************************************************************
* 利用栈后序遍历
* 1、首先创建一种新的数据结构,包含原来的数据结构和isFirst标志()
* 2、从根节点开始,入栈,将isFirst置为1,访问左子树
* 3、遇到节点为NULL时,如果isFirst==1,访问栈顶元素,得到该节点的右孩子
* 4、该节点的右孩子为NULL时,出栈,访问该节点,然后将该节点置为NULL,使下次循环必定会进入第3步
* 5、该节点的右孩子不为NULL时,将该右孩子当作根节点,重复2、3
**********************************************************************/
void postPrint(pTree root)
{
int height=getHeight(root);
struct TPostTree //节点新的数据结构
{
pTree node;
int isFirst;
};
TPostTree *sk=new TPostTree[height+1];
int cnt=0;
pTree p=root;
while(p!=NULL||cnt!=0)
{
if (p!=NULL) //左
{
sk[++cnt].node=p;
sk[cnt].isFirst=1;
p=p->left;
}
else if (sk[cnt].isFirst) //右
{
sk[cnt].isFirst=0;
p=sk[cnt].node->right; //根据sk保存的找到右节点
}
else //根节点
{
p=sk[cnt--].node;
cout<<p->data<<" ";
p=NULL; //保证下次循环必定进入if的else分支
}
}
delete []sk;
}
7、按层遍历二叉树
/***************************************************************************
* 按层遍历
* 1、访问根节点,将根节点进队
* 2、取出队列的第一个元素,访问该元素,并将取出的该元素节点的左右孩子节点(不为NULL)进队
* 3、循环进行第二步,直至队列为空
* 4、下面的代码用数组替换了队列
***************************************************************************/
void BTraverse(pTree root)
{
int n=getNode(root);
pTree *sk=new pTree[n],p;
int front=0,rear=0;
sk[front]=root;
while(front!=n)
{
p=sk[front];
cout<<p->data<<" ";
if (p->left!=NULL)
{
sk[rear+1]=p->left;
rear++;
}
if (p->right!=NULL)
{
sk[rear+1]=p->right;
rear++;
}
front++;
}
cout<<endl;
delete []sk;
}