随机生成二叉树是我自己写的,随机性不是很大,应该也有漏洞,看着办吧。
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define maxSize 5
//二叉树的四种遍历方法
//结构体构造
typedef struct BTNode{
int val;
struct BTNode* lchild;
struct BTNode* rchild;
}BTNode;
//对根的操作
void visit(BTNode *p){
printf("%-3d",p->val);
}
//1.先序遍历
void preorder(BTNode *bt){
if(bt!=NULL){
visit(bt);
preorder(bt->lchild);
preorder(bt->rchild);
}
}
//1.非递归先序遍历
void preorderNonrecursion(BTNode *bt){
if(bt!=NULL){
//定义栈
BTNode *stack[maxSize];
int top = -1;
BTNode *p;
stack[++top] = bt;
while(top!=-1){
//出栈
p = stack[top--];
visit(p);
//这里是先右结点进入栈因为栈FILO
if(p->rchild != NULL){
stack[++top] = p->rchild;
}
if(p->lchild != NULL){
stack[++top] = p->lchild;
}
}
}
}
//2.中序遍历
void inorder(BTNode *bt){
if(bt!=NULL){
inorder(bt->lchild);
visit(bt);
inorder(bt->rchild);
}
}
//2.非递归中序遍历
void inorderNonrecursion(BTNode *bt){
if(bt!=NULL){
BTNode *stack[maxSize];
int top = -1;
BTNode *p;
p=bt;
while(top!=-1 || p!=NULL){
while(p!=NULL){
stack[++top]=p;
p = p->lchild;
}
if(top!=-1){
p=stack[top--];
visit(p);
p=p->rchild;
}
}
}
}
//3.后序遍历
void postorder(BTNode *bt){
if(bt!=NULL){
postorder(bt->lchild);
postorder(bt->rchild);
visit(bt);
}
}
//3.非递归后序遍历
void postorderNonrecursion(BTNode *bt){
if(bt!=NULL){
//考研中最简单的方法
//双栈
BTNode *stack1[maxSize];
BTNode *stack2[maxSize];
int top1=-1;
int top2=-1;
BTNode *p;
stack1[++top1] = bt;
while(top1!=-1){
//出栈
p = stack1[top1--];
//这里注意是放到另一个栈中,而不是visit,个人想把上下两句连一起
stack2[++top2] = p;
if(p->lchild !=NULL){
stack1[++top1] = p->lchild;
}
if(p->rchild != NULL){
stack1[++top1] = p->rchild;
}
}
//输出二栈中的后序
while(top2!=-1){
p = stack2[top2--];
visit(p);
}
}
}
//4.层次遍历
void level(BTNode *bt){
//建立一个循环队列
BTNode *queue[maxSize];
int front,rear;
front = rear = 0;
BTNode *p;
if(bt!=NULL){
//根节点进队
rear = (rear+1)%maxSize;
queue[rear] = bt;
while(front!=rear){
//出队
front = (front+1)%maxSize;
p = queue[front];
visit(p);
if(p->lchild!=NULL){
rear = (rear+1)%maxSize;
queue[rear] = p->lchild;
}
if(p->rchild!=NULL){
rear = (rear+1)%maxSize;
queue[rear] = p->rchild;
}
}
}
}
//随机获得二叉树 (并不完善,随机性很弱)
BTNode* getNode(int a[maxSize]){
int i;
//初始化随机数
srand((unsigned)time(NULL));
BTNode *p;
BTNode *q;
BTNode *bt = (BTNode*)malloc(sizeof(BTNode));
bt->lchild=NULL;
bt->rchild=NULL;
bt->val=a[0];
printf("根节点:%d\n",bt->val);
q = bt;
for(i=1;i<maxSize;i++){
p = (BTNode*)malloc(sizeof(BTNode));
//这里不设置为NULL会出大事!
//一个好习惯:建立一个结点就将里边的指针全部置空
p->lchild = NULL;
p->rchild = NULL;
//数值随机0-10
p->val = a[i];
//随机左右子树
int x = rand()%2;
if(x==1 && q->lchild==NULL){
//随机数为1,左孩子
q->lchild = p;
printf("结点%2d的左孩子:%d\n",q->val,p->val);
//随机决定是否将q指针指向左孩子
int x = rand()%2;
if( x|| q->rchild!=NULL){
q = q->lchild;
}
}else if(x==0 && q->rchild==NULL){
q->rchild = p;
printf("结点%2d的右孩子:%d\n",q->val,p->val);
//随机决定是否将q指针指向左孩子
int x = rand()%2;
if(x || q->lchild!=NULL){
q = q->rchild;
}
}else if(x==1){
//随机数为1,但是左孩子已经存在的解决办法
int x = rand()%2;
if(x){
q->lchild->lchild = p;
printf("结点%2d的左孩子:%d\n",q->lchild->val,p->val);
q = q->lchild;
}else{
q->lchild->rchild = p;
printf("结点%2d的右孩子:%d\n",q->lchild->val,p->val);
q = q->lchild;
}
} else if(x==0){
//随机数为0,但是右孩子已经存在的解决办法
int x = rand()%2;
if(x){
q->rchild->lchild = p;
printf("结点%2d的左孩子:%d\n",q->rchild->val,p->val);
q = q->rchild;
}else{
q->rchild->rchild = p;
printf("结点%2d的右孩子:%d\n",q->rchild->val,p->val);
q = q->rchild;
}
}
}
return bt;
}
int main(){
int a[maxSize] = {1,2,3,4,5};
//随机生成二叉树
BTNode *bt = getNode(a);
//先序遍历
printf("先序遍历\n 递归:");
preorder(bt);
printf("\n非递归:");
preorderNonrecursion(bt);
printf("\n");
//中序遍历
printf("中序遍历\n 递归:");
inorder(bt);
printf("\n非递归:");
inorderNonrecursion(bt);
printf("\n");
//后序遍历
printf("后序遍历\n 递归:");
postorder(bt);
printf("\n非递归:");
postorderNonrecursion(bt);
printf("\n");
printf("层次遍历\n");
level(bt);
return 0;
}