0、二叉树的结点表示
if(p->lchild != NULL && p->rchild != NULL)//度为2的结点,左右孩子同时不空
if((p->lchild == NULL && p->rchild != NULL) || (p->lchild != NULL && p->rchild == NULL))//度为1的结点,左孩子不为空,或者右孩子不为空
if(p->lchild == NULL && p->rchild == NULL)//度为0的结点,两个孩子都为空
1、二叉树的先序遍历递归与非递归
void preorder(BiTree T)
{
if(T != NULL)
{
visit();
preorder(T->lchild);
preorder(T->rchild);
}
}
//一直入栈往左走,到头出栈掉个头
void preorder(BiTree T)
{
InitStack(S);
p = T:
while(p != NULL || !StackEmpty(S))
{
if(p !=NULL)
{
printf(p->data);
push(S,p);
p = p->lchild;
}
else
{
pop(S,p);
p = p->rchild;
}
}
}
2、二叉树的中序遍历
void Inorder(BiTree T)
{
if( T != NULL)
{
Inorder(T->lchild);
visit(T);
Inorder(T->rchild);
}
}
void Inorder(BiTree T)
{
InitStack(S);
p = T;
while(p != NILL || !StackEmpty(S))
{
if(p != NULL)
{
push(S,p);
p = p->lchild;
}
else
{
pop(S,p);
printf(p->data);
p = p->rchild;
}
}
}
3、二叉树的后序遍历
void postorder(BiTree T)
{
if(T != NULL)
{
postOrder(T->lchild);
postorder(T->rchild);
visit(T);
}
}
void PostOrder(BiTree T)
{
InitStack(T);
p = T;
while(p != NULL || !StackEmpty(s))
{
if(p != NULL)
{
push(S,p);
p = p->lchild;
}
else
{
pop(S,p);
if(p->rchild == NULL && (p->rchild).tag == 0)//如果右孩子为空或者标志位为0则
{
push(S,p);
p = p->rchild;
}
else//如果top的右孩子为空且没有被访问过则输出
{
printf(p->data);
p.tag = 1;
p = NULL;
}
}
}
}
4、二叉树的层序遍历算法
void LevelOrder(BiTree T)
{
InitQueue(Q);
BiTree p;
EnQueue(Q,T);
while(!IsEmpty(Q))
{
DeQueue(Q,p);
visit(p);
if(p->lchild != NULL)
EnQueue(Q,p->lchild);
if(p->rchild != NULL)
EnQueue(Q,p->rchild);
}
}
void levelorder(BiTree T)
{
BiTree Q[MAXSIZE];
BiTree p = T;
int front = -1,rear = -1;
int last = 0,level = 0;
Q[++rear] = T;
while(front < rear)//队列不为空
{
p = Q[++front];
if(p->lchild)
Q[++rear] = p->lchild;
if(p->rchild)
Q[++rear] = p->rchild;
}
}
5、编写二叉树自下而上,从右到左的层序遍历算法
算法思想
一般的二叉树层序遍历是自上而下,从左到右的顺序,可以将每一次访问的结点入栈,遍历结束后在出栈
void LevelOrder(BiTree T)
{
InitQueue(Q);
InitStack(S);
BiTree p = T;
EnQueue(Q,p);
while(!isEmpty(Q))
{
DeQueue(Q,p);
posh(S,p);
if(p->lchild != NULL)
{
Enqueue(Q,p->lchild);
}
if(p->rchild != NULL)
{
Enqueue(Q,p->rchild)
}
}
while(IsEmpty(s))
{
pop(S,p);
visit(p->data);
}
}
6、求二叉树中层序的最高度
int Bidepth(BiTree T)
{
if(T == NULL)
{
return 0;
}
else
{
BiTree Q[Maxsize];
BiTree p;
int front = -1,rear = -1;
int last = 0,level = 0;
Q[++rear] = T;
while(front < rear)
{
p = Q[++front];
if(p->lchild != NULL)
Q[++rear] = p->lchild;
if(p->rchild != NULL)
Q[++rear] = p->rchild;
if(front == level)
{
level++;
last = rear;//last指向当前层数的最右结点,这个地方不是很理解,硬记!
}
}
}
}
7、求二叉树中宽度
int Width(BiTree T)
{
if(T == NULL)
{
return 0;
}
else
{
BiTree Q[MAXSIZE];
BiTree p;
int front = -1,rear = -1;
int last = 0,count = 0;
Q[++rear] = T;
while(front < rear)
{
p = Q[++front];
temp++;
if(p->lchild != NULL)
Q[++rear] = p->lchild;
if(p->rchild != NULL)
Q[++rear] = p->rchild;
if(front > last)//不是很理解为啥
{
last = rear;//为沙
if(temp > maxw)
maxw = temp;
temp = 0;
}
}
}
return maxw;
}
8、计算二叉树所有结点个数
int Node(BiTree T)
{
int num1,num2;
if(T == NULL)
return 0;
else
{
num1 = Node(T->lchild);
num2 = Node(T->rchild);
return (num1 + num2 + 1);//因为有根结点所有要+1
}
}
9、计算二叉树所有的叶子结点(度为1的结点)
int Node(BiTree T)
{
if(T == NULL)
return 0;
else if(T->lchild == NULL && T->rchild == NULL)
return 1;
else
{
num1 = Node(T->lchild);
num2 = Node(T->rchild);
return num1+num2;
}
}
10、计算二叉树中双分支结点(度为2的结点)
int Node(BiTree T)
{
if(T == NULL)
return 0;
else if(T->lchild == NULL || T->rchild == NULL)//当n为单分支时不计算
n = 0;
else//当为双分支时n=1
n = 1;
num1 = Node(T->lchild);
num2 = Node(T->rchild);
return (num1+num2+n)
}
int
11、求二叉树中最小值的结点
int FindMinNode(BiTree T)
{
if(T != NULL)
{
if(T->data < min)
{
min = T->data;
}
FindMinNode(T->lchild,min);
FindMinNode(T->rchild,min);
}
}
int preorder(BiTree T)
{
min = 0
if(T != NULL)
{
if(min > T->data)
min = T->data;
preorder(T->lchild);
preorder(T->rchild);
}
return min;
}
12、求二叉树所有结点值的和
int Findsum(BiTree T)
{
if(T == NULL)
return 0;
else
return (T->data + Findsum(T->lchild) + Findsum(T->rchild));
}
int preorder(BiTree T)
{
int sum = 0
if(T != NULL)
{
sum += T->data;
preorder(T->lchild);
preorder(T->rchild);
}
return sum;
}
13、求二叉树中值为x的结点
int FindCount(BiTree T,int x)
{
count = 0;
if(T != NULL)
{
if(T->data == x)
count++;
FindCount(T->lchild);
FindCount(T->rchild);
}
return count;
}
int FindCount(BiTree T,int x)
{
if(T == NULL)
return 0;
else if(T->data == x)
return (1+FindCount(T->lchild,x) + FindCount(T->rchild,x));
else
return (FindCount(T->lchild,x) + FindCount(T->rchild,x));
}
14、求二叉树结点的高度
int Depth(BTNode *T)
{
if(T == NULL)
return 0;
else
{
ldeep = Depth(T->lchild);
rdeep = Depth(T->rchild);
return (ldeep > rdeep):(ldeep + 1):(rdeep + 1);//加1是因为根结点
}
}
15、求指定值x的双亲结点p(没看懂)
算法思想
在二叉树中查找x的双亲结点,找到后p指向x结点的双亲结点否则p=NULL,当b为空或根结点为x时,p=NULL
void FindParent(BiTree T,int x,BiTree &p)
{
if(T != NULL)
{
if(T->data == x)
{
p = NULL;
}
else if(T->lchild != NULL && T->lchild->data == x)//如果T->lchild 不为空或者T->lchild==x则
{
p = b;
}
else if(T->rchild != NULL && T->rchild->data == x)
{
p = b;
}
else
{
FindParent(T->lchild,x,p);
if(p == NULL)
FIndParent(T->rchild,x,p);
}
}
else
{
p = NULL;
}
}
16、交换树b的左右子树
void Swap(BiTree T)
{
BiTree *Temp;
if(T != NULL)
{
Swap(T->lchild);
Swap(T->rchild);
temp = T->lchild;
T->lchild = T->rchild;
T->rchild = temp;
}
}
17、求二叉树T中值为x的层号
int level(BiTree T)
{
InitQueue(Q);
P = T;
Enqueue(Q,p);
while(!IsEmpty(Q))
{
DeQueue(Q,p);
visit(p);
if(p->lchild != NULL)
Enqueue(Q,p->lchild);
if(p->rchild != NULL)
Enqueue(Q,p->rchild);
}
}
int level(BiTree T)
{
if(T == NULL)
{
return 0;
}
else
{
BiTree Q[MAXSIZE];
BiTree p;
int front = -1,rear = -1;
int last = 0,level = 0;
Q[++rear] = T;
while(front < rear)
{
p = Q[++front];
if(p->data == x)
return level;
if(p->lchild != NULL)
{
Q[++rear] = p->lchild;
}
if(p->rchild != NULL)
{
Q[++rear] = p->rchild;
}
if(front == level)
{
level++;
last = rear;
}
}
}
}
int NodeLevel(BiTree T,int x,int h)
{
int h1;
if(T == NULL)
return 0;
else if(T->data == x)
return h;
else
{
h1 = NodeLevel(T->lchild,x,h+1);//在左子树中递归查找
if(h1 == 0)//为沙呀,没看懂
return NodeLevel(T->rchild,x,h+1);//左子树中为找到在右子树查找
else
return h1;
}
}
18、求先序遍历中第k个结点的值
算法思想
用全局变量n保存先序遍历时访问结点,
当二叉树为空时返回空,
当k==n时表示找到结点,
当k!=n时,在左子树找,若找到返回,否则在右子树找,返回
int preorder(BiTree T,int k)
{
int count = 0;
p = T;
if(p != NULL)
{
if(k == count)
visit(p->data);
count++;
preorder(p->lchild);
preorder(p->rchild);
}
}
int preNode(BiTree T,int k)
{
if(T == NULL)
return 0;
if(n == k)
return T->data;
n++;
ch = PreNode(T->lchild,k);
if(ch != NULL)
return ch;
ch = PreNode(T->rchild,k);
return ch;
}
19、中序遍历中第k的结点
ElemType InNOde(BiTree T,int k)
{
if(T == NULL)
{
return 0;
}
ch = InNode(T->lchild);//在左子树中找
if(ch != NULL)//找到返回
return ch;
else//在右子树找
{
if(n == k)
return T->data;
n++;
return InNode(T->rchild,k);
}
}
20、后序遍历中第k的结点
ElemType PostNode(BiTree T,int k)
{
if(T == NULL)
return 0;
ch = postnode(T->lchild,k);
if(ch != NULL)
return ch;
else
{
ch = postNode(T->rchild,k);
if(ch != NULL)
return ch;
if(n == k)
return T->data;
n++;
}
}
21、求二叉树的WPL
算法思想
基于先序遍历,记录每个wpl把每个结点的深度作为递归函数的一个参数
int wpl_preorder(BiTree T,int deep)
{
int wpl = 0;
if(T->lchild == NULL && T->rchild == NULL)//叶子结点,度为0的结点计算wpl
wpl = wpl + deep*T->weight;
if(T->lchild != NULL)
wpl_preorder(T->lchild,deep+1);
if(T->rchild != NULL)
wpl_preorder(T->lchild,deep+1);
return wpl;
}
22、将二叉树转为中缀表达式,通过括号反映出优先级次序
算法思想
如果是叶子结点输出,除根结点外,遍历左子树之前加左括号,遍历完右子树加右括号
typedef struct Node
{
char data[10];
struct node *left,*right;
}BiTree;
void BtreeToExp(BiTree T,int deep)
{
if(T == NULL)
return 0;
else if(T->left === NULL && T->right == NULL)//如果是叶子结点则输出
print(T->data);
else
{
if(deep > 1) //若有子表达式,则加括号
printf("(");
BtreeToExp(T->left,deep+1);
printf(T->data);
BtreeToExp(T->right,deep+1);
if(deep > 1)//加括号
printf(")");
}
}
23、输出从根到叶子结点的路径
int path(BiTree *p)
{
int i = 0,top = 0;
ElemType stack[MAXSIZE];
if(p != NULL)
{
stack[++top] = p->data;
}
if(p->lchild == NULL && p->rchild == NULL)
{
for(i = 0;i < top;i++)
{
printf(stack[i]);
}
}
path(p->lchild);
path(p->rchild);
--top;
}
24、判断二叉树是否为完全二叉树
算法思想
如果树为空,则直接返回错。
如果树不为空,层次遍历二叉树 ;
如果树左孩子为空,右孩子不为空,则该树一定不是完全二叉树;
如果树左右孩子都不为空,则pop该节点,将其左右孩子入队列;
如果树左孩子不为空,右孩子为空;或者左右孩子都为空;则该节点之后的队列中的结点都为叶子节点;
该树才是完全二叉树,否则就不是完全二叉树。
void level(BiTree T)
{
InitQueue(Q);
EnQueue(Q,T);
if(T == NULL)
return 0;
while(!isempty(Q))
{
if(T->lchild == NULL && T->rchild != NULL)//如果左子树为空,右子树不为空则肯定不是完全二叉树
return 0;
if(T->lchild != NULL && T->rchild != NULL)//如果左右孩子都不为空
{
DeQueue(Q,T);
EnQueue(Q,T->lchild);
EnQueue(Q,T->rchild);
}
if((T->lchild != NULL && T->rchild == NULL) || T->lchild == NULL && T->rchild != NULL)//为叶子结点
{
DeQueue(Q,T);
while(QueueLength(Q))
{
if(T->lchild == NULL && T->rchild == NULL)
{
DeQueue(Q,t);
}
else
{
return 0;
}
return 1;
}
}
//DeQueue(Q,p);
//if(p->lchild != NULL)
// EnQueue(Q,p->lchild);
//if(p->rchild != NULL)
// EnQueue(Q,p->rchild);
}
return 1;
}