(六)数据结构之二叉树的简单实现
2017-09-17 18:45
441 查看
1、基本数据结构
/* 二叉树的基本数据结构的定义 */typedef char ElementType;
typedef struct TreeNode *BinTree;
typedef BinTree Position;
struct TreeNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
采用链式存储方式来存储二叉树,每个二叉树结点包括一个数据域和两个指针域,其中数据域用来存放二叉树对应结点的数据,指针域分别用来指向其左右孩子结点。
2、二叉树的递归遍历
2.1 先序遍历
/* 先序递归遍历 */void PreOrderTraversal( BinTree BT )
{
if( BT )
{
printf("%c ", BT->Data);
PreOrderTraversal( BT->Left );
PreOrderTraversal( BT->Right );
}
}
2.2 中序遍历
/* 中序递归遍历 */void InOrderTraversal( BinTree BT )
{
if( BT )
{
InOrderTraversal( BT->Left );
printf("%c ", BT->Data);
InOrderTraversal( BT->Right );
}
}
2.3 后序遍历
/* 后序递归遍历 */ void PostOrderTraversal( BinTree BT ) { if( BT ) { PostOrderTraversal( BT->Left ); PostOrderTraversal( BT->Right); printf("%c ", BT->Data); } }
3、二叉树的非递归遍历
考虑到算法的复杂度问题常常为了提高效率而采用非递归的二叉树遍历方法,为了实现非递归遍历需要借助一种基本的数据结构堆栈,堆栈的具体实现可以参考这篇文章http://blog.csdn.net/tech_pro/article/details/78011998。3.1 先序遍历
/* 先序非递归遍历 */ void PreOrderTraversalWithStack( BinTree BT ) { BinTree T = BT; Stack *S = CreateStack(); /*创建并初始化堆栈S*/ while( T || !IsEmpty(S) ) { while(T) { /*一直向左并将沿途结点压入堆栈*/ printf("%c ", T->Data); /*(访问)打印结点*/ Push(S,T); T = T->Left; } if(!IsEmpty(S)) { T = Pop(S); /*结点弹出堆栈*/ T = T->Right; /*转向右子树*/ } } DestroyStack(S); }
3.2 中序遍历
/* 中序非递归遍历 */ void InOrderTraversalWithStack( BinTree BT ) { BinTree T = BT; Stack *S = CreateStack(); /*创建并初始化堆栈S*/ while( T || !IsEmpty(S) ) { while(T) { /*一直向左并将沿途结点压入堆栈*/ Push(S,T); T = T->Left; } if(!IsEmpty(S)) { T = Pop(S); /*结点弹出堆栈*/ printf("%c ", T->Data); /*(访问)打印结点*/ T = T->Right; /*转向右子树*/ } } DestroyStack(S); }
3.3 后序遍历
/* 后序非递归遍历 */ void PostOrderTraversalWithStack( BinTree BT ) { BinTree T = BT; BinTree Done = NULL; /* 做一个标记来判断相关结点是否已经被访问 */ Stack *S = CreateStack(); /*创建并初始化堆栈S*/ while( T || !IsEmpty(S) ) { while(T) { /*一直向左并将沿途结点压入堆栈*/ Push(S,T); T = T->Left; } if(!IsEmpty(S)) { T = Pop(S); /*结点弹出堆栈*/; if((T->Right == NULL) || (T->Right == Done)) { printf("%c ", T->Data); /*(访问)打印结点*/ Done = T; T = NULL; } else { Push(S, T); T = T->Right; } } } DestroyStack(S); }
4、二叉树的层次遍历
二叉树的层次遍历要借助一种基本的数据结构队列,关于队列的具体实现可以参考这篇文章:http://blog.csdn.net/tech_pro/article/details/78012076。/* 层次遍历二叉树 */
void LevelOrderTraversal ( BinTree BT )
{
Queue *Q = NULL;
BinTree T = NULL;
if ( !BT ) return; /* 若是空树则直接返回 */
Q = CreatQueue(); /*创建并初始化队列Q*/
AddQ( Q, BT );
while ( !IsEmptyQ( Q ) )
{
T = DeleteQ( Q );
printf("%c ", T->Data); /*访问取出队列的结点*/
if ( T->Left ) AddQ( Q, T->Left );
if ( T->Right ) AddQ( Q, T->Right );
}
}
5、基本的应用
5.1 输出叶子结点
/* 输出二叉树的叶子结点, 按照先序遍历 */int PreOrderPrintLeaves( BinTree BT )
{
int i = 0;
if( BT )
{
if ( !BT->Left && !BT->Right )
{
printf("%c ", BT->Data );
i = i + 1;
}
PreOrderPrintLeaves ( BT->Left );
PreOrderPrintLeaves ( BT->Right );
}
return i;
}
5.2 求二叉树的高度
/* 求二叉树的高度 */ int PostOrderGetHeight( BinTree BT ) { int HL, HR, MaxH; if( BT ) { HL = PostOrderGetHeight(BT->Left); /*求左子树的深度*/ HR = PostOrderGetHeight(BT->Right); /*求右子树的深度*/ MaxH = (HL > HR) ? HL : HR; /*取左右子树较大的深度*/ return ( MaxH + 1 ); /*返回树的深度*/ } else return 0; /* 空树深度为0 */ }
6、实例代码完整实现
/* 实现二叉树的一些基本操作 */#include <stdio.h>
#include <stdlib.h>
/* 二叉树的基本数据结构的定义 */
typedef char ElementType;
typedef struct TreeNode *BinTree;
typedef BinTree Position;
struct TreeNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
/* 创建一颗二叉树, 先创建根节点,然后创建左子树,最后创建右子树*/
BinTree CreatBinTree()
{
ElementType data;
BinTree T;
scanf("%c ", &data); // 通过控制台获得一个结点数据
if('#' == data) // 如果为空树结点
{
T = NULL;
}
else // 如果为非空树结点
{
T = (BinTree)malloc(sizeof(struct TreeNode)); // 分配一块内存给根结点
if(NULL == T) return NULL;
T->Data= data;
T->Left = CreatBinTree(); // 递归创建左子树
T->Right = CreatBinTree(); // 递归创建右子树
}
return T; // 返回树根结点
}
/* 销毁一颗二叉树 */
void DestroyBinTree(BinTree BT)
{
if (BT)
{
DestroyBinTree(BT->Left);
DestroyBinTree(BT->Right);
free(BT);
BT = NULL;
}
}
/***************************************** 递归遍历 *******************************************/
/* 先序递归遍历 */
void PreOrderTraversal( BinTree BT )
{
if( BT )
{
printf("%c ", BT->Data);
PreOrderTraversal( BT->Left );
PreOrderTraversal( BT->Right );
}
}
/* 中序递归遍历 */
void InOrderTraversal( BinTree BT )
{
if( BT )
{
InOrderTraversal( BT->Left );
printf("%c ", BT->Data);
InOrderTraversal( BT->Right );
}
}
/* 后序递归遍历 */ void PostOrderTraversal( BinTree BT ) { if( BT ) { PostOrderTraversal( BT->Left ); PostOrderTraversal( BT->Right); printf("%c ", BT->Data); } }
/**********************定义堆栈的基本操作和数据结构***************************/
/* 定义堆栈的数据结构 */
#define MaxSize 20
typedef BinTree ElementTypeB;
typedef struct _Stack{
ElementTypeB Data[MaxSize];
int Top;
} Stack;
/* 创建一个堆栈 */
Stack *CreateStack()
{
Stack *S = (Stack*)malloc(sizeof(Stack));
if(NULL != S) S->Top = -1;
return S;
}
/* 销毁一个堆栈 */
void DestroyStack(Stack *PtrS)
{
if(NULL != PtrS)
{
free(PtrS);
PtrS = NULL;
}
}
/* 判断一个堆栈是否为空,为空返回1,否者返回0 */
int IsEmpty( Stack *S )
{
return (S->Top == -1);
}
/* 判断一个堆栈是否为满, 为满返回1,否者返回0 */
int IsFull( Stack *S )
{
return (S->Top == MaxSize - 1);
}
/* 压栈操作,先移动Top,后压入 */
void Push( Stack *PtrS, ElementTypeB item )
{
if (IsFull(PtrS)) // 判断是否栈满
{
printf("Stack is full!\n");
return;
}
else
{
PtrS->Data[++(PtrS->Top)] = item;
return;
}
}
/* 出栈操作,先弹出,后移动Top */
ElementTypeB Pop( Stack *PtrS )
{
if (IsEmpty(PtrS)) // 判断堆栈是否为空
{
printf("The stack is empty!\n");
return NULL;
}
else
return ( PtrS->Data[(PtrS->Top)--] );
}
/*********************************结束***************************************/
/***************************************** 非递归遍历 *******************************************/
/* 先序非递归遍历 */ void PreOrderTraversalWithStack( BinTree BT ) { BinTree T = BT; Stack *S = CreateStack(); /*创建并初始化堆栈S*/ while( T || !IsEmpty(S) ) { while(T) { /*一直向左并将沿途结点压入堆栈*/ printf("%c ", T->Data); /*(访问)打印结点*/ Push(S,T); T = T->Left; } if(!IsEmpty(S)) { T = Pop(S); /*结点弹出堆栈*/ T = T->Right; /*转向右子树*/ } } DestroyStack(S); }
/* 中序非递归遍历 */
void InOrderTraversalWithStack( BinTree BT )
{
BinTree T = BT;
Stack *S = CreateStack(); /*创建并初始化堆栈S*/
while( T || !IsEmpty(S) )
{
while(T)
{
/*一直向左并将沿途结点压入堆栈*/
Push(S,T);
T = T->L
c623
eft;
}
if(!IsEmpty(S))
{
T = Pop(S); /*结点弹出堆栈*/
printf("%c ", T->Data); /*(访问)打印结点*/
T = T->Right; /*转向右子树*/
}
}
DestroyStack(S);
}
/* 后序非递归遍历 */ void PostOrderTraversalWithStack( BinTree BT ) { BinTree T = BT; BinTree Done = NULL; /* 做一个标记来判断相关结点是否已经被访问 */ Stack *S = CreateStack(); /*创建并初始化堆栈S*/ while( T || !IsEmpty(S) ) { while(T) { /*一直向左并将沿途结点压入堆栈*/ Push(S,T); T = T->Left; } if(!IsEmpty(S)) { T = Pop(S); /*结点弹出堆栈*/; if((T->Right == NULL) || (T->Right == Done)) { printf("%c ", T->Data); /*(访问)打印结点*/ Done = T; T = NULL; } else { Push(S, T); T = T->Right; } } } DestroyStack(S); }
/**************************定义队列操作的基本数据和算法*************************** */
/* 定义队列的基本数据结果 */
//#define MaxSize 20
typedef BinTree ElementTypeC;
typedef struct _Queue{
ElementTypeC Data[ MaxSize ];
int rear;
int front;
} Queue;
/* 创建一个空队列 */
Queue *CreatQueue()
{
Queue *Q = (Queue*)malloc(sizeof(Queue));
if(NULL != Q)
{
Q->front = 0;
Q->rear = 0;
}
return Q;
}
/* 消除一个队列 */
void DestroyQueue(Queue *PtrQ)
{
if(NULL != PtrQ)
free(PtrQ);
PtrQ = NULL;
}
/* 判断队列是否为空,1为空,0非空 */
int IsEmptyQ( Queue *PtrQ )
{
return (PtrQ->front == PtrQ->rear);
}
/* 判断队列是否为满,1为满,0为空 */
int IsFullQ( Queue *PtrQ )
{
return ((PtrQ->rear+1)%MaxSize == PtrQ->front);
}
/* 向循环队列尾部插入一个元素 */
void AddQ( Queue *PtrQ, ElementTypeC item)
{
if ( IsFullQ(PtrQ) )
{
printf("The queue is full!\n");
return;
}
PtrQ->rear = (PtrQ->rear+1)% MaxSize;
PtrQ->Data[PtrQ->rear] = item;
}
/* 删除循环队列的队头的元素 */
ElementTypeC DeleteQ ( Queue *PtrQ )
{
if ( IsEmptyQ(PtrQ) )
{
printf("The queue is empty!\n");
return NULL;
}
else
{
PtrQ->front = (PtrQ->front+1)% MaxSize;
return PtrQ->Data[PtrQ->front];
}
}
/********************************************队列定义结束****************************************/
/* 层次遍历二叉树 */
void LevelOrderTraversal ( BinTree BT )
{
Queue *Q = NULL;
BinTree T = NULL;
if ( !BT ) return; /* 若是空树则直接返回 */
Q = CreatQueue(); /*创建并初始化队列Q*/
AddQ( Q, BT );
while ( !IsEmptyQ( Q ) )
{
T = DeleteQ( Q );
printf("%c ", T->Data); /*访问取出队列的结点*/
if ( T->Left ) AddQ( Q, T->Left );
if ( T->Right ) AddQ( Q, T->Right );
}
}
/********************************************定义二叉树的一些其他应用****************************************/
/* 输出二叉树的叶子结点, 按照先序遍历 */
int PreOrderPrintLeaves( BinTree BT )
{
int i = 0;
if( BT )
{
if ( !BT->Left && !BT->Right )
{
printf("%c ", BT->Data );
i = i + 1;
}
PreOrderPrintLeaves ( BT->Left );
PreOrderPrintLeaves ( BT->Right );
}
return i;
}
/* 求二叉树的高度 */ int PostOrderGetHeight( BinTree BT ) { int HL, HR, MaxH; if( BT ) { HL = PostOrderGetHeight(BT->Left); /*求左子树的深度*/ HR = PostOrderGetHeight(BT->Right); /*求右子树的深度*/ MaxH = (HL > HR) ? HL : HR; /*取左右子树较大的深度*/ return ( MaxH + 1 ); /*返回树的深度*/ } else return 0; /* 空树深度为0 */ }
/* 程序入口 */
int main()
{
BinTree tree = NULL;
/* 创建一颗二叉树 */
tree = CreatBinTree();
/* 递归遍历 */
printf("************************Traversal***************************\n");
printf("Pre : "); PreOrderTraversal(tree); printf("\n");
printf("In : "); InOrderTraversal(tree); printf("\n");
printf("Post : "); PostOrderTraversal(tree); printf("\n");
/* 非递归遍历 */
printf("************************normal******************************\n");
printf("Pre : "); PreOrderTraversalWithStack(tree); printf("\n");
printf("In : "); InOrderTraversalWithStack(tree); printf("\n");
printf("Post : "); PostOrderTraversalWithStack(tree); printf("\n");
/* 层次遍历二叉树 */
printf("************************level*******************************\n");
printf("Level : "); LevelOrderTraversal(tree); printf("\n");
/* 二叉树的一些基本使用 */
printf("************************apply*******************************\n");
printf("Leaves : "); PreOrderPrintLeaves(tree); printf("\n");
printf("The height of this tree is %d\n", PostOrderGetHeight(tree));
DestroyBinTree(tree); /* 销毁一棵树 */
return 0;
}
相关文章推荐
- 简单数据结构的实现之二叉树
- 【数据结构】数据结构C语言的实现(简单二叉树)
- 数据结构(JAVA)---二叉树的简单实现及排序
- 数据结构学习笔记8——简单二叉树的实现与遍历
- 简单数据结构之二叉树(C++实现)
- 数据结构-二叉树实现
- 用c++实现二叉树及堆的数据结构
- 数据结构(Java语言)——BinaryHeap简单实现
- 二叉树 简单实现 问题解决
- 初识树结构,简单模拟无规律的二叉树,实现二叉树的构建,计算树的深度以及三种遍历方式以及搜索删除,销毁整个树
- 简单数据结构----链栈的C++实现
- javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题
- 数据结构 二叉树的重构(java实现)
- java 数据结构二叉树的实现代码
- 数据结构-二叉树(应用篇)-之二叉搜索树 C和C++的实现
- 几种基本数据结构--栈、队列、双向链表、有根树的分析和简单实现
- (七)数据结构之搜索二叉树的简单实现
- java实现简单二叉树排序
- 【数据结构】迭代器实现二叉树的中序遍历
- 数据结构之查找的概念及简单实现