二叉树的链式结构的非递归遍历
一. 非递归前序遍历和非递归中序遍历
1. Stack.h
#ifndef__STACK_H__
#define__STACK_H__
#include
#include
// 栈的初始化大小
#defineSTACK_INIT_SIZE 8
// 栈满的时候增加的容量
#defineSTACK_INCR_SIZE 8
// 重命名了栈中数据元素的数据类型
typedef structBinTreeNode *StackElemType;
// 定义了栈的结构
typedef structStack
{
StackElemType *base; // 栈底指针
StackElemType *top; // 栈顶指针
int capacity; // 栈的容量
}Stack;
// 栈中函数的声明
intinitStack(struct Stack *);
intincrStack(struct Stack *);
int isEmpty(structStack *);
int isFull(structStack *);
int push(structStack *, StackElemType);
int pop(structStack *);
int getHead(structStack *, StackElemType);
#endif
2. Stack.c
#include"stack.h"
/*
* 函数名 :initStack
* 函数参数 :struct Stack *stack (栈管理结构的地址)
* 函数功能 :初始化栈的结构
* 函数返回值 :return 0
*
*/
intinitStack(struct Stack *stack)
{
stack->base = (StackElemType*)malloc(sizeof(StackElemType)*STACK_INIT_SIZE);
if(stack->base == NULL)
{
printf("malloc error!!!\n");
return -1;
}
stack->top = stack->base;
stack->capacity = STACK_INIT_SIZE;
return 0;
}
/*
* 函数名 : incrStack
* 函数参数 :struct Stack *stack(栈的管理结构地址)
* 函数功能 : 在栈满了的时候给栈增加容量
* 函数返回值 : return 0
*/
intincrStack(struct Stack *stack)
{
StackElemType *newBase = (StackElemType*)realloc(stack->base, sizeof(StackElemType)*(stack->capacity +STACK_INCR_SIZE));
if(NULL == newBase)
{
return -1;
}
stack->base = newBase;
stack->top = stack->base +stack->capacity;
stack->capacity += STACK_INCR_SIZE;
return 0;
}
/*
* 函数名 :isFull
* 函数参数 :struct Stack *stack (栈的管理结构地址)
* 函数功能 : 判断栈是否满栈
* 函数返回值 : 如果栈是满返回1 否则返回0
*/
int isFull(structStack *stack)
{
return (stack->base +stack->capacity) == stack->top ? 1 : 0;
}
/*
* 函数名 :isEmpty
* 函数参数 : struct Stack *stack (栈的管理结构指针)
* 函数功能 : 判断栈是否是空栈
* 函数返回值 : 如果是空栈返回1 否则返回0
*/
int isEmpty(structStack *stack)
{
return stack->top == stack->base ?1 : 0;
}
/*
* 函数名 : push
* 函数参数 :参数 1 struct Stack *stack(栈管理结构地址)
* 参数 2 StackElemType item 入栈的数据元素
* 函数功能 : 入栈操作
* 函数返回值 : return 0
*/
int push(structStack *stack, StackElemType item)
{
if(isFull(stack) &&incrStack(stack) == -1)
{
printf("内部不足!!!\n");
return -1;
}
*(stack->top) = item;
stack->top ++;
return 0;
}
/*
* 函数名 :getHead
* 函数参数 :参数 1 struct Stack *stack(栈管理结构的地址)
* 参数 2 StackElemType *item 出栈数据元素存放的地方
* 函数功能 : 获取栈顶元素的值
* 函数返回值 : return 0
*/
int getHead(structStack *stack, StackElemType *item)
{
if(isEmpty(stack))
{
return 0;
}
*item = *(stack->top - 1);
return 0;
}
/*
* 函数名 :pop
* 函数参数 :struct Stack *stack(栈管理结构的地址)
* 函数功能 : 出栈
* 函数返回值 : return 0
*/
int pop(structStack *stack)
{
if(isEmpty(stack))
{
return 0;
}
stack->top --;
return 0;
}
3. BinTree.h
#ifndef__BINTREE_H__
#define__BINTREE_H__
#include
#include
#include"stack.h"
// typedef关键字是用来重命名数据类型的 这里重命名了数结点中有效数据的类型
typedef intBinTreeElemType;
// 定义了树的结点类型
typedef structBinTreeNode
{
BinTreeElemType data; // 1. 结点中有效数据
struct BinTreeNode *leftChild; // 2. 结点的左孩子指针
struct BinTreeNode *rightChild; // 3. 结点的右孩子指针
}BinTreeNode;
// 定义了树的结构
typedef structBinTree
{
struct BinTreeNode *root; // 1. 树根的指针
char refvalue; // 2. 定义了结点为空的标志位
}BinTree;
// 函数的声明
intinitBinTree(struct BinTree *);
intcreateBinTree(struct BinTree *);
intpreOrder(struct BinTree *tree);
int inOrder(structBinTree *);
intpostOrder(struct BinTree);
#endif
4. BinTree.c
#include"BinTree.h"
/*
* 函数名 : initBinTree
* 函数参数 : struct BinTree *tree(树结构的地址)
* 函数的功能 :在我们创建一颗二叉树的时候,对二叉树进行初始化
* 1.将根结点的指针 指向为NULL 避免野指针
* 2.使用 '#' 作为空结点的标志
* 函数的返回值 : return 0
*/
intinitBinTree(struct BinTree *tree)
{
tree->root = NULL;
tree->refvalue = '#';
return 0;
}
/*
* 函数名 :createBinTree
* 函数参数 :struct BinTree *tree(树结构的地址)
* 函数的功能 :创建一颗二叉树这个方法是给用户调用的
* 函数的返回值 :return 0
*
*/
intcreateBinTree(struct BinTree *tree)
{
__createBinTree(tree,&(tree->root));
return 0;
}
/*
* 函数名 :__createBinTree
* 函数参数 :参数1 struct BinTree *tree (树的地址)
* 参数2 struct BinTreeNode **t(二重指针 自己理解)
* 函数功能 : 这个方法是内部的方法 被createBinTree函数调用
* 函数返回值 : return 0
*/
int__createBinTree(struct BinTree *tree, struct BinTreeNode **t)
{
// 测试字符串 ABC##DE##F##G#H##
char item;
scanf("%c", &item);
if(item == tree->refvalue)
{
*t = NULL;
}
else
{
*t = (struct BinTreeNode*)malloc(sizeof(struct BinTreeNode));
(*t)->data = item;
(*t)->leftChild =(*t)->rightChild = NULL;
__createBinTree(tree,&((*t)->leftChild));
__createBinTree(tree,&((*t)->rightChild));
}
return 0;
}
/*
* 函数名 :preOrder
* 函数参数 :struct BinTree *tree (树的地址)
* 函数功能 :非递归前序遍历二叉树
* 函数返回值 :return 0
*/
intpreOrder(struct BinTree *tree)
{
printf("递归前序遍历二叉树 : ");
__preOrder(tree->root);
printf("\n");
return 0;
}
/*
* 函数名 :__preOrder
* 函数参数 :struct BinTreeNode *t (树中结点的指针)
* 函数功能 :该函数是内部函数被preOrder函数调用
* 函数返回值 :return 0
*/
int__preOrder(struct BinTreeNode *t)
{
struct BinTreeNode *p = t;
struct Stack stack;
initStack(&stack);
push(*stack, p);
while(!isEmpty(&stack))
{
getHead(&stack, &p);
pop(&stack);
printf("%c",p->data);
if(p->rightChild != NULL)
{
push(&stack,p->rightChild);
}
if(p->leftChild != NULL)
{
push(&stack,p-leftChild);
}
}
return 0;
}
// 中序遍历二叉树
int inOrder(structBinTree *tree)
{
printf("递归中序遍历二叉树 : ");
__inOrder(tree->root);
printf("\n");
return 0;
}
int__inOrder(struct BinTreeNode *t)
{
struct BinTreeNode *p = t;
struct Stack stack;
initStack(&stack);
push(&stack, p);
while(!isEmpty(&stack))
{
while(p->leftChild != NULL)
{
p = p->leftChild;
push(&stack, p);
}
getHead(&stack, &p);
pop(&stack);
printf("%c",p->data);
if(p->rightChild != NULL)
{
p = p->rightChilsd;
push(&stack, p);
}
}
return 0;
}
5. Main.c
#include"BinTree.h"
int main(int argc,char &argv)
{
struct BinTree tree;
// 初始化二叉树
initBinTree(&tree);
// 创建二叉树
createBinTree(&tree);
// 非递归前序遍历
preOrder(&tree);
// 非递归中序遍历
inOrder(&tree);
// 非递归后续遍历
postOrder(&tree);
return 0;
}
二. 非递归后序遍历
1. Stack.h
#ifndef__STACK_H__
#define__STACK_H__
#include
#include
// 栈的初始化大小
#defineSTACK_INIT_SIZE 8
// 栈满的时候增加的容量
#defineSTACK_INCR_SIZE 8
// 重命名了栈中数据元素的数据类型
typedef structStackNode StackElemType;
// 定义了栈的结构
typedef structStack
{
StackElemType *base; // 栈底指针
StackElemType *top; // 栈顶指针
int capacity; // 栈的容量
}Stack;
// 配合后续遍历使用栈中保存的数据类型
typedefenum{L,R}FLAG;
typedef structStackNode
{
struct BinTreeNode *brAddress;
FLAG flag;
}StackNode;
// 栈中函数的声明
intinitStack(struct Stack *);
intincrStack(struct Stack *);
int isEmpty(structStack *);
int isFull(structStack *);
int push(structStack *, StackElemType);
int pop(structStack *);
int getHead(structStack *, StackElemType);
#endif
2. Stack.c
同上
3. BinTree.h
同上
4. BinTree.c
// 后序遍历二叉树
intpostOrder(struct BinTree *tree)
{
printf("递归中序遍历二叉树 : ");
__postOrder(tree->root);
printf("\n");
return 0;
}
int__postOrder(struct BinTreeNode *t)
{
struct BinTreeNode *p = t;
struct Stack stack;
initStack(&stack);
struct StackNode stNode;
do
{
while(p != NULL)
{
stNode.btAddress = p;
stNode.flag = L;
push(&stack, stNode);
p = p->leftChild;
}
getHead(&stack, &stNode);
pop(&stack);
if(stNode.flag == R)
{
printf("%c",stNode.brAddress->data);
continue;
}
if(stNode.flag = L)
{
stNode.flag = R;
push(&stack, stNode);
p =stNode.btAddress->rightChild;
}
}while(!isEmpty(&stack));
}
其余代码同上
5. Main.c
同上