二叉树基本操作与实现

其中先中后遍历分别使用了递归和非递归两种算法实现,层序遍历借助了队列,非递归遍历借助了栈来实现。



BinaryTree.h

#pragma once 
#include<stdio.h>
#include<Windows.h>
#include<assert.h>

typedef int BTDataType;
size_t count = 0;
typedef struct BinTreeNode
{
	struct BinTreeNode* _left;
	struct BinTreeNode* _right;
	BTDataType data;
}BTNode;
#include"Queue.h"
#include"TreeStack.h"


//创建节点
BTNode* BuyBTNode(BTDataType x)
{
	BTNode* Node = (BTNode*)malloc(sizeof(BTNode));
	assert(Node);
	Node->data = x;
	Node->_left = NULL;
	Node->_right = NULL;
	return Node;

}


//创建二叉树
BTNode* CreateBTree(BTDataType* a, size_t* pIndex, BTDataType invalid)
{
	
	if (a[*pIndex] == invalid)
	{
		(*pIndex)++;
		return NULL;
	}
	
	BTNode* Node = BuyBTNode(a[(*pIndex)++]);
	 Node->_left = CreateBTree(a, pIndex, invalid);
	 Node->_right = CreateBTree(a, pIndex, invalid);
	return Node;
}



//先序遍历
void BTreePrevOrder(BTNode* root)
{
	
	if (root != NULL)
	{
		printf("%d  ", root->data);
		BTreePrevOrder(root->_left);
		BTreePrevOrder(root->_right);

	}
}


//中序遍历
void BTreeInOrder(BTNode* root)
{
	if (root != NULL)
	{
		
		BTreeInOrder(root->_left);
		printf("%d  ", root->data);
		BTreeInOrder(root->_right);

	}

}

//后续遍历
void BTreePostOrder(BTNode* root)
{
	if (root != NULL)
	{
		BTreePostOrder(root->_left);
		BTreePostOrder(root->_right);
		printf("%d  ", root->data);

	}
}


//层序遍历
void BTreeLevelOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);  
	while (QueueEmpty(&q))
	{
		BTNode* b;
		b = QueueFront(&q);
		printf("%d ", b->data);
		if (b->_left != NULL)
		{
			QueuePush(&q, b->_left);
		}

		if (b->_right != NULL)
		{
			QueuePush(&q, b->_right);
		}
		QueuePop(&q);
	}
}



size_t BTreeSize(BTNode* root)    //求结点个数
{
	if (root == NULL)
	{
		return 0;	//这里不能用-1,会溢出size_t的范围
	}
	return 1 + BTreeSize(root->_left) + BTreeSize(root->_right);
}


size_t BTreeLeafSize(BTNode* root)    //求叶子节点个数
{
	
		if (root == NULL)
			return 0;
		if (root->_left == NULL&&root->_right== NULL)
			return 1;
		else
			return BTreeLeafSize(root->_left) + BTreeLeafSize(root->_right);
	
}

int BTreeKLevelSize(BTNode* root, size_t k)    //求第K层节点个数
{
	if (k == 1)
	{
		return 1;
	}
	return  BTreeKLevelSize(root->_left, k - 1) + BTreeKLevelSize(root->_right, k - 1);
}


size_t BTreeDepth(BTNode* root)    //求二叉树深度
{
	if (root == NULL)
	{
		return 0;
	}
	return 1+(BTreeDepth(root->_left) > BTreeDepth(root->_right) ? BTreeDepth(root->_left) : BTreeDepth(root->_right));
}



int IsCompleteBTree(BTNode* root)//判断一棵二叉树是否是完全二叉树
{
	if (root == NULL)
	{
		return 0;
	}
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (QueueFront(&q)!=NULL)
	{
		BTNode* b = QueueFront(&q);	
		QueuePush(&q, b->_left);		
		QueuePush(&q, b->_right);
		QueuePop(&q);
	}

	while (QueueEmpty(&q) != 0)
	{
		QueuePop(&q);
		if (QueueFront(&q) != NULL)
		{
			return 0;
		}
		
	}

	return 1;
}


void BTreePrevOrderNonR(BTNode* root)		//非递归前序遍历二叉树
{
	if (root == NULL)
	{
		return;
	}

	Stack s;
	StackInit(&s, 20);
	BTNode* cur = root;
	while (cur != NULL || StackEmpty(&s) != 0)
	{
		while (cur != NULL)
		{
			StackPush(&s, cur);
			printf("%d ", cur->data);
			cur = cur->_left;
		}
		//此时左树已经走完
		BTNode* ret = StackTop(&s);
		cur = ret->_right;
		StackPop(&s);
	}
}



void BTreeInOrderNonR(BTNode* root)//中序非递归遍历二叉树
{
	if (root == NULL)
	{
		return;
	}

	Stack s;
	StackInit(&s, 20);
	BTNode* cur = root;
	while (cur != NULL || StackEmpty(&s) != 0)
	{
		while (cur != NULL)
		{
			StackPush(&s, cur);
			cur = cur->_left;
		}
		//此时左树已经走完
		BTNode* ret = StackTop(&s);
		printf("%d ", ret->data);

		cur = ret->_right;
		StackPop(&s);
	}

}

void BTreePostOrderNonR(BTNode* root)//后序非递归遍历二叉树
{
	if (root == NULL)
	{
		return;
	}

	Stack s;
	StackInit(&s,20);
	BTNode *cur = root;
	BTNode *last = NULL;//新定义一个last记录右孩子是否遍历过,遍历过则将top->_right赋给last
	while (cur || StackEmpty(&s))
	{
		while (cur)
		{
			StackPush(&s, cur);
			cur = cur->_left;
		}
		BTNode *top = StackTop(&s);
		//如果此时发现top无右孩子或者右孩子已经被遍历过了,则直接输出top的data
		if (top->_right == NULL || last == top->_right)
		{
			printf("%d ", top->data);
			StackPop(&s);
		}
		else
		{
			//进行到这里说明top有右孩子且尚未遍历过
			cur = top->_right;
			last = top->_right;

		}
	}

}




void TestBinaryTree()
{
	
	int a[] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6, '#', '#', '#' };
	size_t index = 0;
	BTNode* tree = CreateBTree(a, &index, '#');
	BTreeLevelOrder(tree);
	printf("\n");
	printf("是否为完全二叉树:%d\n",IsCompleteBTree(tree));
	BTreePrevOrderNonR(tree);
	printf("\n");
	BTreeInOrderNonR(tree);
	printf("\n");
	BTreePostOrderNonR(tree);
}

—————————————————————————————————————————————

Queue.h

#include<stdio.h>
#include<windows.h>
#include<assert.h>


typedef struct QueueNode
{
	BTNode* _data;    //链式队列
	struct QueueNode* _next;
}QueueNode;

typedef struct Queue
{
	QueueNode* _head;//队头指针
	QueueNode* _tail;//队尾指针
}Queue;

void QueueInit(Queue* q)//队列初始化
{
	q->_head = (QueueNode*)malloc(sizeof(QueueNode));
	assert(q->_head);
	q->_tail = q->_head;
	q->_tail->_next = NULL;
}



void QueuePush(Queue* q, BTNode* node)//入队
{
	assert(q);
	QueueNode *newnode = (QueueNode*)malloc(sizeof(QueueNode));
	assert(newnode);
	newnode->_data = node;
	newnode->_next = NULL;
	q->_tail->_next = newnode;
	q->_tail = newnode;
}



void QueuePop(Queue* q)//出队
{
	assert(q);
	if (q->_head == q->_tail)
	{
		return ;
	}
	QueueNode* p = q->_head->_next;
	q->_head = p;
}



BTNode* QueueFront(Queue* q)//取队头数据指针
{
	assert(q);
	if (q->_head == q->_tail)
	{
		return NULL;
	}
	return (q->_head->_next)->_data;
}




size_t QueueSize(Queue* q)//计算队列长度
{
	assert(q);
	if (q->_head == q->_tail)
	{
		return 0;
	}
	QueueNode *flag = q->_head->_next;
	size_t i = 0;
	while (flag != q->_tail)
	{
		flag = flag->_next;
		i++;
	}
	return i + 1;
}


int QueueEmpty(Queue* q)//判断队列是否为空
{
	assert(q);
	if (q->_head == q->_tail)
	{
		return 0;
	}
	return 1;
}


—————————————————————————————————————————————

TreeStack.h

#pragma once  

#include<stdio.h>  
#include<windows.h>  
#include<assert.h>  
#include<malloc.h>  
#define  STACKINCREMENT    10  
#define MAX_SIZE 100  
typedef BTNode* DataType;

typedef struct Stack
{
	DataType*  _st;
	size_t _size;
	size_t _capacity;       //容量  
}Stack;

void StackInit(Stack *s, size_t capacity);
void StackDestory(Stack *s);
void StackPush(Stack *s, DataType x);
void StackPop(Stack*s);
DataType StackTop(Stack *s);
size_t StackSize(Stack *s);
size_t StackEmpty(Stack *s);
void StackPush(Stack *s, DataType x);



void StackInit(Stack *s, size_t capacity)       //初始化  
{
	assert(s && capacity>0);
	s->_st = (DataType *)malloc(sizeof(DataType)*capacity);
	assert(s->_st);
	s->_size = 0;
	s->_capacity = capacity;
}




void StackPush(Stack *s, DataType x)        //入栈  
{
	assert(s);
	if (s->_size == s->_capacity)
	{
		s->_capacity *= 2;
		s->_st = (DataType*)realloc(s->_st, sizeof(DataType)*s->_capacity);
	}

	s->_st[s->_size++] = x;
}


void StackPop(Stack*s)      //出栈  
{
	assert(s && s->_size > 0);
	--s->_size;
}

DataType StackTop(Stack *s)     //取栈顶  
{
	assert(s && s->_size > 0);
	return s->_st[s->_size - 1];
}


size_t StackSize(Stack *s)      //取栈元素个数  
{
	assert(s);
	return s->_size;
}


size_t StackEmpty(Stack *s)     //判空  
{
	return s->_size;
}


————————————————————————————————————————————

main.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"BinaryTree.h"
int main()
{
	TestBinaryTree();
	system("pause");
	return 0;
}


猜你喜欢

转载自blog.csdn.net/yc1515707718/article/details/80203167
今日推荐