二叉树的实现
Posted CyExcel
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的实现相关的知识,希望对你有一定的参考价值。
实现二叉树前要先实现栈和队列。
二叉树、队列使用C语言编写。栈原先使用C语言编写,后修改成C++模板(简陋版),因此 this 指针是显式传入函数的,而且没有构造函数和析构函数。不过这样才是C++的本来面貌。
队列:linkqueue.h linkqueue.cpp
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);
#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
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;
}
二叉树:bintree.h bintree.cpp
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);
// 在树中查找 key
Node* 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);
// 初始化树
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;
}
}
// 在树中查找 key
Node* 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;
}
以上是关于二叉树的实现的主要内容,如果未能解决你的问题,请参考以下文章