//LinkBinTree.h
#ifndef _LINKBINTREE_H_
#define _LINKBINTREE_H_
#include
#include
#include
//此处不能使用typedef去"定义"数据的类型,提供一个typedef会传递此数据结构支持多种类型的信息,而创建二叉树节点的函数,却明确指定以固定%x的方式去
//格式化存储输入,这种声明与实现的不一致可能会带来不必要的烦恼
//typedef char Element; 禁止!!!
//二叉树节点类型结构
typedef struct _BinTreeNode
{
char data;
struct _BinTreeNode *leftChild; //左孩子
struct _BinTreeNode *rightChild; //右孩子
}BinTreeNode;
//二叉树管理结构,flag参数用于标记空节点,当数据等于flag的值时,节点为空
typedef struct _BinTree
{
BinTreeNode *root;
char flag;
}BinTree;
//初始化函数,用于初始化二叉树管理变量
void InitBinTree(BinTree *tree, char flag);
//创建函数,以输入字符方式创建
void CreateBinTree_input(BinTree *tree); //提供接口的封装函数
//非递归遍历
//层次遍历
void LevelOrder(BinTree tree);
//先、中序遍历非递归实现
void PreOrder(BinTree tree);
void InOrder(BinTree tree);
#endif // _LINKBINTREE_H_
//LinBinTree.c
#include "LinkBinTree.h"
#include "LinkQueue.h"
#include "LinkStack.h"
void InitBinTree(BinTree *tree, char flag)
{
tree->root = NULL;
tree->flag = flag;
}
static void Create_1(BinTree *tree, BinTreeNode **node) //创建方式的先序的
{
char item;
if( 1 != scanf("%c", &item) || item == tree->flag ) //如果输入字符与空节点标记值相等,则将节点置NULL并立即返回
{
*node = NULL;
return ;
}
//输入值不为标记,创建节点并创建左右孩子
*node = (BinTreeNode *)malloc(sizeof(BinTreeNode));
if( NULL == *node )
{
*node = NULL;
return ;
}
(*node)->data = item;
Create_1(tree, &(*node)->leftChild);
Create_1(tree, &(*node)->rightChild);
}
static BinTreeNode *Create_2(BinTree *tree)
{
char item;
if( 1 != scanf("%c", &item) || item == tree->flag )
return NULL;
BinTreeNode * p = (BinTreeNode *)malloc(sizeof(BinTreeNode));
if( NULL == p )
return NULL;
p->data = item;
p->leftChild = Create_2(tree);
p->rightChild = Create_2(tree);
return p;
}
void CreateBinTree_input(BinTree *tree)
{
printf("请输入各节点元素,#表示该节点为空节点\n");
Create_1(tree, &(tree->root));
//tree->root = Create_2(tree);
}
//利用队列先入先出的特性对二叉树进行层次遍历
static void LevelOrder_(BinTreeNode *node)
{
if( NULL == node )
return ;
BinTreeNode *e = NULL;
LinkQueue queue;
InitQueue(&queue);
EnQueue(&queue, node);
while (!IsEmpty(queue)) //有未被访问节点
{
GetTop(queue, &e);
DeQueue(&queue); //保证只被访问一次
printf("%c", e->data);
if( NULL != e->leftChild )
EnQueue(&queue, e->leftChild); //先入队左孩子确保左孩子先被访问
if( NULL != e->rightChild )
EnQueue(&queue, e->rightChild);
}
}
void LevelOrder(BinTree tree)
{
LevelOrder_(tree.root);
printf("\n");
}
//利用栈先入后出的特性对二叉树进行层次遍历
static void PreOrder_(BinTreeNode *node)
{
if( NULL == node )
return ;
BinTreeNode *e = NULL;
LinkStack stack;
initStack(&stack);
push(&stack, node);
while (!isEmpty(stack))
{
getTop(stack, &e);
pop(&stack); //及时弹出
printf("%c", e->data);
if( NULL != e->rightChild ) //先入栈右孩子,以确保左孩子先被访问
push(&stack, e->rightChild);
if( NULL != e->leftChild )
push(&stack, e->leftChild);
}
}
void PreOrder(BinTree tree)
{
PreOrder_(tree.root);
printf("\n");
}
static void InOrder_(BinTreeNode *node)
{
if( NULL == node )
return ;
BinTreeNode *e = NULL, *p = node;
LinkStack stack;
initStack(&stack);
push(&stack, node);
while (!isEmpty(stack))
{
while (NULL != p && NULL != p->leftChild) //保证左子树先被访问
{
push(&stack, p->leftChild);
p = p->leftChild;
}
//已无可入栈左子树,可以访问根节点了
getTop(stack, &e);
pop(&stack);
printf("%c", e->data);
//当前子树的右子树可能不存在
if( NULL != e->rightChild ) //存在则将其右子树入栈,回到while循环保证右子树的所有左子树先被访问
{
push(&stack, e->rightChild);
p = e->rightChild;
}
}
}
void InOrder(BinTree tree)
{
InOrder_(tree.root);
printf("\n");
}
//main.cpp
#include "LinkBinTree.h"
int main(int argc, char **argv)
{
//const char *str = "ABC##DE##F##G#H##";
BinTree tree;
InitBinTree(&tree, '#');
CreateBinTree_input(&tree);
LevelOrder(tree);
PreOrder(tree);
InOrder(tree);
return 0;
}
//LinkQueue.h
#ifndef _LINKQUEUE_H_
#define _LINKQUEUQ_H_
#include
#include "LinkBinTree.h"
typedef BinTreeNode *ElementType;
typedef struct QueueNode
{
ElementType data;
struct QueueNode *next;
}QueueNode;
typedef struct LinkQueue
{
QueueNode *first;
int size;
QueueNode *last;
}LinkQueue;
bool InitQueue(LinkQueue *lq);
bool EnQueue(LinkQueue *lq, ElementType e);
bool DeQueue(LinkQueue *lq);
void Show(LinkQueue lq);
bool GetTop(LinkQueue lq, ElementType *e);
int Length(LinkQueue lq);
bool IsEmpty(LinkQueue lq);
void Clear(LinkQueue *lq);
void Destroy(LinkQueue *lq);
#endif //_LINKQUEUE_H_
#include "LinkQueue.h"
#include
#include
static QueueNode *CreateNode(ElementType e)
{
QueueNode *p = (QueueNode *)malloc(sizeof(QueueNode));
if( NULL != p )
{
p->next = NULL;
p->data = e;
}
return p;
}
bool InitQueue(LinkQueue *lq)
{
QueueNode *p = CreateNode(NULL);
if( NULL == p )
return false;
lq->first = lq->last = p;
lq->size = 0;
return true;
}
bool EnQueue(LinkQueue *lq, ElementType e)
{
QueueNode *p = CreateNode(e);
if( NULL == p )
return false;
lq->last->next = p;
lq->last = p;
lq->size++;
return true;
}
bool DeQueue(LinkQueue *lq)
{
if( IsEmpty(*lq) )
{
printf("队列为空\n");
return false;
}
QueueNode *p = lq->first->next;
lq->first->next = p->next;
if( NULL == p->next ) //p为最后一个节点
{
lq->last = lq->first; //令尾指针指向头结点
}
free(p);
lq->size--;
return true;
}
void Show(LinkQueue lq)
{
QueueNode *p = lq.first->next;
while(NULL != p)
{
printf("%p\n", p->data);
p = p->next;
}
}
bool GetTop(LinkQueue lq, ElementType *e)
{
if( NULL == lq.first->next )
{
printf("队列为空\n");
return false;
}
*e = lq.first->next->data;
return true;
}
int Length(LinkQueue lq)
{
return lq.size;
}
bool IsEmpty(LinkQueue lq)
{
return lq.first == lq.last;
}
void Clear(LinkQueue *lq)
{
if( NULL == lq->first->next )
{
return ;
}
QueueNode *p = lq->first->next;
while( NULL != p)
{
lq->first->next = p->next;
free(p);
p = lq->first->next;
}
lq->size = 0;
}
void Destroy(LinkQueue *lq)
{
Clear(lq);
free(lq->first);
lq->first = lq->last = NULL;
}
#ifndef _LINKSTACK_H_
#define _LINKSTACK_H_
#include
#include "LinkBinTree.h"
typedef BinTreeNode *ElementType;
typedef enum
{
false_,
true_
}bool_;
typedef struct StackNode
{
ElementType data;
struct StackNode *next;
}StackNode;
typedef struct LinkStack
{
int size;
StackNode *Node;
}LinkStack, *pLinkStack;
void initStack(LinkStack *st);
bool_ push(LinkStack *st, ElementType e);
bool_ pop(LinkStack *st);
void show(LinkStack st);
bool_ getTop(LinkStack st, ElementType *e);
bool_ isEmpty(LinkStack st);
int length(LinkStack st);
void destroy(LinkStack *st);
#endif //_LINKSTACK_H_
//LinkStack.c
#include "LinkStack.h"
#include
void initStack(LinkStack *st)
{
st->Node = NULL;
st->size = 0;
}
bool_ push(LinkStack *st, ElementType e)
{
StackNode *node = (StackNode *)malloc(sizeof(StackNode));
if( NULL == node )
{
printf("申请节点失败\n");
return false_;
}
node->data = e;
node->next = NULL;
node->next = st->Node;
st->Node = node;
st->size++;
return true_;
}
bool_ pop(LinkStack *st)
{
if( isEmpty(*st))
{
printf("栈已空\n");
return false_;
}
StackNode *p = st->Node;
st->Node = p->next;
free(p);
st->size--;
return true_;
}
void show(LinkStack st)
{
StackNode *p = st.Node;
while (NULL != p)
{
printf("%d\n", p->data);
p = p->next;
}
}
bool_ getTop(LinkStack st, ElementType *e)
{
if( isEmpty(st) )
{
printf("栈已空\n");
return false_;
}
*e = st.Node->data;
return true_;
}
bool_ isEmpty(LinkStack st)
{
return NULL == st.Node;
}
int length(LinkStack st)
{
return st.size;
}
void destroy(LinkStack *st)
{
if( NULL == st->Node )
return ;
StackNode *p = st->Node;
while(NULL != p)
{
st->Node = p->next;
free(p);
p = st->Node;
}
st->size = 0;
}