1. 程式人生 > >資料結構之二叉排序樹及二叉樹的遍歷

資料結構之二叉排序樹及二叉樹的遍歷

本文解決的問題是:

構建一個二叉排序樹,隨機產生20個樹,並實現該二叉樹的三種深度遍歷(遞迴和非遞迴)和一種廣度遍歷。

實現程式碼如下:

#include<stdio.h>
#include<stdlib.h>

#define MaxSize 100
typedef struct btnode
{
    int data;
	int BF;
    struct btnode *lchild,*rchild;
}Btnode,*bitree;
//定義佇列
typedef struct{
	bitree data[MaxSize];
	int front,rear;
}SqQueue;
//定義棧
typedef struct{
	bitree data[MaxSize];
	int top;
}SqStack;

//建立二叉樹
bitree creatTree(bitree root)
{
	int i;
	int temp;
	bitree r,s,pre;
	for(i=0;i<20;i++)
	{
		temp=rand()%90+11;
		printf("本次插入的是:%d\n",temp);
		r=(bitree)malloc(sizeof(btnode));
		r->data=temp;
		r->lchild=NULL;
		r->rchild=NULL;
		pre = NULL;
		s=root;
		if(root->data == NULL)
		{
			root=r;
			continue;
		}
		while(s)
		{
			if(temp==s->data)
			{
				//當前結點與新傳入的值相等
				i--;
				pre=NULL;
				printf("本次%d為重複結點,請重新生成結點!!\n",temp);
				break;
			}else if(temp<s->data)
			{
				//當前結點大於新傳入值,遍歷左結點
				pre = s;
				s = s->lchild;
			}else{
				//當前結點小於新傳入值,遍歷右結點
				pre = s;
				s = s->rchild;
			}
		}
		if(pre != NULL)
		{
			//找到結點(父節點)插入位置
			if(temp<pre->data)
			{
				//插入左子樹
				pre->lchild = r;
			}else{
				//插入右子樹
				pre->rchild = r;
			}	
		}	
	}
	return root;
}
//前序遍歷遞迴
void preErgodic_recu(bitree root)
{
	if(root)
	{
		printf("%d ",root->data);
		preErgodic_recu(root->lchild);
		preErgodic_recu(root->rchild);
	}
}
//前序遍歷非遞迴
void preErgodic_recu_no(bitree root)
{
	SqStack q;
	q.top=0;
	q.data[q.top]=root;
	bitree p=root;
	while(p||q.top != 0)
	{
		if(p)
		{
			printf("%d ",p->data);
			q.data[q.top++] = p;
			p=p->lchild;
		}else{
			p=q.data[--q.top];
			p=p->rchild;
		}
	}
}
//中序遍歷遞迴
void midErgodic_recu(bitree root)
{
	if(root)
	{
		midErgodic_recu(root->lchild);
		printf("%d ",root->data);
		midErgodic_recu(root->rchild);
	}
}
//中序遍歷非遞迴
void midErgodic_recu_no(bitree root)
{
	SqStack q;
	q.top=0;
	q.data[q.top]=root;
	bitree p=root;
	while(p||q.top != 0)
	{
		if(p)
		{
			q.data[q.top++] = p;
			p=p->lchild;
		}else{
			p=q.data[--q.top];
			printf("%d ",p->data);
			p=p->rchild;
		}
	}
}
//後序遍歷遞迴
void postErgodic_recu(bitree root)
{
	if(root)
	{
		postErgodic_recu(root->lchild);
		postErgodic_recu(root->rchild);
		printf("%d ",root->data);
	}
}
//後序遍歷非遞迴
void postErgodic_recu_no(bitree root)
{
	SqStack q;
	q.top=0;
	q.data[q.top]=root;
	bitree p=root;
	bitree r=NULL;
	while(p||q.top != 0)
	{
		if(p)
		{
			q.data[q.top++] = p;
			p=p->lchild;
		}else{
			p=q.data[q.top-1];
			if(p->rchild&&p->rchild != r)
			{
				p=p->rchild;
				q.data[q.top++] = p;
				p=p->lchild;
			}else
			{
				p=q.data[--q.top];
				printf("%d ",p->data);
				r=p;
				p=NULL;
			}
		}
	}
}
//入隊
void push_queue(SqQueue *q,bitree root)
{
	q->data[q->rear]=root;
	q->rear++;
}
//出隊
bitree pop_queue(SqQueue *q)
{
	return q->data[q->front++];
}
//廣度遍歷
void breafthTraversal(bitree root)
{
	SqQueue q;
	q.front = q.rear = 0;
	if(!root)
	{
		printf("二叉樹為空!!\n");
		return;
	}
	//根節點入隊
	push_queue(&q,root);
	while(q.front != q.rear)
	{
		bitree temp=pop_queue(&q);
		printf("%d ",temp->data);
		if(temp->lchild != NULL)
		{
			push_queue(&q,temp->lchild);
		}
		if(temp->rchild != NULL)
		{
			push_queue(&q,temp->rchild);
		}
	}

}

int main()
{
	bitree root;
	root=(bitree)malloc(sizeof(btnode));
	root->data=NULL;
	root=creatTree(root);
	//列印樹
	/*****************************三種深度遍歷******************************************/
	/******************1.1 前序深度遍歷*****************/
	printf("前序遍歷--遞迴:\n");
	preErgodic_recu(root);
	printf("\n");
	printf("前序遍歷--非遞迴:\n");
	preErgodic_recu_no(root);
	printf("\n");
	printf("\n");
	printf("\n");
	/******************1.2 中序深度遍歷*****************/
	printf("中序遍歷--遞迴:\n");
	midErgodic_recu(root);
	printf("\n");
	printf("中序遍歷--非遞迴:\n");
	midErgodic_recu_no(root);
	printf("\n");
	printf("\n");
	printf("\n");
	/******************1.3 後序深度遍歷*****************/
	printf("後序遍歷--遞迴:\n");
	postErgodic_recu(root);
	printf("\n");
	printf("後序遍歷--非遞迴:\n");
	postErgodic_recu_no(root);
	printf("\n");
	printf("\n");
	printf("\n");
	/*****************************一種廣度遍歷******************************************/
	printf("廣度遍歷的結果為:\n");
	breafthTraversal(root);
	printf("\n");
	return 0;
}
如有疑問,請及時提出,謝謝!

---------------------------------------------------------------------------------------------------------------------