
void PostOrder(BiTree T)
{
InitStack(S);
p = T;r = NULL;
while (p || Is_Empty(S)) {
if (p) {
push(S,p);
p = p->lchild;
} else {
GetTop(S,p);
if (p->rchild&&p->rchild != r) {
push(S,P->rchild);
p = p->rchild;
} else {
pop(S,p);visit(p->data);
r = p;p = NULL;
}
}
}
}
附注:
void PreOrder(BiTree T)
{
if (T != NULL) {
visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
void InOrder(BiTree T)
{
if (T != NULL) {
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}
void PostOrder(BiTree T)
{
if (T != NULL) {
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
}
void InOrder2(BiTree T)
{
InitStack(S);BiTree p = T;
while (p || !IsEmpty(S)) {
if (p) {
Push(S,p);
p = p->lchild;
} else {
Pop(S,p);visit(p);
p = p->rchild;
}
}
}
void PreOrder2(BiTree T)
{
InitStack(S);BiTree p = T;
while (p || !IsEmpty(S)) {
if (p) {
visit(p);Push(S,p);
p = p->lchild;
} else {
Pop(S,p);
p = p->rchild;
}
}
}
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 InvertLevel(BiTree bt)
{
Stack S;Queue Q;
if (bit != NULL) {
InitStack(S);
InitQueue(Q);
EnQueue(Q,bt);
while (IsEmpty(Q) == false) {
DeQueue(Q,p);
Push(s,p);
if (p->lchild)
EnQueue(Q,p->lchild);
if (p->rchild)
EnQueue(Q,p->rchild);
}
while (IsEmpty(s) == false) {
Pop(s,p);
visit(p->data);
}
}
}
按照先序遍历,叶子结点出栈时的栈的长度就是深度
//二叉链表的结构
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//层次遍历二叉树
int GetBiTreeHeigth(BiTree T){
if(T==NULL) retrun 0; //空树,高度为0;
InitQueue Q[MaxSize]; //初始化一个空队列;
int front =-1,rear=-1;
int last=0;
int level =0;
BiTree P;
//EnQueue(Q,T); //将当前结点入队;
Q[++rear] = T;
while(front <rear){
P = Q[++front]; //出队,DeQueue(Q,Q.front);
//访问当前结点visit(T);
if(P->lchild){
Q[++rear] = P->lchild; //EnQueue(Q,T->lchild);
}
if(P->rchild){
Q[++rear] = P->rchild; //EnQueue(Q,T->rchild);
}
if(front==last){//当前层最后结点;
level++;
last=rear;//上一层最后一个节点,出队的时候,队首正好是下一层的最后一个节点
}
}
return level;
}
int Btdepth2(BiTree T)
{
if(T == NULL) {
return 0;
}
ldep = Btdepth2(T->lchild);
rdep = Btdepth2(T->rchild);
return max(ldep,rdep)+1;
}
BiTree PreInCreat(ElemType A[],ElemType B[],int l1,int h1,int l2,int h2)
{
root = (BiTNode*)malloc(sizeof(BiTNode));
root->data = A[l1];
for(i = l2;B[i]!=root->data;i ++) ;
llen = i-l2;
rlen = h2-i;
if (llen) root->lchild = PreInCreat(A,B,l1+1,l1+llen,l2,l2+llen-1);
else root->lchild = NULL;
if (rlen) root->rchild = PreInCreat(A,B,h1-rlen+1,h1,h2-rlen+1,h2);
else root->rchild = NULL;
return root;
}
层次遍历,遇到一个只有左儿子或者
bool IsComplete(BiTree T)
{
InitQueue(Q);
if (!T)
return 1;
EnQueue(Q,T);
while (!IsEmpty(Q)) {
DeQueue(Q,p);
if (p) {
if (p->lchild==NULL&&p->rchild) return 0;//只有右儿子,没有左儿子。
EnQueue(Q,p->lchild);
EnQueue(Q,p->rchild);
} else {
while (!IsEmpty(Q)) {
DeQueue(Q,p);
if (p)
return 0;
}
}
}
return 1;
}
层次遍历或者递归
int DsonNodes(BiTree b)
{
if (b == NULL)
return 0;
else if (b->lchild != NULL&&b->rchild != NULL) {
return DsonNodes(b->lchild) + DsonNodes(b->rchild) + 1;
} else {
return DsonNodes(b->lchild) + DsonNodes(b->rchild);
}
}
创建一个新树,递归赋值-左子树赋给右儿子,右子树赋给左儿子
这个想法可能有点问题
void swap(BiTree b)
{
if (b) {
swap(b->lchild);
swap(b->rchild);
temp = b->lchild;
b->lchild = b->rchild;
b->rchild = temp;
}
}
//own idea;
BiTree T2;
void swap2(BiTree T,BiTree T2)
{
if(T) {
swap(T->lchild,T2->lchild);
swap(T->rchild,T2->rchild);
T2->lchild = T->rchild;
T2->rchild = T->lchild;
}
}
直接操作就行
int i = 1;
ElemType PreNode(BiTree b,int k)
{
if (b == NULL) return '#';
if (i == k)
return b->data;
i ++;
ch = preNode (b->lchild,k);
if (ch != '#')
return ch;
ch = PreNode(b->rchild,k);
return ch;
}
看代码
void Search(BiTree bt,ElemType x)
{
BiTree Q[];
if (bt) {
if (bt->data == x) {
DeleteXTree(bt);
exit(0);
}
InitQueue(Q);
EnQueue(Q,bt);
while (!IsEmpty(Q)) {
DeQueue(Q,p);
if (p->lchild) {
if (p->lchild->data == x){
DeleteXTree(p->lchild);
p->lchild = NULL;
} else {
EnQueue(Q,p->lchild);
}
}
if (p->rchild) {
if (p->rchild->data == x) {
DeleteXTree(p->rchild);p->rchild = NULL;
} else{
EnQueue(Q,p->rchild);
}
}
}
}
}
非递归后序遍历,找到值为x的结点时,把栈中所有元素打印出来。
void Search(BiTree bt,ElemType x)
{
stack s[];
top = 0;
while (bt != NULL || top > 0) {
while (bt != NULL&&bt->data != x) {
s[++top].t = bt;
s[top].tag = 0;
bt = bt->lchild;
}
if (bt != NULL&&bt-data==x) {
printf("所查结点的所有祖先结点的值为:\n");
for (i = 1;i <= top;i ++)
printf("%d",s[i].t->data);
exit(1);
}
while (tag != 0&&s[top].tag == 1) {
top --;
}
if (top != 0) {
s[top].tag = 1;
bt = s[top].t->rchild;
}
}
}
一直除以2
倍增求LCA
答案思路:
采用后序非递归算法,栈中存放二叉树结点的指针,当访问到某结点时,栈中所有元素均为该结点的祖先。假设p在q的左边,后序遍历先访问到p,先将栈中元素复制到另一辅助栈中。继续遍历到结点q时,将栈中元素从栈顶开始逐个到辅助栈中匹配,第一个匹配的就是LCA。
略。。。不是最优
层次遍历,一次整完一层的元素,然后队列最大长度就是所求
//求二叉树的宽度
int WidthOfBiTree(BiTree root)
{
if(root == NULL)
return 0;
int maxWidth = 0;
deque<BiTree> d;
d.push_back(root);
while(true)
{
int len = d.size();
if(len == 0)
break;
while(len > 0)
{
BiTree temp = d.front();
d.pop_front();
len--;
if(temp->Lchild)
d.push_back(temp->Lchild);
if(temp->Rchild)
d.push_back(temp->Rchild);
}
maxWidth = maxWidth > d.size() ? maxWidth : d.size();
}
return maxWidth;
}
void PreToPost(ElemType pre[],int l1,int h1,ElemType post[],int l2,int h2)
{
int half;
if (h1 >= l1) {
post[h2] = pre[l1];
half = (h1 - l1)/2;
PreToPost(pre,l1+1,l1+half,post,l2,l2+half-1);
PreToPost(pre,l1+half+1,h1,post,l2+half,h2-1);
}
}
层次遍历,队列中存放结点——错误思路,因为不是完全二叉树
答案 :中序遍历,设置前驱节点指针pre。第一个叶结点右指针head指向,遍历到叶结点时,就将它前驱的rchild指针指向它,子u后一个叶结点的rchild为空。
LinkedList head, pre = NULL;
LinkedList InOrder(BiTree bt)
{
if (bt) {
InOrder(bt->lchild);
if (bt->lchild == NULL&&bt->rchild == NULL) {
if (pre == NULL) {
head = bt;
pre = bt;
} else {
pre ->rchild = bt;
pre = bt;
}
}
InOrder(bt->rchild);
pre->rchild = NULL;
}
return head;
}
递归
int similar(BiTree T1,BiTree T2)
{
int leftS,rightS;
if (T1 == NULL &&T2 == NULL) {
return 1;
} else if (T1 == NULL||T2== NULL) {
return 0;
} else {
leftS = similar(T1->lchild,T2->lchild);
rightS = similar(T1->rchild,T2->rchild);
return leftS&&rightS;
}
}
算法思想:
在后序序列中,若结点p有右子女,则右子女是其前驱,若无右子女而有左子女,则左子女是其前驱。若结点为叶子,若其中序左线索指向某祖先节点f,若f有左子女,则其左子女是结点p的后序前驱;若f无左子女,则顺其前驱找双亲的双亲,直到找到双亲有左子女。还有一种情况,若p是中序遍历的第一个结点,则结点p在中序和后序下均无前驱。
BiThrTree InPostPre(BiThrTree t,BiThrTree p)
{
BiThrTree q;
if (p->rtag == 0) q=p->rchild;
else if (p->ltag == 0) q = p->lchild;
else if (p->lchild== NULL) q=NULL;
else {
while (p->ltag==1&&p->lchild!=NULL)
p = p->lchild;
if (p->ltag==0) q = p->lchild;
else q = NULL;
}
return q;
}
typedef struct BiTNode{
int weight;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
int WPL(BiTree root) {
return wpl_PreOrder(root,0);
}
int wpl_PreOrder(BiTree root,int deep)
{
static int wpl = 0;
if (root->lchild== NULL&&root->rchild== NULL) wpl+=deep*root->weight;
if (root->lchild!= NULL) wpl_PreOrder(root->lchild,deep+1);
if (root->rchild!= NULL) wpl_PreOrder(root->rchild,deep+1);
return wpl;
}
typedef struct
{
LBTree* p;
int lno;
}Queue;
int WPL(LBTree* lbt)
{
Queue Q[maxSize];
int front,rear;
front = rear = 0;
int Lno = 1;
LBTree* q = lbt;
Q[rear].p = q;
Q[rear].lno = Lno;
rear++;
while (front != rear)
{
q = Q[front].p;
Lno = Q[front].lno;
front++;
if (q->lchild != NULL)
{
Q[rear].p = q->lchild;
Q[rear].lno = Lno + 1;
rear++;
}
if (q->rchild != NULL)
{
Q[rear].p = q->rchild;
Q[rear].lno = Lno + 1;
rear++;
}
}
int wpl = 0;
for (int i = 0; i < rear; i++)
{
if (Q[i].p->weigth != -1)
wpl += (Q[i].p->weigth) * (Q[i].p->lno - 1);
}
return wpl;
}
算法的中序序列加上必要的括号即为等价的中缀表达式。可以基于二叉树的中序遍历策略得到所需的表达式。表达式树中分支节点所对应的子表达式的计算次序,由该分支节点所处的位置决定。在适当位置增加必要的括号。显然表达式最外层和根节点不需要添加括号
void BtreeToE(BTree *root)
{
BtreeToExp(root,1);
}
void BtreeToExp(BiTree *root,int deep)
{
if (root == NULL) return ;
else if (root->next == NULL&&root->right==NULL) {
printf("%s",root->data);
} else {
if (deep > 1) printf("(");
BtreeToExp(root->left,deep+1);
printf("%s",root->data);
BtreeToExp(root->right,deep+1);
if (deep>1) printf("%s",")");
}
}