0.二叉树结构体
typedef struct treenode{
struct treenode * lchild,rchild;
int info;
int tag;
}*tree;
0.二叉树的建立
void buildtree(tree t)
{
char ch;
ch=getchar();
if(ch='#') return t=NULL;
else{
t=(tree)malloc(sizeof(treenode));
t->info=ch;
t->lchild=NULL;
t->rchild=NULL;
buildtree(t->lchild);
buildtree(t->rchild)
}
}
1.前序递归
void preOrder(tree t)
{
printf(”%d“,t->info);
preOrder(t->lchild);
preOrder(t->rchild);
}
2.递归后续
void lastOrder(tree t)
{
preOrder(t->lchild);
preOrder(t->rchild);
printf(”%d“,t->info);
}
3.递归中序
void midOrder(tree t)
{
preOrder(t->lchild);
printf(”%d“,t->info);
preOrder(t->rchild);
}
4.非递归前序
void preOrder(tree t)
{
treenode *stack[10];
treenode *p;
p=t;
int top=-1;
while(p || top!=-1)
{
if(p)
{
top++;
stack[top]=p;
printf("%d",p->info);
p=p->lchild;
}else{
p=stack[top];
top--;
p=p->rchild;
}
}
}
5.非递归中序
void preOrder(tree t)
{
treenode *stack[10];
treenode *p;
p=t;
int top=-1;
while(p || top!=-1)
{
if(p)
{
top++;
stack[top]=p;
p=p->lchild;
}else{
p=stack[top];
top--;
printf("%d",p->info);
p=p->rchild;
}
}
}
6.非递归后续
void preOrder(tree t)
{
treenode *stack[10];
treenode *p;
p=t;
int top=-1;
while(p || top!=-1)
{
if(p)
{
top++;
stack[top]=p;
p=p->lchild;
}else{
p=stack[top];
if(p->rchild&&p->rchild->tag==0)
p=p-rchild;
else{
p=stack[top];
top--;
printf("%d",p->info);
p->tag=1;
p=NULL;
}
}
}
}
7.递归树高 (***)
int depth(tree t)
{
int lh,rh,h;
if(t==NULL)return 0;
else{
lh=depth(t->lchild);
rh=depth(t->rchild);
if(lh>=rh)
h=lh+1
else
h=rh+1;
}
return h;
}
8.非递归树高 (***)
int depth(tree t)
{
if(t==NULL) return 0;
treenode *s[10];
treenode *p;
int front=-1,rear=-1;
int h=0,L=0;
s[++rear]=t;
if(front<rear)
{
p=s[++front];
if(p->lchild)
s[++rear]=p->lchild;
if(p->rchild)
s[++rear]=p->rchild;
if(front==L)
{
L=rear;
h++;
}
}
return h;
}
9.前序遍历最后一个元素
void preOrderlast(tree t)
{
if(t->rchild)
t=preOrderlast(t->rchild);
else
t=preOrderlast(t->lchild);
return t;
}
10.中序遍历第一个元素
void midOrderfirst(tree t)
{
if(t->lchild)
t=midOrderfirst(t->lchild);
return t;
}
11.中序遍历最后一个元素
void midOrderlast(tree t)
{
if(t->rchild)
t=midOrderlast(t->rchild);
return t;
}
12.后续遍历第一个元素
void postOrderfirst(tree t)
{
if(t->lchild)
t=postOrderfirst(t->lchild);
else
t=postOrderfirst(t->rchild);
return t;
}
13.交换左右子树
void change(tree t)
{
tree p;
if(t)
{
p=t->rchild;
t->rchild=t->lchild;
t->lchild=t->rchild;
change(t->lchild);
change(t->rchild);
}
}
14.双分支结点个数 (****)
int num(tree t)
{
if(t==NULL)
return 0;
if(t->rchild&&t->lchild)
return num(t->lchild)+num(t->rchild)+1;
else
return num(t->lchild)+num(t->rchild);
}
15.总结点个数
1.递归
int sum(tree t)
{
if(!t) retrun 0;
else{
return sum(t->lchild)+sum(t->rchild)+1;
}
16.叶子结点个数
1.递归
int CountLeafCount(tree t)
{
if(t==NULL)
return 0;
if(t->lchild==NULL&&t->rchild==NULL)
return 1;
return CountLeafCount(t->rchild)+CountLeafCount(t->lchild);
}
2.非递归
int CountLeafCount(tree t)
{
int count=0;
int top=-1;
tree stack[100];
while(t!=NULL || top!=-1)
{
while(t!=NULL)
{
if(t->lchild==NULL&&t->rchild==NULL)
count++;
s[++top]=t;
t=t->lchild;
}
if(top!=-1)
{
t=s[--top];
t=t->rchild;
}
}
return count;
}
17.第k层结点个数
/*
递归解法:
(1)如果二叉树为空或者k<1返回0
(2)如果二叉树不为空并且k==1,返回1
(3)如果二叉树不为空且k>1,返回左子树中k-1层的节点个数与右子树k-1层节点个数之和
*/
int getCountK(tree t,int k)
{
if(k<0 ||t==NULL) return 0;
if(!t) return 0;
if(k==1) return1;
else
return getCountK(t->lchild,k-1)+getCountK(t->rchild,k-1);
}
18.层序遍历 (****)
void levelOrder(tree t)
{
squeue q[10];
int front,rear,tag;
front=rear=tag=0;
treenode *p;
EnQueue(q,t);
while(!(front==rear&&tag==0))
{
DeQueue(q,p);
printf("%c",p->info);
if(p->lchild)
EnQueue(q,p->lchild);
if(p->rchild)
EnQueue(q,p->rchild);
}
}
19.判断二叉树等价 (****)
int isequal(tree t1,tree t2)
{
int t;
t=0;
if(t1==NULL&&t2==NULL)
return 1;
else{
if(t1!=NULL&&t2!=NULL)
if(t1->info==t2->info)
if(isequal(t->lchild,t->lchild))
t=isequal(t->rchild,t->rchild)
}
return t;
}
20.查找第x结点 (****)
tree searchX(tree t,char x)
{
if(t==NULL)
return NULL;
else{
if(t->data == x) return t;
else{
p->searchX(t->lchild);
if(p)
return p;
else
p=searchX(t->rchild);
}
}
}
21.返回X结点所在二叉树的层数
int Level(tree t, char x,int h)
{
int l;
if (t == NULL)
return 0;
else if (t->data == x)
return h;
else
{
l = Level(t->lchild, x,h+1);
if (l == 0)
return Level(t->rchild, x, h + 1);
else
return l;
}
}
22.根据前序和中序和长度,返回二叉树根地址
tree findKey(treenode* t, int key1, int key2) {
if (t == NULL) return NULL;
if (t->data == key1 || t->data == key2) return t; // 1. 其中一个key在root上;
treenode* left = findKey(t->lchild, key1, key2);
treenode* right = findKey(t->rchild, key1, key2);
if (left && right) return t; // 2. key分布在两侧
if (left) return left; // 3. key分布在一侧:左侧
if (right) return right; // 3. key分布在一侧:右侧
return NULL;
}
23.求公共祖先
typedef struct node /*二叉树结点定义*/
{
char data;
struct node* lchild, * rchild;
}bintnode;
typedef bintnode* bintree;
typedef struct stack //顺序栈结构定义
{
bintree data[100];
int tag[100];
int top;
}seqstack;
void creat(bintree* t);
void SeekAncestor(bintree t, char x, char y, bintree* antor)
{
seqstack s;
bintree data[100] = { 0 };
int i = 0, j;
s.top = -1;
while (t || s.top > -1)
{
while (t)
{
s.data[++s.top] = t;
s.tag[s.top] = 0;
t = t->lchild;
}
while (s.top > -1 && s.tag[s.top])
{
t = s.data[s.top];
if (t->data == x)
while (i <= s.top) //记录 x 结点的所有祖先结点
{
data[i] = s.data[i];
i++;
}
else
if (t->data == y)
{
while (s.top > -1)
{
j = i - 1;
while (j >= 0 && t != data[j])
//查找 y 与 x 的最近公共祖先结点
j--;
if (j >= 0)
{
*antor = data[j]; //返回公共祖先结点地址
return;
}
t = s.data[--s.top];
}
}
--s.top;
}
if (s.top > -1)
{
t = s.data[s.top];
s.tag[s.top] = 1;
t = t->rchild;
}
else t = NULL;
}
}
24.二叉排序树
1.二叉排序树建立
treenode* buildBst()
{
treenode *t = NULL;
int data;
printf("\n请输入666为结束标记");
scanf("%d", &data);
while (data != 666)
{
InsertBstree(&t, data);
scanf("%d", &data);
}
return t;
}
2.插入
treenode* InsertBstree(treenode* t, int data)
{
treenode *temp, *p;
p = t;
while (p)
{
if (data == p->data)return;//二叉排序树中已有此data不用插入
temp = p;//用temp存储p
p = (data < p->data) ? p->lchild : p->rchild;
}
p = (treenode*)malloc(sizeof(treenode));//生成待插入的新结点
p->data = data;
p->lchild = p->rchild = NULL;
if (t == NULL)
t = p;
else
{
if (data < temp->data)
temp->lchild = p;
else
temp->rchild = p;
}
}
3.判断二叉排序树
int IsBST(const tree t) //递归遍历二叉树是否为二叉排序树
{
if (!t) //空二叉树情况
return 1;
else if (!(t->lchild) && !(t->rchild)) //左右子树都无情况
return 1;
else if ((t->lchild) && !(t->rchild)) //只有左子树情况
{
if (t->lchild->data > t->data)
return 0;
else
return IsBST(t->lchild);
}
else if ((t->rchild) && !(t->lchild)) //只有右子树情况
{
if (t->rchild->data < t->data)
return 0;
else
return IsBST(t->rchild);
}
else //左右子树全有情况
{
if ((t->lchild->data > t->data) || (t->rchild->data < t->data))
return 0;
else
return (IsBST(t->lchild) && IsBST(t->rchild));
}
}
25.穿线二叉树
1.结构体
typedef struct treenode {
char data;
struct treenode* lchild, * rchild;
int ltag,rtag;
}treenode,*tree;
2.创建穿线二叉树
tree pre; // 全局变量,始终指向刚刚访问过的结点
// 中序遍历进行中序线索化
void InThreading (tree p)
{
if(p)
{
InThreading(p->lchild); // 递归左子树线索化
if(!p->lchild) // 没有左孩子
{
p->LTag=Thread; //前驱线索
p->lchild=pre; //左孩子的指针指向前驱
}
if(!pre->rchild) //前驱没有右孩子
{
pre->RTag=Thread; // 后继线索
pre->rchild=p;
}
pre=p; // 保持pre始终指向p的前驱
InThreading(p->rchild);
}
}
3.穿线二叉树线索化
void InThread(tree p, tree* pre) {
// 中序遍历对二叉树线索化的递归算法
if (p) {
InThread(p->lchild, pre); // 递归,线索化左子树
if (!p->lchild) { // 左子树为空,则建立前驱线索
p->lchild = *pre;
p->ltag = 1;
}
if (*pre && !(*pre)->rchild) { // 建立前驱结点的后继线索
(*pre)->rchild = p;
(*pre)->rtag = 1;
}
*pre = p; // 标记当前结点成为刚刚访问过的结点
InThread(p->rchild, pre); // 递归,线索化右子树
}
}
void CreateInThread(ThreadTree T)
{// 通过中序遍历建立中序线索二叉树的主过程
ThreadTree pre = NULL;
if (T) { // 非空二叉树,线索化
InThread(T, &pre); // 线索化二叉树
pre->rchild = NULL; // 处理遍历的最后一个结点
pre->rtag = 1;
}
}
4.中序遍历穿线二叉树
tree insuccnode(tree p) //寻找p结点中序下的后继结点
{
tree q;
if (p->rtag == 1) //p的右指针为线索,恰巧指向p的后继结点
return p->rchild;
else
{
q = p->rchild; //寻找p的右子树中最左下的结点
while (q->ltag == 0)
q = q->lchild;
return q;
}
}
5.中序遍历中序穿线二叉树
void inthrtree(tree p)
{
if (p)
{
while (p->ltag == 0)
p = p->lchild; //求p遍历下的第一个结点
do
{
printf("%c", p->data);
p = insuccnode(p); //求p中序遍历下的后继结点
} while (p);
}
}
Q.E.D.