遍历
先序遍历
//递归void PreOrder(BiTree T){if(T!=NULL){visit(T);PreOrder(T->lchild);PreOrder(T->rchild);}}//非递归,用栈void PreOrder(BiTNode *bt){if(bt!=NULL){BiTNode *Stack[maxsize];//手动模拟栈int top=-1;BiTNode *p;Stack[++top]=bt;//根结点入栈while(top!=-1){p=Stack[top--];visit(p);if(p->rchild!=NULL)//应该让右孩子先入栈Stack[++top]=p->rchild;if(p->lchild!=NULL)Stack[++top]=p->lchild;}//while}}
中序遍历
//递归void InOrder(BiTree T){if(T!=NULL){InOrder(T->lchild);visit(T);InOrder(T->rchild);}}//非递归void InOrder(BiTNode *bt){if(bt!=NULL){BiTNode *Stack[maxsize];int top=-1;BiTNode *p=bt;while(top!=-1||p!=NULL){if(p){Stack[++top]=p;p=p->lchild;}else{p=Stack[top--];visit(p);p=p->rchild;}}}
后序遍历
//递归void PostOrder(BiTree T){if(T!=NULL){PostOrder(T->lchild);PostOrder(T->rchild);visit(T);}}typedef struct BiTNode{ElemType data;struct BiTNode *lchild,*rchild;int tag;//访问位,0表示未访问,1表示已访问}BiTNode,*BiTree;//非递归void PostOrder(BiTNode *bt){if(T!=NULL){BiTNode *Stack[maxsize];int top=-1;BiTNode *p=T;while(top!=-1||p!=NULL){if(p){Stack[++top]=p;p=p->lchild;}else{p=Stack[top--];if(p->lchild&&(p->lchild->tag==0)){Stack[++top]=p;p=p->rchild;}else{visit(p);p->tag=1;p=NULL;}}}}
层序遍历
typedef struct Queue{BiTNode *data[maxsize];int front,rear;}Queue;//借助队列void LevelOrder(BiTNode *bt){Queue Q;InitStack(Q);EnQueue(Q,bt);BiTNode *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);}}//手动模拟队列void LevelOrder(BiTNode *bt){BiTNode *Q[maxsize];int front=rear=0;BiTNode *p;if(bt!=NULL){rear=(rear+1)%maxsize;Q[rear]=bt;while(front!=rear){front=(front+1)%maxsize;p=Q[front];visit(p);if(p->lchild!=NULL){rear=(rear+1)%maxsize;Q[rear]=p->lchild;}if(p->rchild!=NULL){rear=(rear+1)%maxsize;Q[rear]p->rchild;}}//while}}
1. 试编写二叉树的自下而上、从右到左的层次遍历算法。
【算法思想】
一般的二叉树层次遍历是自上而下,自左到右。在这里刚好相反。我们利用原有的层次遍历算法,各结点出队的同时将各结点指针入栈,在所有结点入栈后再从 栈顶开始依次访问。
void InvertLevelOrder(BiTree bt){Stack S;Queue Q;if(bt!=NULL){InitStack(S);InitQueue(Q);EnQueue(Q,bt);BiTNode *P;while(!IsEmpty(Q)){DeQueue(Q,p);Push(S,p);if(p->lchild)EnQueue(Q,P->lchild);if(p->rchild)EnQueue(Q,p->rchild);}while(!IsEmpty(S)){Pop(S,p);visit(p);//自下而上,从右到左的遍历}}//if}
2.设二叉树采用二叉链表的存储结构,试着编写非递归算法二叉树的高度。
【算法思想】
采用层次遍历的算法,设置变量 level 记录当前结点所在的层次,设置变量 last指向当前层的最右结点。每层次遍历出队时与 last 指针比较,若两者相等,则层数+1,并且计算下一层的最右结点,直到遍历完成。level 的值即为二叉树的高度
int BtDepth(BiTree T){if(T==NULL)return 0;else{//采用手动模拟队列方式int front=rear=-1;int last=level=0;BiTree *Q[maxsize];Q[++rear]=T;BiTree p;while(front<rear){p=Q[++front];if(p->lchild)Q[++rear]=p->lchild;if(p->rchild)Q[++rear]=p->rchild;if(front==last){level++;last=rear;}}//whilereturn level;}}//递归实现int BtDepth(BiTree T){if(T==NULL)return 0;ldep=BtDepth(T->lchild);rdep=BtDepth(T->rchild);if(ldep>rdep)return ldep+1;elsereturn rdep+1;}
3.计算二叉树的最大宽度(二叉树的最大宽度是指二叉树所有层中结点个数的最大值)
//采用level数组记录每个结点所在层次int BtWidth(BiTree T){if(T==NULL)return 0;BiTree p;int k;//记录结点所在层次BiTree *Q[maxsize];int front=rear=-1;int level[maxsize];Q[++rear]=T;level[rear]=1;//根结点层次为1while(front<rear){p=Q[++front];//出队结点k=level[front];//出队结点的层次if(p->lchild){Q[++rear]=p->lchild;level[rear]=k+1;}if(p->rchild){Q[++rear]=p->lchild;level[rear]=k+1;}}//while//遍历结束后,rear+1为结点数int max=0;int i=0;k=1;while(i<=rear){n=0;//记录每一层的结点数while(i<=rear&&level[i]==k){n++;i++;}k=level[i];//更新层数if(n>max)max=n;}//whilereturn max;}//改进,不使用level数组,一边遍历一边统计int BtWidth(BiTree T){if(!T)return 0;BiTree *Q[maxsize];front=rear=-1;int last=1;//记录最右边结点在队列中位置int wid=0;//记录局部宽度int maxwidth=0;//记录最大宽度Q[++rear]=T;while(front<rear){p=Q[++front];wid++;if(p->lchild)Q[++rear]=p->lchild;if(p->rchild)Q[++rear]=p->rchild;if(front>last){last=rear;//last指向下一层最右边元素if(wid>maxwidth)maxwidth=wid;wid=0;}//if}//whilereturn maxwidth;}
4.假设二叉树采用二叉链存储结构存储,试设计一个算法,计算一棵给定二叉树的所有节点数。
//递归int Nodes(BTNode *bt){int left,right;if(!bt)return 0else{left=Nodes(bt->lchild);right=Nodes(bt->rchild);return (left+right+1);}}
5.假设二叉树采用二叉链存储结构存储,设计一个算法计算一棵给定二叉树的所有叶子节点个数。
//递归int leafNodes(BiTNode *bt){int m,n;if(!bt)return 0;else if(bt->lchild==NULL&&bt->rchild==NULL)return 1;else{m=leafNodes(bt->lchild);n=leafNodes(bt->rchild);return m+n;}}
6.假设二叉树采用二叉链存储结构存储,设计一个算法计算一棵给定二叉树的所有双分支节点。
//递归int doubleNodes(BiTNode *bt){int left,right,n;if(!bt)return 0;else if(bt->lchild==NULL||bt->rchild==NULL)n=0;elsen=1;left=doubleNodes(bt->lchild);right=doubleNodes(bt->rchild);return (left+right+n);}
7.假设二叉树采用二叉链存储结构存储,所有节点的值为正整数,设计一个算法求所有节点值之和。
//递归int Findsum(BiTNode *bt){if(!bt)return 0;elsereturn (bt->data+Findsum(bt->lchild)+Findsum(bt->rchild));}
8.假设二叉树采用二叉链存储结构存储,设计一个算法求其中节点值为 x的节点个数。
//递归int count_x(BiTNode *bt,ElemType x){if(!bt)return 0;else if(bt->data==x)return (1+count_x(bt->lchild,x)+count_x(bt->rchild,x));elsereturn (count_x(bt->lchild,x)+count_x(bt->rchild,x));)
9 假设二叉树采用二叉链表结构存储,设计一个算法求先序遍历序列中第k(1<=k<=二叉树中节点个数)个节点的值。
int n=1;//标记结点序号ElemType PreNode(BiTNode *bt,int k){ElemType ch;if(bt==NULL)return '';if(n==k)return bt->data;n++;ch=PreNode(bt->lchild,k);//遍历左子树if(ch!='')return ch;ch=PreNode(bt->rchild,k);return ch;}
10.假设二叉树采用二叉链存储结构存储,设计一个算法,求中序遍历序列中第k(1≤k≤二叉树中节点个数)个节点的值。
int n=1;ElemType InOrder(BiTNode *bt,int k){ElemType ch;if(bt==NULL)return '';ch=InOrder(bt->lchild,k);if(ch!='')return ch;else{if(n==k)return bt->data;n++;ch=InOrder(bt->rchild,k);return ch;}}
11.假设二叉树采用二叉链存储结构存储,设计一个算法,求后序遍历序列中第k(1≤k≤二叉树中节点个数)个节点的值。
int n=1;ElemType PostOrder(BiTNode *bt,int k){ElemType ch;if(bt==NULL)return '';ch=PostOrder(bt->rchild,k);if(ch!='')return ch;else{ch=PostOrder(bt->lchild,k);if(ch!='')return ch;if(n==k)return bt->data;n++;}}

int wpl_PreOrder(BiTree root,int deep){static int wpl=0;if(root->lchild==NULL&&root->rchild==NULL)wpl=wpl+deep*root->weight;//叶子结点if(root->lchild!=NULL)wpl_PreOrder(root->left,deep+1);if(root->right!=NULL)wpl_PreOrder(root->rchild,deep+1);return wpl;}

typedef struct node{char data[maxsize];struct node *left,*right;}BiTree;void BiTreeToExp(BiTree *bt,int deep){if(bt==NULL)return ;else if(bt->left==NULL&&bt->right==NULL)//叶子结点printf("%s",bt->data);else{if(deep>1)printf("(");BiTreeToExp(bt->left,deep+1);printf("%s",bt->data);BiTreeToExp(bt->right,deep+1);if(deep>1)printf(")");}}
17.判断一个树是否是完全二叉树
typedef struct BiTNode{ElemType data[maxsize];struct BiTNode *lchild,*rchild;}typedef struct Queue{BiTNode *data[maxsize];int front,rear;}bool isCompleteBiTNode(BiTNode *bt){Queue Q;InitQueue(Q);if(bt==NULL)return true;EnQueue(Q,bt);int tag=0;//判断前面是否有空结点的标志位while(!isEmpty(Q)){BiTNode p;DeQueue(Q,p);if(p->lchild&&!tag)EnQueue(Q,p->lchild);else{if(p->lchild)return false;elsetag=1;//首次出现非空结点}if(p->rchild&&!tag)EnQueue(Q,p->rchild);else{if(p->rchild)return false;elsetag=1;}}return true;}
