二叉树的实现

Posted CyExcel

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的实现相关的知识,希望对你有一定的参考价值。

    实现二叉树前要先实现栈和队列。

    二叉树、队列使用C语言编写。栈原先使用C语言编写,后修改成C++模板(简陋版),因此 this 指针是显式传入函数的,而且没有构造函数和析构函数。不过这样才是C++的本来面貌。



队列:linkqueue.h linkqueue.cpp

#ifndef __LINKQUEUE_H__#define __LINKQUEUE_H__
#include "cc.h"
struct BinTreeNode;
#define Type struct BinTreeNode*
typedef struct QueueNode{ Type data; struct QueueNode* next;} QueueNode;
typedef struct QueueLink{ struct QueueNode* front; struct QueueNode* tail; size_t size;} LinkQueue;
typedef struct QueueLink List;
// 初始化表void InitList(List* Q);
// 显示表void show(List* Q);
// 判断是否为空bool QueueIsEmpty(List* Q);
// 插入void Push(List* Q,Type val);
// 删除void Pop(List* Q);
// 获得长度size_t getSize(List* Q);
// 获得队头Type getHead(List* Q);
// 清空void clear(List* Q);
// 销毁表 void destroy(List* Q);
// 创建新节点QueueNode* NewNode(Type val);
#endif
#include "linkqueue.h"
// 初始化表void InitList(List* Q){ QueueNode* head = (QueueNode*)malloc(sizeof(QueueNode)); if (head == NULL) return;
head->next = NULL; Q->front = Q->tail = head;
Q->size = 0;}
// 判断是否为空bool QueueIsEmpty(List* Q){ return Q->front == Q->tail;}
// 创建新节点QueueNode* NewNode(Type val){ QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode)); if (newnode == NULL) return NULL;
newnode->data = val;
return newnode;}
// 显示表void show(List* Q){ QueueNode* p = Q->front->next; while (p != NULL) { printf("%d-->",p->data); p = p->next; } puts("null");}
// 插入void Push(List* Q,Type val){ QueueNode* node = NewNode(val); if (node == NULL) return;
Q->tail->next = node; Q->tail = node;
Q->size++;}
// 删除void Pop(List* Q){ if (Q->size == 0) return;
QueueNode* p = Q->front->next; Q->front->next = p->next; free(p); if (Q->size == 1) Q->tail = Q->front;
Q->size--;}// 获得长度size_t getSize(List* Q){ return Q->size;}
// 获得队头Type getHead(List* Q){ return Q->front->next->data;}
// 清空void clear(List* Q){ if (Q->size == 0) return;
QueueNode* p = Q->front->next; QueueNode* temp = NULL; while (p != NULL) { temp = p; p = p->next; Q->front->next = p; free(temp); }
Q->tail = Q->front; Q->size = 0;}
// 销毁表 void destroy(List* Q){ clear(Q);
free(Q->front);
Q->front = Q->tail = NULL; Q->size = 0;}



栈:SeqStack.hpp

#ifndef __SEQSTACK_H__#define __SEQSTACK_H__
#include "cc.h"
#define STACK_INIT_SIZE 8#define STACK_INC_SIZE 3
template<typename T>struct SeqStack{ T* base; int capacity; int top;
bool Inc(struct SeqStack *s); void InitStack(struct SeqStack *s); bool IsFull(struct SeqStack *s); bool IsEmpty(struct SeqStack *s); void Push(struct SeqStack *s, T x); void Pop(struct SeqStack *s); bool GetTop(struct SeqStack *s, T* v); void Show(struct SeqStack *s); int Length(struct SeqStack *s); void Clear(struct SeqStack *s); void Destroy(struct SeqStack *s);};
template<typename T>void SeqStack<T>::InitStack(SeqStack *s){ s->base = (T*)malloc(sizeof(T)*STACK_INIT_SIZE); assert(s->base != NULL); s->capacity = STACK_INIT_SIZE; s->top = 0;}
template<typename T>bool SeqStack<T>::Inc(struct SeqStack *s){ T* newbase = (T*)realloc(s->base, sizeof(T)*(s->capacity + STACK_INC_SIZE)); if (newbase == NULL) { printf("内存不足,无法申请空间.\n"); return false; } s->base = newbase; s->capacity += STACK_INC_SIZE; return true;}
template<typename T>bool SeqStack<T>::IsFull(struct SeqStack *s){ return s->top >= s->capacity;}
template<typename T>bool SeqStack<T>::IsEmpty(struct SeqStack *s){ return s->top == 0;}
template<typename T>void SeqStack<T>::Push(struct SeqStack *s, T x){ if (IsFull(s) && !Inc(s)) { printf("栈空间已满,%d 不能入栈.\n", x); return; }
s->base[s->top++] = x; //s->top++;}
template<typename T>void SeqStack<T>::Pop(struct SeqStack *s){ if (IsEmpty(s)) { printf("栈空间已空,不能出栈.\n"); return; }
s->top--;}
template<typename T>bool SeqStack<T>::GetTop(struct SeqStack *s,T* v){ if (IsEmpty(s)) { printf("栈空间已空,不能取栈顶元素.\n"); return NULL; }
*v = s->base[s->top - 1]; return true;}
template<typename T>void SeqStack<T>::Show(struct SeqStack *s){ for (int i = s->top - 1; i >= 0; --i) { printf("%d\n", s->base[i]); } printf("\n");}
template<typename T>int SeqStack<T>::Length(struct SeqStack *s){ return s->top;}
template<typename T>void SeqStack<T>::Clear(struct SeqStack *s){ s->top = 0;}
template<typename T>void SeqStack<T>::Destroy(struct SeqStack *s){ free(s->base); s->base = NULL; s->capacity = s->top = 0;}#endif



二叉树:bintree.h bintree.cpp

#ifndef __BINTREE_H__#define __BINTREE_H__

#include "linkqueue.h"#include "SeqStack.hpp"
#define ElemType char
typedef struct BinTreeNode{ ElemType data; struct BinTreeNode* left; struct BinTreeNode* right;}Node;
typedef struct BinTree{ ElemType stop; struct BinTreeNode* root;}Tree;
// 初始化树void InitBinTree(Tree* tree, ElemType stop);
// 递归创建树void CreateBinTree(Tree* tree, char* str);void CreateBinTree(Tree* tree,Node** node, char* &str);
// 根据先序和中序恢复二叉树void RestoreBinTree_PM(Tree* tree, ElemType* VLR, ElemType* LVR, size_t n);void RestoreBinTree_PM(Node* &node, ElemType* VLR, ElemType* LVR, size_t n);
// 根据后序和中序恢复二叉树void RestoreBinTree_MS(Tree* tree, ElemType* LVR, ElemType* LRV, size_t n);void RestoreBinTree_MS(Node* &node, ElemType* LVR, ElemType* LRV, size_t n);
// 先序遍历void preAcc(Tree* tree);void preAccess(Node* node);
// 中序遍历void midAcc(Tree* tree);void midAccess(Node* node);
// 后序遍历void subAcc(Tree* tree);void subAccess(Node* node);
// 层次遍历void levelAcc(Tree* tree);void levelAccess(Node* node);
// 先序非递归遍历void pre_Acc(Tree* tree);void pre_Access(Node* node);
// 中序非递归遍历void mid_Acc(Tree* tree);void mid_Access(Node* node);
// 后序非递归遍历void sub_Acc(Tree* tree);void sub_Access(Node* node);
// 求节点个数int Size(Tree* tree);int Size(Node* node);
// 求树的高度(层次)int Height(Tree* tree);int Height(Node* node);
// 在树中查找 keyNode* Search(Tree* tree,ElemType key);Node* Search(Node* node,ElemType key);
// 查找指定节点的父节点Node* SearchParent(Tree* tree,Node* p);Node* SearchParent(Node* node,Node* p);
// 查找指定节点的左子节点Node* Left(Node* p);
// 查找指定节点的左子节点Node* Right(Node* p);
// 判断是否为空树bool TreeIsEmpty(Tree* tree);
// 拷贝树void Copy(Tree* dest,Tree* src);void Copy(Node* &dest,Node* src);
// 清除树void TreeClear(Tree* tree);void TreeClear(Node* &node);
#endif
#include "bintree.h"
// 初始化树void InitBinTree(Tree* tree, ElemType stop){ tree->root = NULL; tree->stop = stop;}
// 递归创建树void CreateBinTree(Tree* tree, char* str){ CreateBinTree(tree,&(tree->root),str);}
void CreateBinTree(Tree* tree, Node** node, char* &str){ if (node == NULL) return; if (tree->stop == *str) *node = NULL; else { *node = (Node*)malloc(sizeof(Node)); if (*node == NULL) return; (*node)->data = *str; CreateBinTree(tree,&( (*node)->left),++str); CreateBinTree(tree,&( (*node)->right),++str); }}
// 根据先序和中序恢复二叉树void RestoreBinTree_PM(Tree* tree, ElemType* VLR, ElemType* LVR, size_t n){ RestoreBinTree_PM(tree->root,VLR,LVR,n);}
void RestoreBinTree_PM(Node* &node, ElemType* VLR, ElemType* LVR, size_t n){ if (n == 0) { node = NULL; return; }
int i = 0; while (VLR[0] != LVR[i]) { if (i > n) return; i++; }
node = (Node*)malloc(sizeof(Node)); if (node == NULL) return;
node->data = LVR[i]; RestoreBinTree_PM(node->left,VLR+1,LVR,i); RestoreBinTree_PM(node->right,VLR+i+1,LVR+i+1,n-i-1);}
// 根据后序和中序恢复二叉树void RestoreBinTree_MS(Tree* tree, ElemType* LVR, ElemType* LRV, size_t n){ RestoreBinTree_MS(tree->root,LVR,LRV,n);}
void RestoreBinTree_MS(Node* &node, ElemType* LVR, ElemType* LRV, size_t n){ if (n == 0) { node = NULL; return; }
int i = 0; while (LRV[n-1] != LVR[i]) { if (i > n) return; i++; }
node = (Node*)malloc(sizeof(Node)); if (node == NULL) return;
node->data = LVR[i]; RestoreBinTree_MS(node->right,LVR+i+1,LRV+i,n-i-1); RestoreBinTree_MS(node->left,LVR,LRV,i);}
// 先序遍历void preAcc(Tree* tree){ preAccess(tree->root);}
void preAccess(Node* node){ if (node == NULL) return;
printf("%c",node->data); if (node->left != NULL) preAccess(node->left); if (node->right != NULL) preAccess(node->right);}
// 中序遍历void midAcc(Tree* tree){ midAccess(tree->root);}
void midAccess(Node* node){ if (node == NULL) return;
if (node->left != NULL) midAccess(node->left); printf("%c",node->data); if (node->right != NULL) midAccess(node->right);}
// 后序遍历void subAcc(Tree* tree){ subAccess(tree->root);}
void subAccess(Node* node){ if (node == NULL) return; if (node->left != NULL) subAccess(node->left); if (node->right != NULL) subAccess(node->right); printf("%c",node->data);}
// 层次遍历void levelAcc(Tree* tree){ levelAccess(tree->root);}
void levelAccess(Node* node){ if (node == NULL) return;
struct QueueLink Q; InitList(&Q); Push(&Q,node);
Node* p = NULL; while (!QueueIsEmpty(&Q)) { p = getHead(&Q); printf("%c",p->data); Pop(&Q);
if (p->left != NULL) Push(&Q,p->left); if (p->right != NULL) Push(&Q,p->right); }
destroy(&Q); p = NULL;}
// 先序非递归遍历void pre_Acc(Tree* tree){ pre_Access(tree->root);}
void pre_Access(Node* node){ if (node == NULL) return;
SeqStack<Node*> s; s.InitStack(&s); s.Push(&s,node);
Node* p = node; while (!s.IsEmpty(&s)) { s.GetTop(&s,&p); printf("%c",p->data); s.Pop(&s);
if (p->right != NULL) s.Push(&s,p->right); if (p->left != NULL) s.Push(&s,p->left); }
s.Destroy(&s); p = NULL;}
// 中序非递归遍历void mid_Acc(Tree* tree){ mid_Access(tree->root);}
void mid_Access(Node* node){ if (node == NULL) return;
SeqStack<Node*> s; s.InitStack(&s); s.Push(&s,node);
Node* p = node; Node* q = NULL; while (!s.IsEmpty(&s)) { while (p != NULL && p->left != NULL) { s.Push(&s,p->left); p = p->left; }
s.GetTop(&s,&q); printf("%c",q->data); s.Pop(&s);
if (q->right != NULL) { s.Push(&s,q->right); p = q->right; } }
s.Destroy(&s); p = q = NULL;}
// 后序非递归遍历void sub_Acc(Tree* tree){ sub_Access(tree->root);}
void sub_Access(Node* node){ if (node == NULL) return;
typedef enum {A,B} Flag;
typedef struct Snode { Node* ptr; Flag flag; }Snode;
Snode sn; memset(&sn,0,sizeof(struct Snode));
SeqStack<Snode> s; s.InitStack(&s);
bool sign = true; Node* p = node;
do { while (p != NULL) { sn.ptr = p; sn.flag = A; s.Push(&s,sn); p = p->left; }
sign = true;
while (sign && !s.IsEmpty(&s)) { s.GetTop(&s,&sn); s.Pop(&s);
switch (sn.flag) { case A: sn.flag = B; p = (sn.ptr)->right; sign = false; s.Push(&s,sn); break; case B: printf("%c",(sn.ptr)->data); break; default: break; } } } while (!s.IsEmpty(&s));
s.Destroy(&s); p = NULL;}
// 求节点个数int Size(Tree* tree){ return Size(tree->root);}
int Size(Node* node){ if (node == NULL) return 0;
return Size(node->left) + Size(node->right) + 1;}
// 求树的高度(层次)int Height(Tree* tree){ return Height(tree->root);}
int Height(Node* node){ if (node == NULL) return 0;
int left = 0; int right = 0;
left = Height(node->left); right = Height(node->right); if (left > right) return left + 1; else { return right + 1; }}
// 在树中查找 keyNode* Search(Tree* tree, ElemType key){ return Search(tree->root,key);}
Node* Search(Node* node, ElemType key){ if (node == NULL) return NULL; if (node->data == key) return node;
Node* p = NULL; p = Search(node->left,key); if (p != NULL) return p; else { return Search(node->right,key); }
p = NULL;}
// 查找指定节点的父节点Node* SearchParent(Tree* tree, Node* p){ return SearchParent(tree->root,p);}
Node* SearchParent(Node* node, Node* p){ if (node == NULL) return NULL; if (node->left == p || node->right == p || node == p) return node;
Node* ret = NULL; ret = SearchParent(node->left,p); if (ret != NULL) return ret; else { return SearchParent(node->right,p); } ret = NULL;}
// 查找指定节点的左子节点Node* Left(Node* p){ if (p == NULL) return NULL; return p->left;}
// 查找指定节点的左子节点Node* Right(Node* p){ if (p == NULL) return NULL; return p->right;}
// 判断是否为空树bool TreeIsEmpty(Tree* tree){ return tree->root == NULL;}
// 拷贝树void Copy(Tree* dest, Tree* src){ Copy(dest->root,src->root);}
void Copy(Node* &dest, Node* src){ if (src == NULL) { dest == NULL; return; }
dest = (Node*)malloc(sizeof(Node)); if (dest == NULL) return; dest->data = src->data; Copy(dest->left,src->left); Copy(dest->right,src->right);}
// 清除树void TreeClear(Tree* tree){ TreeClear(tree->root);}
void TreeClear(Node* &node){ if (node == NULL) return;
TreeClear(node->left); TreeClear(node->right); free(node); node = NULL;}


以上是关于二叉树的实现的主要内容,如果未能解决你的问题,请参考以下文章

二叉树的代码实现

二叉树的非递归遍历怎么写?

二叉树(2.二叉树的遍历和实现)

Python数据结构系列☀️《树与二叉树-基础知识》——知识点讲解+代码实现☀️

python代码实现二叉树的镜像树

python代码实现二叉树的分层打印