二叉树各类算法实现

Posted cjj2503

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树各类算法实现相关的知识,希望对你有一定的参考价值。

数据结构----二叉树各类算法实现

二叉树的各类算法设计实现

主要功能:
① 建立不少于10个结点的二叉树T;
② 用非递归方式先序遍历方式输出树T的结点;
③ 用非递归方式中序遍历方式输出树T的结点;
④ 用后序遍历方式输出树T的结点;
⑤ 用层次遍历方式输出树T的结点;
⑥ 输出树T的深度;
⑦ 输出树T的叶子结点和非叶子结点;

测试数据说明:
以完全二叉树的方式从左到右,从上到下,输入数据,数据为0表示对应没有结点,指针为空
1 5 8 0 9 0 10 0 0 54 3 0 0 9 -1 //二叉树的数据,以-1结尾

测试案例
20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 -1

> 输出案例
> The tree is:
         --6
              --14
                     --7
       --18
                     --8
              --15
                     --9
--20
                     --10
              --16
                     --11
       --19
                            --2
                     --12
                            --3
              --17
                            --4
                     --13
                            --5
The result of  PreOrder traversal not recursion:
20 19 17 13 5 4 12 3 2 16 11 10 18 15 9 8 14 7 6
The result of  InOrder traversal not recursion:
5 13 4 17 3 12 2 19 11 16 10 20 9 15 8 18 7 14 6
The result of recursion PostOrder traversal:
5 4 13 3 2 12 17 11 10 16 19 9 8 15 7 6 14 18 20
The result of level traversal:
20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2
The deepth of the tree is: 4
All the leaves of the tree after sorting:
2 3 4 5 6 7 8 9 10 11
All the not leaves of the tree after sorting:
12 13 14 15 16 17 18 19 20

BiTree.h

#ifndef BITREE_H
#define BITREE_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int ItemType;

//二叉树结点结构定义
typedef struct TreeNode
{
	ItemType data;
	struct	TreeNode* leftChild;
	struct TreeNode* rightChild;
	
}BiTreeNode; 

void CreateTree(BiTreeNode** root,int i, ItemType d[], int n);  
void PreOrder(BiTreeNode* root,ItemType data[], int* n);
void InOrder(BiTreeNode* root,ItemType data[], int* n);
void PostOrder(BiTreeNode* root, ItemType data[], int* n);
void LevelorderTraverse(BiTreeNode  *root,ItemType data[], int* n);
int  Deepth(BiTreeNode  *root);
void GetLeaves(BiTreeNode  *root,ItemType leaves[], int* n);
void GetNotLeaves(BiTreeNode  *root,ItemType notleaves[], int* n);
void PrintTree(BiTreeNode *root,int n);
void FreeTree(BiTreeNode** root);
#endif

SeqCQueue.h

#ifndef SEQCQUEUE_H
#define SEQCQUEUE_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "BiTree.h"

#define MaxQueueSize 100
typedef BiTreeNode* QDataType;

//顺序循环队列的结构体
typedef struct Queue
{ 
	QDataType queue[MaxQueueSize];
	int rear;  //队尾指针
	int front;  //队头指针
	int count;  //计数器
} SeqCQueue; 

void QueueInitiate(SeqCQueue *Q);

int QueueNotEmpty(SeqCQueue Q);

int QueueAppend(SeqCQueue *Q, QDataType x);

int QueueDelete(SeqCQueue *Q, QDataType *d);

int QueueGet(SeqCQueue Q, QDataType *d);

#endif

SeqStack.h

#ifndef SEQSTACK_H
#define SEQSTACK_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "BiTree.h"

#define MaxStackSize 100
typedef BiTreeNode* DataType;

//顺序堆栈结构体定义
typedef struct
{	DataType stack[MaxStackSize];			
	int top;
} SeqStack;


void StackInitiate(SeqStack *S);	

int StackNotEmpty(SeqStack*S);

int StackPush(SeqStack *S, DataType x);

int StackPop(SeqStack *S, DataType *d);

int StackTop(SeqStack S, DataType *d);

#endif

SeqCQueue.c

#include "SeqCQueue.h"

//初始化QueueInitiate(Q)
void QueueInitiate(SeqCQueue *Q)
{
	Q->rear = 0;		
	Q->front = 0;
	Q->count = 0;
}


//判断循环队列Q非空否,非空则返回1,否则返回0
int QueueNotEmpty(SeqCQueue Q)
{
	if(Q.count != 0)	return 1;
	else return 0;
}


//把数据元素值x插入顺序循环队列Q的队尾,成功返回0,失败返回-1
int QueueAppend(SeqCQueue *Q, QDataType x)
{
	if(Q->count > 0 && Q->rear == Q->front)
	{	
		printf("The queue is full!\\n");
		return -1;
	}
	else
	{	
		Q->queue[Q->rear] = x;
		Q->rear = (Q->rear + 1) % MaxQueueSize;
		Q->count++;
		return 0;
	}
}


//删除顺序循环队列Q的队头元素并赋值给d,成功则返回0,失败返回-1
int QueueDelete(SeqCQueue *Q, QDataType *d)
{
	if(Q->count == 0)
	{	printf("The queue is empty!\\n");
		return -1;
	}
	else
	{	*d = Q->queue[Q->front];
		Q->front = (Q->front + 1) % MaxQueueSize;
		Q->count--;
		return 0;
	}
}

//取队头数据元素 ,成功则返回0,失败返回-1
int QueueGet(SeqCQueue Q, QDataType *d)
{
	if(Q.count == 0)
	{
		printf("The queue is empty!\\n");
		return -1;
	}
	else
	{
		*d = Q.queue[Q.front];
		return 0;
	}
}

SeqStack.c

#include "SeqCQueue.h"

//初始化QueueInitiate(Q)
void QueueInitiate(SeqCQueue *Q)
{
	Q->rear = 0;		
	Q->front = 0;
	Q->count = 0;
}


//判断循环队列Q非空否,非空则返回1,否则返回0
int QueueNotEmpty(SeqCQueue Q)
{
	if(Q.count != 0)	return 1;
	else return 0;
}


//把数据元素值x插入顺序循环队列Q的队尾,成功返回0,失败返回-1
int QueueAppend(SeqCQueue *Q, QDataType x)
{
	if(Q->count > 0 && Q->rear == Q->front)
	{	
		printf("The queue is full!\\n");
		return -1;
	}
	else
	{	
		Q->queue[Q->rear] = x;
		Q->rear = (Q->rear + 1) % MaxQueueSize;
		Q->count++;
		return 0;
	}
}


//删除顺序循环队列Q的队头元素并赋值给d,成功则返回0,失败返回-1
int QueueDelete(SeqCQueue *Q, QDataType *d)
{
	if(Q->count == 0)
	{	printf("The queue is empty!\\n");
		return -1;
	}
	else
	{	*d = Q->queue[Q->front];
		Q->front = (Q->front + 1) % MaxQueueSize;
		Q->count--;
		return 0;
	}
}

//取队头数据元素 ,成功则返回0,失败返回-1
int QueueGet(SeqCQueue Q, QDataType *d)
{
	if(Q.count == 0)
	{
		printf("The queue is empty!\\n");
		return -1;
	}
	else
	{
		*d = Q.queue[Q.front];
		return 0;
	}
}

BiTree.c

#include "BiTree.h"
#include "SeqStack.h"
#include "SeqCQueue.h"


//根据ItemType d[]的数据创建不带头结点的二叉树
void CreateTree(BiTreeNode** root,int i, ItemType d[], int n)
{
	if(i>=n||d[i]==0){  //数据是0,则表示没有此结点
	 	*root=NULL;
		return ;
	}
	*root =(BiTreeNode*)malloc(sizeof(BiTreeNode));
	(*root)->data=d[i];
	CreateTree(&((*root)->leftChild),2*i+1,d,n);
	CreateTree(&((*root)->rightChild),2*i+2,d,n);

}


//非递归先序遍历,遍历的数据放入数组data[ ]中带出函数外,n为数组元素的个数
void PreOrder(BiTreeNode* root,ItemType data[], int* n){
    SeqStack *stk;
    stk = (SeqStack*)malloc(sizeof(SeqStack));
    StackInitiate(stk);
    BiTreeNode *p=root;
    while (p || StackNotEmpty(stk)) {
    if(p) { 
			StackPush(stk, p);
			data[*n] = p->data;
			(*n)++;
			p = p->leftChild;
	}
	else
	{
		StackPop(stk, &p);
		p = p->rightChild;
	}
   }
}
//非递归中序遍历,遍历的数据放入数组data[]中带出函数外,n为数组元素的个数
void InOrder(BiTreeNode* root,ItemType data[], int* n){
	//填充代码
	SeqStack* stk;
	stk = (SeqStack*)malloc(sizeof(SeqStack));
	StackInitiate(stk);
	BiTreeNode *p = root;
	while (p || StackNotEmpty(stk)) {
		if (p) {
			StackPush(stk, p);
			p = p->leftChild;
		}
		else {
			StackPop(stk, &p);
			data[*n] = p->data;
			(*n)++;
			p = p->rightChild;
		}
	}	
}

//递归后序遍历二叉树,遍历的数据放入数组data[]中带出函数外,n为数组元素的个数
void PostOrder(BiTreeNode* root,ItemType data[], int* n)
{
    if (root->leftChild != NULL)
    {
		PostOrder(root->leftChild, data, n);
	}
	if (root->rightChild != NULL)
	{
		PostOrder(root->rightChild, data, n);
	}
	data[*n] = root->data;
	(*n)++;
	//printf("%d",p->data);
}

//层次遍历,遍历的数据放入数组data[]中带出函数外,n为数组元素的个数
void  LevelorderTraverse(BiTreeNode  *root, ItemType data[], int* n){  
	SeqCQueue *q;
	q = (SeqCQueue*)malloc(sizeof(SeqCQueue));
	QueueInitiate(q);
	BiTreeNode *pt =root;
	QueueAppend(q,pt);
	while (QueueNotEmpty(*q))
		{
			QueueDelete(q, &pt);
			data[*n]=pt->data;
			(*n)++;
			if (pt->leftChild != NULL)
				QueueAppend(q, pt->leftChild);
			if (pt->rightChild != NULL)
				QueueAppend(q, pt->rightChild);
		}   
}

//求树的深度,深度通过返回值带回函数外,注意:根的深度为0
int Deepth(BiTreeNode  *root){ 
	//填充代码
	int h1,h2;
	if(root == NULL){
		return -1;
	}
		h1 = Deepth(root->leftChild);
		h2 = Deepth(root->rightChild);
		if(h1>h2)
		{
			return h1+1;
		}
		else
		{
			 return h2+1;
		}
}
//得到所有叶子结点,叶子结点数据放入数组leaves[]带出函数外,n为数组元素的个数
void GetLeaves(BiTreeNode  *root,ItemType leaves[], int* n){

	//填充代码
	if(root!=NULL)
	{
	if(root->leftChild == NULL && root->rightChild == NULL)
	{
		leaves[*n]=root->data;
		(*n)++;
	}
	GetLeaves(root->leftChild, leaves, n);
	GetLeaves(root->rightChild, leaves, n);
	}	
}

//得到所有非叶子结点,非叶子结点数据放入数组notleaves[]带出函数外,n为数组元素的个数
void GetNotLeaves(BiTreeNode  *root, ItemType notleaves[], int* n){

	if(root!=NULL)
	{
	if(root->leftChild!= NULL || root->rightChild!= NULL)
	{
		notleaves[*n]=root->data;
		(*n)++;
	}
	GetNotLeaves(root->leftChild, notleaves, n);
	GetNotLeaves(root->rightChild, notleaves, n);
	}		
}

//打印二叉树
void PrintTree(BiTreeNode* root,int n){
	int i;
	if(root==NULL)return;
	PrintTree(root->rightChild,n+1);
	for(i=0;i<n;i++)printf("       ");
	if(n>=0){
		printf("--");
		printf("%d\\n",root->data);
	}
	PrintTree(root->leftChild,n+1);
}


以上是关于二叉树各类算法实现的主要内容,如果未能解决你的问题,请参考以下文章

二叉树各类算法实现

二叉树各类算法实现

求数据结构算法平衡二叉树实现代码

一文搞定二叉树---由二叉树到贪心算法

用java实现二叉树的遍历算法

C# 霍夫曼二叉树压缩算法实现