二叉树面试题和基本操作的完整代码

BinTree.h
#pragma once
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
#include "Stack.h"
#include "SQueue.h"


typedef char BTDataType;

typedef struct BinTreeNode
{
	struct BinTreeNode* _pLeft;
	struct BinTreeNode* _pRight;
	BTDataType _data;
}BTNode,*PBTNode;


//构建二叉树的结点
PBTNode BuyBinTreeNode(BTDataType data);

//创建二叉树
void _CreateBinTree(PBTNode* pRoot,const BTDataType* array,
					int size,int* index,BTDataType invalid);

void CreateBinTree(PBTNode* pRoot,const BTDataType* array,
				   int size,BTDataType invalid);

// 拷贝二叉树 
PBTNode CopyBinTree(PBTNode pRoot); 

// 销毁二叉树 
void DestroyBinTree(PBTNode *pRoot); 

// 前序遍历递归 
void PreOrder(PBTNode pRoot);

// 前序遍历非递归 
void PreOrderNor(PBTNode pRoot); 

// 中序遍历递归 
void InOrder(PBTNode pRoot);

//中序遍历非递归
void InOrderNor(PBTNode pRoot);

// 后序遍历递归 
void PostOrder(PBTNode pRoot);

//后序遍历非递归
void PostOrderNor(PBTNode pRoot);

// 层序遍历 
void LevelOrder(PBTNode pRoot); 

// 二叉树的镜像递归 
void MirrorBinTree(PBTNode pRoot); 

// 二叉树的镜像非递归 
void MirrorBinTreeNor(PBTNode pRoot); 

// 求二叉树中结点的个数 
int BinTreeSize(PBTNode pRoot); 

// 获取二叉树中叶子结点的个数 
int GetLeafCount(PBTNode pRoot); 

// 求二叉树中K层结点的个数 
int GetKLevelNode(PBTNode pRoot, int K); 

// 求二叉树的高度 
int Height(PBTNode pRoot); 

//判断一个结点是否在一颗二叉树中
int IsNodeInBinTree(PBTNode pRoot,PBTNode pNode);

//判断一棵二叉树是否是完全二叉树
int IsCompeleteBinTree(PBTNode pRoot);

BInTree.c

#define _CRT_SECURE_NO_WARNING 1

#include "BinTree.h"

//构建二叉树的结点
PBTNode BuyBinTreeNode(BTDataType data)
{
	PBTNode pNewNode = NULL;
	pNewNode = (PBTNode)malloc(sizeof(BTNode));
	if(NULL == pNewNode)
	{
		printf("申请失败!!!\n");
		return NULL;
	}
	pNewNode->_data = data;
	pNewNode->_pLeft = NULL;
	pNewNode->_pRight = NULL;

	return pNewNode;
}

//创建二叉树数据节点(按前序遍历的方式创建)
void _CreateBinTree(PBTNode* pRoot,const BTDataType* array,
					int size,int* index,BTDataType invalid)
					//(*index)是访问数组array的下标
{
	assert(index);
	assert(pRoot);
	if(NULL == pRoot || array[*index] == invalid)
		return;
	else if((*index) < size && invalid != array[*index])
	{
		//创建根节点
		*pRoot = BuyBinTreeNode(array[*index]);

		//创建根节点的左子树
		++(*index);
		_CreateBinTree(&(*pRoot)->_pLeft,array,size,index,invalid);
		
		//创建根节点的右子树
		++(*index);
		_CreateBinTree(&(*pRoot)->_pRight,array,size,index,invalid);

	}
}

//创建二叉树结构
void CreateBinTree(PBTNode* pRoot,const BTDataType* array,
				   int size,BTDataType invalid)
{
	int index = 0;
	_CreateBinTree(pRoot,array,size,&index,invalid);
}

// 拷贝二叉树 
PBTNode CopyBinTree(PBTNode pRoot)
{
	PBTNode pNewNode = NULL;
	if(NULL == pRoot)
		return NULL;
	else   
	{
		//1.先拷贝根节点
		pNewNode =  BuyBinTreeNode(pRoot->_data);

		//2.拷贝左子树
		pNewNode->_pLeft = CopyBinTree(pRoot->_pLeft);

		//3.拷贝右子树
		pNewNode->_pRight = CopyBinTree(pRoot->_pRight);
	}
	return pNewNode;
}


// 销毁二叉树 
void DestroyBinTree(PBTNode *pRoot)
{
	assert(pRoot);
	if(NULL == *pRoot)
		return;
	else
	{
		//左子树存在,销毁左子树
		if((*pRoot)->_pLeft)
			DestroyBinTree(&(*pRoot)->_pLeft);
		//右子树存在,销毁右子树
		if((*pRoot)->_pRight)
			DestroyBinTree(&(*pRoot)->_pRight);
		//最后才能销毁根节点
		free(*pRoot);
		*pRoot = NULL;
	}
}


// 前序遍历递归 
void PreOrder(PBTNode pRoot)
{
	if(pRoot)
	{
		printf("%c ",pRoot->_data);
		PreOrder(pRoot->_pLeft);
		PreOrder(pRoot->_pRight);
	}
}


// 前序遍历非递归 
void PreOrderNor(PBTNode pRoot)
{
	Stack s;
	PBTNode pCur = NULL;
	StackInit(&s);
	StackPush(&s,pRoot);
	
	if(NULL == pRoot)
		return;

	while(!StackEmpty(&s))
	{
		pCur = StackTop(&s);//用pCur来标记栈顶元素
		printf("%c",pCur->_data);
		StackPop(&s);
	
		if(pCur->_pLeft)
			StackPush(&s,pCur->_pLeft);
		else if(pCur->_pRight)
			StackPush(&s,pCur->_pRight);
	}

}

// 中序遍历递归 
void InOrder(PBTNode pRoot)
{
	if(pRoot)
	{
		InOrder(pRoot->_pLeft);
		printf("%c ",pRoot->_data);
		InOrder(pRoot->_pRight);
	}
}

//中序遍历非递归
void InOrderNor(PBTNode pRoot)
{
	Stack s;
	PBTNode pCur = NULL;
	StackInit(&s);
	if(NULL == pRoot)
		return;
	pCur = pRoot;

	while(!StackEmpty(&s) || pCur)
	{
		while(pCur)
		{
			StackPush(&s,pCur);
			pCur = pCur->_pLeft;
		}
		pCur = StackTop(&s);
		printf("%c",pCur->_data);
		StackPop(&s);

		pCur = pCur->_pRight;
	}

}

// 后序遍历递归 
void PostOrder(PBTNode pRoot)
{
	if(pRoot)
	{
		PostOrder(pRoot->_pLeft);
		PostOrder(pRoot->_pRight);
		printf("%c ",pRoot->_data);
	}
}

//后序遍历非递归
void PostOrderNor(PBTNode pRoot)
{
	PBTNode pCur = pRoot;
	PBTNode pPre = NULL;//标记最近访问过的节点
	PBTNode pTop = NULL;//标记栈顶元素
	Stack s;
	
	if(NULL == pRoot)
		return;
	StackInit(&s);
	while(pCur || !StackEmpty(&s))
	{
		while(pCur)
		{
			StackPush(&s,pCur);
			pCur = pCur->_pLeft;
		}
		pTop = StackTop(&s);
		if(NULL == pTop->_pRight || pPre == pTop->_pRight)
		{
			printf("%c",pTop->_data);
			pPre = pTop;
			StackPop(&s);
		}
		else
			pCur = pTop->_pRight;
	}
}

// 层序遍历 
void LevelOrder(PBTNode pRoot)
{
	PBTNode pCur = NULL;
	SQueue q;

	if(pRoot == NULL)
		return;
	//1.初始化一个队列,让根节点进队列
	SQueueInit(&q);
	//2.根节点指针入队列
	SQueuePush(&q,pRoot);

	//3.队列非空,循环执行
	while(!SQueueEmpty(&q))
	{
		//a.取队头元素并访问
		pCur = SQueueFrontData(&q);
		printf("%c ",pCur->_data);
	
		//b.左子树非空,将左子树入队列
		if(pCur->_pLeft)
			SQueuePush(&q,pCur->_pLeft);
		//c.右子树非空,将右子树入队列
		if(pCur->_pRight)
			SQueuePush(&q,pCur->_pRight);
		SQueuePop(&q);
	}

}

// 二叉树的镜像递归 
void MirrorBinTree(PBTNode pRoot)
{
	if(NULL == pRoot)
		return;
	else
	{
		PBTNode tmp = pRoot->_pLeft;
		pRoot->_pLeft = pRoot->_pRight;
		pRoot->_pRight = tmp;

		MirrorBinTree(pRoot->_pLeft);
		MirrorBinTree(pRoot->_pRight);
	}
}

void Swap(PBTNode *Left,PBTNode *Right)
{
	PBTNode tmp = NULL;
	assert(Left);
	assert(Right);

	tmp = *Left;
	*Left = *Right;
	*Right = tmp;

}

// 二叉树的镜像非递归 
void MirrorBinTreeNor(PBTNode pRoot)
{
	SQueue q;
	if(NULL == pRoot)
		return;

	SQueueInit (&q);
	SQueuePush(&q,pRoot);
	while(!SQueueEmpty(&q))
	{
		PBTNode pCur = SQueueFrontData(&q);

		Swap(&pRoot->_pLeft,&pRoot->_pRight);
		
		if(pCur->_pLeft)
			SQueuePush(&q,pCur->_pLeft);
		if(pCur->_pRight)
			SQueuePush(&q,pCur->_pRight);
		SQueuePop(&q);
	}
	SQueueDestory(&q);
} 



// 求二叉树中结点的个数 
int BinTreeSize(PBTNode pRoot)
{
	if(pRoot == NULL)
		return 0;
	return BinTreeSize(pRoot->_pLeft) + BinTreeSize(pRoot->_pRight) + 1;
}

// 获取二叉树中叶子结点的个数 
int GetLeafCount(PBTNode pRoot)
{
	if(NULL == pRoot)
		return 0;
	if( (NULL == (pRoot->_pLeft)) && (NULL == (pRoot->_pRight)) )
		return 1;
	return GetLeafCount(pRoot->_pLeft) + GetLeafCount(pRoot->_pRight);
}

// 求二叉树中K层结点的个数 
int GetKLevelNode(PBTNode pRoot, int K)
{
	if(NULL == pRoot)
		return 0;
	if(1 == K)
		return 1;
	return GetKLevelNode(pRoot->_pLeft,K-1) + GetKLevelNode(pRoot->_pRight,K-1);
}

// 求二叉树的高度 
int Height(PBTNode pRoot)
{
	if(NULL == pRoot)
		return 0;
	return Height(pRoot->_pLeft)>Height(pRoot->_pRight) ? (1+Height(pRoot->_pLeft)):(1+Height(pRoot->_pRight));
}

//判断一个结点是否在一颗二叉树中
int IsNodeInBinTree(PBTNode pRoot,PBTNode pNode)
{
	int ret = 0;
	if(NULL == pRoot || NULL == pNode)
		return 0;
	if(pRoot == pNode)
		return 1;
	if(ret = IsNodeInBinTree(pRoot->_pLeft,pNode))
		return ret;
	return IsNodeInBinTree(pRoot->_pRight,pNode);
}


//判断一棵二叉树是否是完全二叉树(层序遍历)
int IsCompeleteBinTree(PBTNode pRoot)
{
	SQueue q;
	int flag = 0;//标记仅有左孩子的结点
	if(NULL == pRoot)
		return 1;//空树也是一颗完全二叉树

	SQueueInit(&q);
	SQueuePush(&q,pRoot);

	while(!SQueueEmpty(&q))
	{
		PBTNode pCur = SQueueFrontData(&q);
	
		
		if(flag)//找到了左孩子的结点
		{
			if(pCur->_pLeft || pCur->_pRight)
				return 0;//返回假	
		}
		else
		{
			if(NULL == pCur->_pLeft && NULL != pCur->_pRight)//左孩子没有而右孩子存在,一定不为完全二叉树
				return 0;//返回假
			else if(NULL != pCur->_pLeft && NULL == pCur->_pRight)//只有左孩子
			{
				SQueuePush(&q,pCur->_pLeft);
				flag = 1;//标记仅有左孩子的结点
			}
			else if(pCur->_pLeft && pCur->_pRight)
			{
				SQueuePush(&q,pCur->_pLeft);
				SQueuePush(&q,pCur->_pRight);
			}
			else
				flag = 1;
		}
			SQueuePop(&q);
	}
	return 1;
}

test.c

#define _CRT_SECURE_NO_WARNING 1

#include "BinTree.h"

int main()
{
	PBTNode pRoot = NULL;
	PBTNode pNewTree = NULL;
	const char* str = "ABD###CE##F";
	CreateBinTree(&pRoot,str,strlen(str),'#');
	if(IsCompeleteBinTree(pRoot))
		printf("是完全二叉树!!!\n");
	else
		printf("是完全二叉树!!!\n");
	printf("PreOrder: ");
	PreOrder(pRoot);
	printf("\n");

	MirrorBinTree(pRoot);
	MirrorBinTreeNor(pRoot);

	printf("PreOrder: ");
	PreOrder(pRoot);
	printf("\n");
	
	printf("PreOrder: ");
	PreOrderNor(pRoot);
	printf("\n");

	printf("InOrder: ");
	InOrder(pRoot);
	printf("\n");

	printf("InOrderNor: ");
	InOrderNor(pRoot);
	printf("\n");

	printf("PostOrder: ");
	PostOrder(pRoot);
	printf("\n");

	printf("PostOrderNor: ");
	PostOrderNor(pRoot);
	printf("\n");

	printf("LevelOrder: ");
	LevelOrder(pRoot);
	printf("\n");

	pNewTree = CopyBinTree(pRoot);
	printf("PreOrder: ");
	PreOrder(pNewTree);
	printf("\n");

	printf("二叉树中结点的个数为:%d\n", BinTreeSize(pRoot));
	printf("二叉树中叶子结点的个数为:%d\n", GetLeafCount(pRoot));
	printf("二叉树中的高度为:%d\n", Height(pRoot));
	printf("二叉树中第3层结点的个数为:%d\n",GetKLevelNode(pRoot, 3));

	DestroyBinTree(&pRoot);
	DestroyBinTree(&pNewTree);

	return 0;
}

SQueue.h

#define _CRT_SECURE_NO_WARNING 1

#pragma once

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

//链式队列(即队列的底层实现为链表),链表头结点为队列的对头
//typedef int DataType;

extern struct BinTreeNode;
typedef struct BinTreeNode* DataType;

typedef struct ListNode
{
	struct ListNode* _pNext;
	DataType _data;
}Node,*PNode;

typedef struct SQueue
{
	PNode _front;
	PNode _rear;
}SQueue,*PSQueue;

//初始化队列
void SQueueInit(PSQueue q);

//入队列
void SQueuePush(PSQueue q,DataType data);

//出队列
void SQueuePop(PSQueue q);

//判空
int SQueueEmpty(PSQueue q);

//获得队头元素
DataType SQueueFrontData(PSQueue q);

//获得队尾元素
DataType SQueueRearData(PSQueue q);

//查看队列长度
int SQueueSize(PSQueue q);

//销毁队列
void SQueueDestory(PSQueue q);

SQueue.c

#include "SQueue.h"

//初始化队列
void SQueueInit(PSQueue q)
{
	assert(q);
	q->_front = NULL;
	q->_rear = NULL;
}

PNode BuyNewNode(DataType data)
{
	PNode pNewNode = NULL;
	pNewNode = (PNode)malloc(sizeof(Node));
	if(pNewNode == NULL)
	{
		printf("创建失败!!!\n");
		return NULL;
	}
	pNewNode->_pNext = NULL;
	pNewNode->_data = data;

	return pNewNode;
}

//入队列
void SQueuePush(PSQueue q,DataType data)
{
	assert(q);
	if(NULL == q->_front)
		q->_front = q->_rear = BuyNewNode(data);
	else
	{
		q->_rear->_pNext = BuyNewNode(data);
		q->_rear = q->_rear->_pNext;
	}

}

//出队列
void SQueuePop(PSQueue q)
{
	PNode pDel = NULL;
	assert(q);
	if(q->_front == NULL)
		return;
	pDel = q->_front;
	q->_front = q->_front->_pNext;
	free(pDel);
	pDel = NULL;
}

//判空
int SQueueEmpty(PSQueue q)
{
	assert(q);
	if(q->_front == NULL)
		return 1;
	return 0;
}

//获得队头元素
DataType SQueueFrontData(PSQueue q)
{
	assert(q);
	if(NULL == q->_front)
		return 0;
	return q->_front->_data;
}

//获得队尾元素
DataType SQueueRearData(PSQueue q)
{
	assert(q);
	if(NULL == q->_front)
		return 0;
	return q->_rear->_data;
}

//查看队列长度
int SQueueSize(PSQueue q)
{
	int count = 0;
	PNode pCur = q->_front;
	assert(q);
	if(q->_front)
	{
		while(pCur)
		{
			count++;
			pCur = pCur->_pNext;
		}
	}
	return count;
}

//销毁队列
void SQueueDestory(PSQueue q)
{
	PNode pCur = NULL;
	PNode pDel = NULL;
	assert(q);

	if(q->_front)
	{
		pCur = q->_front;
		while(pCur)
		{
			pDel = pCur;
			pCur = pCur->_pNext;
			free(pDel);
		}
	}
}

Stack.h

#pragma once 
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>

extern struct BinTreeNode;
typedef struct BinTreeNode* DataType;

#define MAX_SIZE 12
//typedef int DataType;
typedef struct Stack
{
	DataType _array[MAX_SIZE];//
	int _top;
}Stack;

//栈的初始化
void StackInit(Stack* s);

//入栈
void StackPush(Stack* s,DataType data);

//出栈
void StackPop(Stack* s);

//获取栈顶元素
DataType StackTop(Stack* s);

//获取栈中元素个数
int StackSize(Stack* s);

//检测栈是否为空
int StackEmpty(Stack* s);


//打印栈中的元素
void StackPrint(Stack* s);

Stack.c

#define _CRT_SECURE_NO_WARNING 1

#include "Stack.h"

//栈的初始化
void StackInit(Stack* s)
{
	if(NULL == s)
		return;
	s->_top = 0;
}


//入栈
void StackPush(Stack* s,DataType data)
{
	assert(s);
	if(MAX_SIZE == s->_top)
		return;
	s->_array[s->_top] = data;
	s->_top++;
}

//出栈
void StackPop(Stack* s)
{
	assert(s);
	if(0 == s->_top)
	{
		printf("栈已空!!!\n");
		return;
	}
	s->_top--;
}



//获取栈中元素个数
int StackSize(Stack* s)
{
	if(NULL == s)
	{
		printf("栈为空!!!\n");
		return 0;
	}
	return s->_top;
}

//检测栈是否为空
int StackEmpty(Stack* s)
{
	if(s->_top == 0)
		return 1;
	return 0;
}

//获取栈顶元素
DataType StackTop(Stack* s)
{
	assert(s);
	if(0 == s->_top)
	{
		printf("栈为空没有元素!!!\n");
		return 0;
	}
	return s->_array[s->_top-1];
}

//打印栈中的元素
void StackPrint(Stack* s)
{
	int i = 0;
	assert(s);
	for( ; i < s->_top ;i++)
	{
		printf("%d--->", s->_array[i]);
	}
	printf("NULL\n");
}

猜你喜欢

转载自blog.csdn.net/ijn842/article/details/80354174