二叉搜索树

二叉树T:一个又穷的结点集合

(这个集合可以为空,若不为空,则它是由根节点和称其左子树TL和右子树TR的两个不相交的二叉树组成)


使用结构体定义树的结点:

struct node
{
	DataType data;
	struct node *left, *right;
};
typedef struct node *BiTree;


开辟一个新结点 (返回这个结点的地址) (总是被Insert函数调用):
BiTree newNode(DataType d)
{
	BiTree n = (BiTree)malloc(sizeof(struct node));
	n->data = d;
	n->left = n->right = NULL;
	return n;
}

定义Insert函数,在树中加入一个结点
(规则:二叉搜索树,左子结点的值比根节点值小,右子结点的值比根节点值大)
BiTree Insert(BiTree node, DataType d)
{
	if(!node)
		node = newNode(d);		// 结点的value 
	else
	{
		if(d >= node->data)
			node->right = Insert(node->right, d);
		else
			node->left = Insert(node->left, d);
	}
	return node;
}

定义MBTree函数,递归建立二叉搜索树(输入0表示null,不为null的根结点还需要2个子树),返回根结点的地址:
BiTree MBTree()
{
	// 输入二叉树data		输入0表示NULL 
	BiTree root = NULL;
	DataType d;
	scanf("%d", &d);
	if(d != 0)
	{
		root = newNode(d);
		root->left = MBTree();
		root->right = MBTree();
	}
	return root;
}
/*----------------------------------到此为止,完成二叉搜索树定义-----------------------------------------*/


二叉树的先序遍历(使用递归的思想):
void PreOrder(BiTree root)
{
	if(root != NULL)
	{
		printf("%d ", root->data);
		PreOrder(root->left);
		PreOrder(root->right);
	}
}



     因为C语言库函数没有栈,因此需要自定义栈(在后序非递归遍历的时候使用) (尽量做到与C++库函数功能一样):
struct stack{
	BiTNode *elem[maxSize];
	int top;
};
// 栈初始化 
void initStack(Stack *S)
{
	S->top = -1;
}
// 判断栈空否,空栈时返回1,否则返回0 
int IsStackEmpty(Stack *S)
{
	if(S->top < 0)
		return 1;
	else
		return 0;
}
// 读栈顶元素,用x返回栈顶元素的值(不退栈),若成功返回1 
BiTree getTop(Stack *S)
{
	if(IsStackEmpty(S))
		return NULL;
	else
		return S->elem[S->top];
}
// 进栈,成功返回1,否则返回0 
int Push(Stack *S, BiTNode *x)
{
	if(S->top >= maxSize)
		return 0;
	else
		S->elem[++S->top] = x;
	return 1;
}
// 出栈,栈非空时,出栈成功返回1,否则返回0 
int Pop(Stack *S, BiTNode **x)
{
	if(S->top < 0)
		return 0;
	else
		*x = S->elem[S->top--];
	return 1;
}

二叉树的中序非递归遍历(需要使用栈):
void InOrder(BiTree root)
{
	Stack *S = (Stack *)malloc(sizeof(struct stack));	// 建立栈 
	initStack(S);			// 栈元素定义为 
	BiTNode *p = root;			// p是遍历指针,从根节点开始 
	do
	{
		while(p != NULL)		// 非空二叉树,沿左链进栈 
		{
			Push(S, p);
			p = p->left;
		}
		if(!IsStackEmpty(S))			// 栈不空时退栈 
		{
			Pop(S, &p);
			printf("%d ", p->data);
			p = p->right;		// 遍历指针进到右子女节点 
		}
	}
	while(p != NULL || !IsStackEmpty(S));
}


    因为C语言库函数没有队列,因此需要自定义队列(在层次遍历的时候使用) (尽量做到与C++库函数功能一样):
struct queue{
	BiTNode *elem[maxSize];
	int front, rear;	// 循环队列的队头、队尾指针 
};

// 队列初始化:创建一个空的队列Q并初始化 
void initQueue(Queue *Q)
{
	Q->front = 0;
	Q->rear = 0;
}

// 判断队列空否:当队列Q为空时函数返回1,否则返回0 
int IsQueueEmpty(Queue *Q)
{
	if(Q->front == Q->rear)
		return 1;
	else
		return 0;
}

// 进队列:当队列Q未满时,将元素成为队尾,成功返回1,否则返回0 
// 进队列:elem[rear]存入数据,rear再++ 
int enQueue(Queue *Q, BiTNode *x)
{
	if((Q->rear+1) % maxSize == Q->front)
		return 0;
	else
	{
		Q->elem[Q->rear] = x;
		Q->rear = (Q->rear+1) % maxSize;
		return 1;
	}
}

// 出队列:当队列Q非空时,将队头元素退出,成功返回1,否则返回0 
int deQueue(Queue *Q, BiTNode **x)
{
	if(IsQueueEmpty(Q))
		return 0;
	else
	{
		*x = Q->elem[Q->front];
		Q->front = (Q->front+1) % maxSize;
		return 1;
	}
}

二叉树的层次遍历(需要使用队列):
void LevelOrder(BiTree root)
{
	BiTNode *p;
	Queue Q;		// 建立一个队列 
	initQueue(&Q);		// 初始化队列 
	
	enQueue(&Q, root);		// 入栈队列 
	while(!IsQueueEmpty(&Q))
	{
		deQueue(&Q, &p);
		printf("%d ", p->data);
		if(p->left != NULL)
			enQueue(&Q, p->left);
		if(p->right != NULL)
			enQueue(&Q, p->right);
	}
}

二叉树的后序非递归遍历(需要使用栈):
void LastOrder(BiTree root)
{
	BiTree temp = NULL;
	Stack *S = (Stack *)malloc(sizeof(struct stack));	// 建立栈 
	initStack(S);
	while(root != NULL || !IsStackEmpty(S))
	{
		while(root != NULL)		// root和全部左子树 都压栈 
		{
			Push(S, root);
			root = root->left;
		}
		if(!IsStackEmpty(S))
			if(getTop(S)->right != NULL)		// 栈顶元素有右子树 
				root = getTop(S)->right;
			else
			{
				do								// 栈顶元素没有右子树 
				{
					Pop(S, &temp);
					printf("%d ", temp->data);
					root = getTop(S);			// root 可能为 null 
				}
				while(!IsStackEmpty(S) && root->right == temp);
				//	栈不空 并且 出栈元素是栈顶元素的右子树 
			}
		if(root && root->left == temp)			// 出栈元素是栈顶元素的左子树 
			root = root->right;
	}
}



下面给出完整代码:
建立二叉搜索树、递归遍历、非递归中序和后序遍历、自定义栈、自定义队列
#include <stdio.h>
#include <stdlib.h>			//#include <malloc.h>
// 建立二叉树,搜索二叉树 

#define maxSize 100
typedef int DataType;
typedef struct node *BiTree;
typedef struct node BiTNode;
typedef struct stack Stack;
typedef struct queue Queue;

struct node
{
	DataType data;
	struct node *left, *right;
};

//-------------------------栈定义---------------------------- 
struct stack{
	BiTNode *elem[maxSize];
	int top;
};
// 栈初始化 
void initStack(Stack *S)
{
	S->top = -1;
}
// 判断栈空否,空栈时返回1,否则返回0 
int IsStackEmpty(Stack *S)
{
	if(S->top < 0)
		return 1;
	else
		return 0;
}
// 读栈顶元素,用x返回栈顶元素的值(不退栈),若成功返回1 
BiTree getTop(Stack *S)
{
	if(IsStackEmpty(S))
		return NULL;
	else
		return S->elem[S->top];
}
// 进栈,成功返回1,否则返回0 
int Push(Stack *S, BiTNode *x)
{
	if(S->top >= maxSize)
		return 0;
	else
		S->elem[++S->top] = x;
	return 1;
}
// 出栈,栈非空时,出栈成功返回1,否则返回0 
int Pop(Stack *S, BiTNode **x)
{
	if(S->top < 0)
		return 0;
	else
		*x = S->elem[S->top--];
	return 1;
}
//-------------------------栈定义end---------------------------- 


//-------------------------队列定义----------------------------- 
struct queue{
	BiTNode *elem[maxSize];
	int front, rear;	// 循环队列的队头、队尾指针 
};

// 队列初始化:创建一个空的队列Q并初始化 
void initQueue(Queue *Q)
{
	Q->front = 0;
	Q->rear = 0;
}

// 判断队列空否:当队列Q为空时函数返回1,否则返回0 
int IsQueueEmpty(Queue *Q)
{
	if(Q->front == Q->rear)
		return 1;
	else
		return 0;
}

// 进队列:当队列Q未满时,将元素成为队尾,成功返回1,否则返回0 
// 进队列:elem[rear]存入数据,rear再++ 
int enQueue(Queue *Q, BiTNode *x)
{
	if((Q->rear+1) % maxSize == Q->front)
		return 0;
	else
	{
		Q->elem[Q->rear] = x;
		Q->rear = (Q->rear+1) % maxSize;
		return 1;
	}
}

// 出队列:当队列Q非空时,将队头元素退出,成功返回1,否则返回0 
int deQueue(Queue *Q, BiTNode **x)
{
	if(IsQueueEmpty(Q))
		return 0;
	else
	{
		*x = Q->elem[Q->front];
		Q->front = (Q->front+1) % maxSize;
		return 1;
	}
}

//-------------------------队列定义end--------------------------



BiTree newNode(DataType d)		// 开辟新结点 
{
	BiTree n = (BiTree)malloc(sizeof(struct node));
	n->data = d;
	n->left = n->right = NULL;
	return n;
}

BiTree Insert(BiTree node, DataType d)
{
	if(!node)
		node = newNode(d);		// 结点的value 
	else
	{
		if(d >= node->data)
			node->right = Insert(node->right, d);
		else
			node->left = Insert(node->left, d);
	}
	return node;
}
BiTree MBTree()
{
	// 输入二叉树data		输入0表示NULL 
	BiTree root = NULL;
	DataType d;
	scanf("%d", &d);
	if(d != 0)
	{
		root = newNode(d);
		root->left = MBTree();
		root->right = MBTree();
	}
	return root;
}

// 先序递归遍历 
void PreOrder(BiTree root)
{
	if(root != NULL)
	{
		printf("%d ", root->data);
		PreOrder(root->left);
		PreOrder(root->right);
	}
}

// 中序非递归遍历 
void InOrder(BiTree root)
{
	Stack *S = (Stack *)malloc(sizeof(struct stack));	// 建立栈 
	initStack(S);			// 栈元素定义为 
	BiTNode *p = root;			// p是遍历指针,从根节点开始 
	do
	{
		while(p != NULL)		// 非空二叉树,沿左链进栈 
		{
			Push(S, p);
			p = p->left;
		}
		if(!IsStackEmpty(S))			// 栈不空时退栈 
		{
			Pop(S, &p);
			printf("%d ", p->data);
			p = p->right;		// 遍历指针进到右子女节点 
		}
	}
	while(p != NULL || !IsStackEmpty(S));
}

// 层次遍历 
void LevelOrder(BiTree root)
{
	BiTNode *p;
	Queue Q;		// 建立一个队列 
	initQueue(&Q);		// 初始化队列 
	
	enQueue(&Q, root);		// 入栈队列 
	while(!IsQueueEmpty(&Q))
	{
		deQueue(&Q, &p);
		printf("%d ", p->data);
		if(p->left != NULL)
			enQueue(&Q, p->left);
		if(p->right != NULL)
			enQueue(&Q, p->right);
	}
}

// 后序遍历 
void LastOrder(BiTree root)
{
	BiTree temp = NULL;
	Stack *S = (Stack *)malloc(sizeof(struct stack));	// 建立栈 
	initStack(S);
	while(root != NULL || !IsStackEmpty(S))
	{
		while(root != NULL)		// root和全部左子树 都压栈 
		{
			Push(S, root);
			root = root->left;
		}
		if(!IsStackEmpty(S))
			if(getTop(S)->right != NULL)		// 栈顶元素有右子树 
				root = getTop(S)->right;
			else
			{
				do				// 栈顶元素没有右子树 
				{
					Pop(S, &temp);
					printf("%d ", temp->data);
					root = getTop(S);			// root 可能为 null 
				}
				while(!IsStackEmpty(S) && root->right == temp);
				//	栈不空 并且 出栈元素是栈顶元素的右子树 
			}
		if(root && root->left == temp)			// 出栈元素是栈顶元素的左子树 
			root = root->right;
	}
}

int main()
{
	BiTree root;	
	root = MBTree();	// 建立二叉搜索树,输入0表示NULL 
	PreOrder(root);		// 先序递归遍历 
	printf("\n");
	
	InOrder(root);		// 中序非递归遍历:栈 
	printf("\n");
	
	LevelOrder(root);		// 层次遍历:堆 
	printf("\n");
	
	LastOrder(root);		// 后序非递归遍历:栈 
	printf("\n");
	
	return 0;
}




运行结果图:




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值