#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define YES 1
#define NO 0
typedef int Status;
typedef char ElemType;
typedef struct BiTreeNode{
ElemType data;
struct BiTreeNode *lchild, *rchild;
}BiTreeNode, *BiTree;
typedef struct QueueNode{
BiTreeNode* binary_tree_node; //存放的"数据"是二叉树的节点的指针
struct QueueNode* next;
}QueueNode, *QueueNodePtr;
typedef struct LinkQueue{
QueueNodePtr front;
QueueNodePtr rear;
}LinkQueue, *Queue;
//创建头结点,初始化
Status InitQueue(Queue q){ //注意这里的参数不是Queue *q,因为不是要为q分配空间
//而是为了q中的front和rear
q->front = (QueueNode*)malloc(sizeof(struct QueueNode));
if( !q->front )
return ERROR;
q->rear = q->front;
q->front->next = NULL;
return OK;
}
//入队
Status EnterQueue(Queue q, BiTreeNode* binaryTreeNode){
QueueNode* new = (QueueNode*)malloc(sizeof(struct QueueNode));
if( !new )
return ERROR;
new->binary_tree_node = binaryTreeNode;
new->next = q->rear->next;
q->rear->next = new;
q->rear = new;
return OK;
}
//出队
Status DeleteQueue(Queue q, BiTreeNode** binaryTreeNode){
if( q->front == q->rear ){
printf("Queue Empty!\n");
return ERROR;
}
QueueNodePtr t;
t = q->front->next;
*binaryTreeNode = t->binary_tree_node;
q->front->next = t->next;
free(t);
if( t == q->rear )
q->rear = q->front;
return OK;
}
Status IsQueueEmpty(Queue q){
return q->front == q->rear ? OK : ERROR;
}
//test Queue
//int main(){
/* 测试 1
* 如何为指针分配空间,都是4?
* 下面的测试中出现了结构对齐的问题。
printf("%d\n",sizeof(ElemType));
printf("%d\n",sizeof(struct QueueNode*));
printf("%d\n",sizeof(QueueNode));
printf("%d\n",sizeof(QueueNodePtr));
printf("%d\n",sizeof(LinkQueue));
printf("%d\n",sizeof(Queue));
int *p;
printf("%d\n",sizeof(p));
*/
/* 测试 2 √
* 原来没有写下面这个函数,导致出错:
使用指针之前请保证它有合法值。
main里的三个指针都没有合法值。(from 优快云)
————————————————————————————————————————————————————————————
Status InitBinaryTreeNode(BiTree *T){
*T = (BiTreeNode*)malloc(sizeof(struct BiTreeNode));
if( !*T )
return ERROR;
return OK;
}
————————————————————————————————————————————————————————————
LinkQueue* q;
InitQueue(q);
BiTree p;
InitBinaryTreeNode(&p);
p->data = 'a';
printf("%c ",p->data);
BiTree t;
InitBinaryTreeNode(&t);
t->data = 'c';
printf("%c ",t->data);
*/
/* 测试 3
LinkQueue* q;
InitQueue(q);
BiTreeNode *p,*r;
InitBinaryTreeNode(&p);
InitBinaryTreeNode(&r);
p->data = 'a';
printf("%c \n",p->data);
EnterQueue(q,p);
DeleteQueue(q,&r);
printf("%c \n",r->data);
// return OK;
}
//test Queue end
*/
//初始化二叉树,在要创建二叉树之前调用
Status InitBiTree(BiTree *T){
*T = NULL;
return OK;
}
//初始化二叉树节点。单个节点使用的时候调用此函数,不然指针会成为野指针
Status InitBinaryTreeNode(BiTree *T){
*T = (BiTreeNode*)malloc(sizeof(struct BiTreeNode));
if( !*T )
return ERROR;
return OK;
}
//使用前序遍历的结构进行二叉树的创建
Status CreateBiTree_PreOrder(BiTree* T){
ElemType c;
scanf("%c", &c);
if( ' ' == c ){
*T = NULL;
}
else{
*T = (BiTree)malloc(sizeof(struct BiTreeNode));
if( !*T )
return ERROR;
(*T)->data = c;
CreateBiTree_PreOrder(&(*T)->lchild);
CreateBiTree_PreOrder(&(*T)->rchild);
}
return OK;
}
void visit(ElemType c,int level){
printf(" %c level is:%d\n", c, level);
}
void visit_2(ElemType c){
printf("%c ", c);
}
//递归的前序遍历二叉树
Status PreOrderTraverse(BiTree T,int level){
if( T ){
visit(T->data,level);
PreOrderTraverse(T->lchild,level + 1);
PreOrderTraverse(T->rchild,level + 1);
}
return OK;
}
//递归的中序遍历二叉树
Status InOrderTraverse(BiTree T,int level){
if( T ){
InOrderTraverse(T->lchild,level + 1);
visit(T->data,level);
InOrderTraverse(T->rchild,level + 1);
}
return OK;
}
//递归的后序遍历二叉树
Status PostOrderTraverse(BiTree T,int level){
if( T ){
PostOrderTraverse(T->lchild,level + 1);
PostOrderTraverse(T->rchild,level + 1);
visit(T->data,level);
}
return OK;
}
//层序遍历二叉树<<非递归>>
//要进行层序遍历需要借助于队列的辅助:先将二叉树的根入队列,然后将其
//出队列,visit。如果该根有左孩子,则入队;如果该根有右孩子,则入队。
//然后出队,对该出队的节点进行以上的相同的访问。直到对空
Status LevelOrderTraverse(BiTree T){
LinkQueue *q = (LinkQueue*)malloc(sizeof(LinkQueue)); /*有几次代码出错都是
因为这个,指针q没有
指向。
*/
InitQueue(q);
BiTreeNode* nodePtr;
InitBinaryTreeNode(&nodePtr);
EnterQueue(q,T);
while( !IsQueueEmpty(q) ){
DeleteQueue(q, &nodePtr);
visit_2(nodePtr->data);
if( nodePtr->lchild != NULL ){
EnterQueue(q,nodePtr->lchild);
}
if( nodePtr->rchild != NULL ){
EnterQueue(q,nodePtr->rchild);
}
}
return OK;
}
//判断二叉树是否为空
Status IsTreeEmpty(BiTree T){
return T == NULL ? OK : ERROR;
}
//计算二叉树的深度
int BiTreeDepth(BiTree T){
int i = 0,j = 0;
if( !T )
return 0;
if( T->lchild )
i = BiTreeDepth(T->lchild);
else
i = 0;
if( T->rchild )
j = BiTreeDepth(T->rchild);
else
j = 0;
return i>j ? i+1 : j+1;
}
/* 判断一棵二叉树是否是完全二叉树:
* 思路: 借助于队列,先将root入队,当队列不为空的时候,出队一个元素。如果节点不为空,
* 则将该节点的左孩子和右孩子入队;如果节点为空,则查找后序出队的元素中是否全
* 是NULL,否则就不是完全二叉树
* */
Status IsCompleteBinaryTree(BiTree T){
Queue q = (Queue)malloc(sizeof(struct QueueNode));
if( !q )
return ERROR;
InitQueue(q);
BiTree node;
InitBinaryTreeNode(&node);
EnterQueue(q, T);
while( IsQueueEmpty(q) != OK ){
DeleteQueue(q, &node);
if( node != NULL ){
EnterQueue(q, node->lchild);
EnterQueue(q, node->rchild);
}
else{
while( IsQueueEmpty(q) != OK ){
DeleteQueue(q, &node);
if( node != NULL )
return NO;
}
}
}
return YES;
}
int main(){
int level = 1;
BiTree BT;
InitBiTree(&BT);
if(IsTreeEmpty(BT))
printf("Binary is Empty!\n");
else
printf("Exist Element in Tree\n");
printf("Create Binary Tree by PreOrder: ");
CreateBiTree_PreOrder(&BT);
printf("PreOrder Traverse: \n");
PreOrderTraverse(BT,level);
printf("InOrder Traverse: \n");
InOrderTraverse(BT,level);
printf("PostOrder Traverse: \n");
PostOrderTraverse(BT,level);
printf("LevelOrder Traverse: \n");
LevelOrderTraverse(BT);
printf("\nthe Depth of Binary is %d\n",BiTreeDepth(BT));
if(IsCompleteBinaryTree(BT) == YES )
printf("Complete Binary Tree!\n");
else
printf("no-Complete Binary Tree!\n");
return 0;
}
二叉树的链式存储结构 前序 后序 中序 层序遍历操作实现 判断是否完全二叉树
最新推荐文章于 2024-03-21 16:37:15 发布
610

被折叠的 条评论
为什么被折叠?



