二叉樹鏈式儲存的實現
阿新 • • 發佈:2019-02-17
//filename:bitree.h #include <stdio.h> #include <stdlib.h> #include <malloc.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define NIL '#' //定義'#'為空節點 typedef struct queue_node qnode; typedef struct bitree_node bitree; struct bitree_node { char elem; bitree *lchild; bitree *rchild; }; /*佇列節點*/ struct queue_node { bitree *btn; qnode *next; }; typedef struct link_queue { qnode *head; qnode *tail; }queue; /*****佇列的基本操作******/ int init_link_queue(queue *Q); int is_queue_empty(queue Q); int enqueue(queue *Q, bitree *btn); int dequeue(queue *Q, char *elem); /*****二叉樹的操作*****/ bitree *create_bitree(); int is_bitree_empty(bitree *btn); int get_bitree_depth(bitree *btn); bitree *get_parent(bitree *btn, char elem); int preorder_traverse(bitree *btn, int (*visit)(char)); int inorder_traverse(bitree *btn, int (*visit)(char)); int postorder_traverse(bitree *btn, int (*visit)(char)); int levelorder_traverse(bitree *btn, int (*visit)(char)); int destory_bitree(bitree *btn); int print_elem(char elem);
//filename:queue.c #include "bitree.h" /* 功能:鏈佇列初始化 */ int init_link_queue(queue *Q) { qnode *tmp_node = (qnode *)malloc(sizeof(qnode)); if(!tmp_node) { return ERROR; } tmp_node->btn = NULL; tmp_node->next = NULL; Q->head = tmp_node; Q->tail = tmp_node; return OK; } /* 功能:佇列是否為空 返回:1 空;0 非空 */ int is_queue_empty(queue Q) { return ((Q.head == Q.tail) ? TRUE : FALSE); } /* 功能:元素num入隊 */ int enqueue(queue *Q, bitree *btn) { qnode *tmp_node = (qnode *)malloc(sizeof(qnode)); if(!tmp_node) { return ERROR; } tmp_node->next = NULL; tmp_node->btn = btn; Q->tail->next = tmp_node; Q->tail = tmp_node; return OK; } /* 功能:出隊,隊頭元素存入num 引數: Q 佇列; btn_addr 存放出隊節點內的bitree *地址 */ int dequeue(queue *Q, int *btn_addr) { qnode *tmp_node = NULL; if(is_queue_empty(*Q)) { return ERROR; } tmp_node = Q->head->next; Q->head->next = tmp_node->next; *btn_addr = tmp_node->btn; if(Q->head->next == NULL) { Q->tail = Q->head; } free(tmp_node); return OK; }
//filename:bitree.c #include "bitree.h" /* 功能:先序建立二叉樹 返回:建立的節點地址 */ bitree *create_bitree() { char elem; bitree *btn = NULL; fflush(stdin); //清空輸入緩衝流 scanf("%c", &elem); if(elem == NIL) { return btn; } else { btn = (bitree *)malloc(sizeof(bitree)); btn->elem = elem; btn->lchild = create_bitree(); btn->rchild = create_bitree(); return btn; } } /* 功能:判斷該二叉樹是否為空 返回:1 空; 0 非空 */ int is_bitree_empty(bitree *btn) { if(!btn) { return TRUE; } else { return FALSE; } } /* 功能:求二叉樹的深度 */ int get_bitree_depth(bitree *btn) { int i = 0; //記錄左子樹深度 int j = 0; //記錄右子樹深度 if(!btn) { return 0; } if(btn->lchild) { i = get_bitree_depth(btn->lchild); } else { i = 0; } if(btn->rchild) { j = get_bitree_depth(btn->rchild); } else { j = 0; } return (i > j) ? (i + 1) : (j + 1); } /* 功能:獲取元素elem節點的父結點 返回:如果elem為根,返回NULL; */ bitree *get_parent(bitree *btn, char elem) { int btn_addr = 0; bitree *father_node = NULL; queue Q; if(!btn) //樹為空 { return NULL; } init_link_queue(&Q); //初始化佇列 enqueue(&Q, btn); while(!is_queue_empty(Q)) //佇列不為空 { dequeue(&Q, &btn_addr); father_node = btn_addr; if((father_node->lchild && father_node->lchild->elem == elem) || (father_node->rchild && father_node->rchild->elem == elem)) { return father_node; } else { if(father_node->lchild) { enqueue(&Q, father_node->lchild); } if(father_node->rchild) { enqueue(&Q, father_node->rchild); } } } return NULL; } /* 功能:先序遍歷二叉樹 */ int preorder_traverse(bitree *btn, int (*visit)(char)) { if(!btn) { return OK; } visit(btn->elem); preorder_traverse(btn->lchild, visit); preorder_traverse(btn->rchild, visit); return OK; } /* 功能:中序遍歷二叉樹 */ int inorder_traverse(bitree *btn, int (*visit)(char)) { if(!btn) { return OK; } inorder_traverse(btn->lchild, visit); visit(btn->elem); inorder_traverse(btn->rchild, visit); return OK; } /* 功能:後序遍歷二叉樹 */ int postorder_traverse(bitree *btn, int (*visit)(char)) { if(!btn) { return OK; } postorder_traverse(btn->lchild, visit); postorder_traverse(btn->rchild, visit); visit(btn->elem); return OK; } /* 功能:按層序遍歷二叉樹,藉助佇列 */ int levelorder_traverse(bitree *btn, int (*visit)(char)) { int btn_addr = 0; //記錄出隊的佇列節點的(bitree *)的地址 bitree *bitree_node = NULL; queue Q; if(!btn) //樹為空 { return NULL; } init_link_queue(&Q); //初始化佇列 enqueue(&Q, btn); while(!is_queue_empty(Q)) //佇列不為空 { dequeue(&Q, &btn_addr); bitree_node = btn_addr; visit(bitree_node->elem); if(bitree_node->lchild) { enqueue(&Q, bitree_node->lchild); } if(bitree_node->rchild) { enqueue(&Q, bitree_node->rchild); } } return NULL; } /* 功能: 銷燬二叉樹 */ int destory_bitree(bitree *btn) { if(btn) { if(btn->lchild) { destory_bitree(btn->lchild); } if(btn->rchild) { destory_bitree(btn->rchild); } free(btn); btn = NULL; } return OK; } /* 功能:列印傳入的引數值 */ int print_elem(char elem) { printf("%c ", elem); return OK; }
//filename:test_bitree.c
#include "bitree.h"
/*
測試資料: 先序建立樹:abd###c##;
先序遍歷: abdc
中序遍歷: dbac
後序遍歷: dbca
*/
int main(int argc, char *argv[])
{
bitree *tmpnode = NULL;
bitree *bitree = NULL;
bitree = create_bitree();
preorder_traverse(bitree, print_elem);
printf("\n");
inorder_traverse(bitree, print_elem);
printf("\n");
postorder_traverse(bitree, print_elem);
printf("\n");
levelorder_traverse(bitree, print_elem);
printf("\n");
printf("the depth of the bitree is %d.\n", get_bitree_depth(bitree));
tmpnode = get_parent(bitree, 'd');
printf("the 'd' father node is:%c\n", tmpnode->elem);
destory_bitree(bitree);
system("pause");
return 0;
}