二叉树的多种创建方式和功能的实现 c语言
提示:文章内容为小白所写,会有借鉴别人代码的地方。
文章目录
前言
提示:这篇文章主要有二叉树的多种创建方式及不同功能的实现。会引入栈和队列的头文件。(文件内容会一开始展示出来,请自行创建)同时再每一种方法我会单独列出来,并作注释。可供参考。
提示:以下是本篇文章正文内容,下面案例可供参考
一、引入二叉树自定义的头文件
栈和队列的头文件,再后续引入是分别称为stack.h和queue.h
1.stack.h
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
typedef char elemtype;
typedef struct bintreenode
{
elemtype data;
struct bintreenode *leftchild;
struct bintreenode *rightchild;
}bintreenode,*binlink;
#define Elemtype binlink
typedef struct snode {
Elemtype data;
struct snode* next;
}snode, * linkstack;
typedef struct snode_ {
Elemtype data;
struct snode_* next;
}snode_, * linkstack_;
void initstack(linkstack& s);
void pushstack(linkstack& s, Elemtype x);
void popstack(linkstack& s, Elemtype& x);
void pushstack_(linkstack_& s, Elemtype x);
void popstack_(linkstack_& s, Elemtype& x);
void printfstack(linkstack s);
int isempty(linkstack &s);
void initstack(linkstack& s)
{
s = (linkstack)malloc(sizeof(snode));
s->next = NULL;
//s = NULL;
}
void pushstack(linkstack& s, Elemtype x)
{
linkstack p = (linkstack)malloc(sizeof(snode));
p->data = x;
p->next = s;
s = p;
}
void pushstack_(linkstack_& s, Elemtype x)
{
linkstack_ p = (linkstack_)malloc(sizeof(snode_));
p->data = x;
p->next = s;
s = p;
}
void popstack(linkstack& s, Elemtype& x)
{
linkstack p = s;
x = p->data;
if(s->next==NULL)
{
s->next = NULL;
}
else {
s = s->next;
}
free(p);
}
void popstack_(linkstack_& s, Elemtype& x)
{
linkstack_ p = s;
x = p->data;
if (s->next == NULL)
{
s->next = NULL;
}
else {
s = s->next;
}
free(p);
}
int isempty(linkstack &s)
{
if(s->next==NULL)
{
return 1;
}
else
{
return 0;
}
}
void printfstack(linkstack s)
{
if(s->next!=NULL)
{
printfstack(s->next);
binlink bt=s->data;
printf("%c",bt->data);
}
}
2.queue.h
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
#include<string.h>
struct bintreenode;
#define qelemtype bintreenode*
typedef struct qnode
{
qelemtype data;
struct qnode *next;
}qnode,*qlink;
typedef struct
{
qlink front;
qlink rear;
}linkqueue;
void initqueue(linkqueue &q);
int isempty(linkqueue q);
void pushqueue(linkqueue &q,qelemtype e);
void popqueue(linkqueue &q,qelemtype &e);
void initqueue(linkqueue &q)
{
q.front=q.rear=(qlink)malloc(sizeof(qnode));
q.front->next=NULL;
}
void pushqueue(linkqueue &q,qelemtype e)
{
qlink p;
p=(qlink)malloc(sizeof(qnode));
p->data=e;
p->next=NULL;
q.rear->next=p;
q.rear=p;
}
void popqueue(linkqueue &q,qelemtype &e)
{
if(q.front==q.rear)
{
printf("队为空,没有可以删除的");
}
else
{
qlink p=q.front->next;
e=p->data;
q.front->next=p->next;
if(q.rear==p)
q.rear=q.front;
free(p);
}
}
int isempty(linkqueue q)
{
if(q.front==q.rear)
return 1;
else
return 0;
}
二、二叉树的创建
1. 定义结构体
typedef struct bintree
{
binlink root;
elemtype refvalue;//stop flag
}bintree;
2.初始化二叉树
void initbintree(bintree *bt,elemtype ref){
bt->root=NULL;
bt->refvalue=ref;
}
3.创建二叉树
void createbintree(bintree *bt,elemtype *str)
{
createbintree(bt,bt->root,str);
}
void createbintree(bintree *bt,binlink &t,elemtype *&str)
{
if(*str==bt->refvalue)
{
t=NULL;
}
else
{
t=(binlink)malloc(sizeof(bintreenode));
assert(t!=NULL);
t->data=*str;
createbintree(bt,t->leftchild,++str);
createbintree(bt,t->rightchild,++str);
}
}
三、二叉树的功能的实现
1.遍历二叉树
递归遍历:
1.先序遍历
void preorder(bintree *bt)
{
printf("preorder:");
preorder(bt->root);
}
void preorder(binlink t)
{
if(t!=NULL)
{
printf("%c",t->data);
preorder(t->leftchild);
preorder(t->rightchild);
}
}
2.中序遍历
void inorder(bintree *bt)
{
printf("inorder:");
preorder(bt->root);
}
void inorder(binlink t)
{
if(t!=NULL)
{
inorder(t->leftchild);
printf("%c",t->data);
inorder(t->rightchild);
}
}
3.后序遍历
void postorder(bintree *bt)
{
printf("postorder:");
preorder(bt->root);
}
void postorder(binlink t)
{
if(t!=NULL)
{
postorder(t->leftchild);
printf("%c",t->data);
postorder(t->rightchild);
}
}
非递归遍历:
1.先序遍历
void preorder_1(bintree *bt)
{
printf("preorder_1:");
preorder_1(bt->root);
}
void preorder_1(binlink t)
{
if(t!==NULL)
{
linkstack st;
initstack st;
binlink p;
pushstack(st,t);
while(!isempty(st))
{
popstack(st,p);
printf("%c",p->data);
if(p->rightchild!=NULL)
pushstack(st,p->rightchild);
if(p->leftchild!=NULL)
pushstack(st,p->leftchild);
}
}
2.中序遍历
void inorder_1(bintree *bt)
{
printf("inorder_1:");
preorder_1(bt->root);
}
void inorder_1(binlink t)
{
if(t!==NULL)
{
linkstack st;
initstack(st);
binlink p;
pushstack(st,t);
while(!isempty(st))
{
while(t->leftchild!=NULL)
{
pushstack(st,t->leftchild);
t=t->leftchild;
}
popstack(st,p);
printf("%c",p->data);
if(p->rightchild!=NULL)
{
t=p->rightchild;
pushstack(st,t);
}
}
3.后序遍历
因为在涉及到后序遍历的内容中的stack.h需要做修改,所以后序遍历的内容我会单独拿出来写一篇,大家可以翻看我的主页查找。
层次遍历
void levelorder(bintree *bt)
{
printf("层次遍历:");
levelorder(bt->root);
}
void levelorder(binlink t)
{
binlink bt;
linkqueue qt;
initqueue(qt);
pushqueue(qt,t);
while(!isempty(qt))
{
popqueue(qt,bt);
printf("%c",bt->data);
if(bt->leftchild!=NULL)
pushqueue(qt,bt->leftchild);
if(bt->rightchild!=NULL)
pushqueue(qt,bt->rightchild);
}
}
2.查找二叉树的深度
int height(bintree *bt)
{
return height(bt->root);
}
int height(binlink t)
{
int i=0;
if(t!=NULL)
{
i=height(t->leftchild)>height(t->rightchild)?height(t->leftchild):height(t->rightchild);
i+=1;
}
return i;
}
3.查找二叉树的个数
int size(bintree *bt)
{
return size_(bt->root);
}
int size_(binlink t)
{
int i=0;
if(t!=NULL)
{
i++;
i+=size_(t->leftchild);
i+=size_(t->rightchild);
}
return i;
}
4.查找二叉树的指定节点
binlink search(bintree *bt,elemtype key)
{
return search(bt->root,key);
}
binlink search(binlink t,elemtype key)
{
if(t==NULL)
{
return NULL;
}
if(t->data==key)
{
return t;
}
binlink p=search(t->leftchild,key);
if(p!=NULL)
{
return p;
}
else{
return search(t->rightchild,key);
}
}
5.复制二叉树
void copy(bintree *bt1,bintree *bt2)
{
copy(bt1->root,bt2->root);
}
void copy(binlink &t1,binlink t2)
{
if(t2!=NULL)
{
t1=(binlink)malloc(sizeof(bintreenode));
t1->data=t2->data;
copy(t1->leftchild,t2->leftchild);
copy(t1->rightchild,t2->rightchild);
}else{
t1=NULL;
}
}
6.凹入输出二叉树
void disbintree(bintree *bt)
{
printf("凹入表显示二叉树");
printf("\n");
disbintree(bt->root,1);
}
void disbintree(binlink t,int level)
{
if(t)
{
for(int i=1;i<level;i++)
putchar(' ');
printf("%c",t->data);
for(int j=i+1;j<20;j++)
putchar('-');
putchar('\n');
disbintree(t->leftchild,level+2);
disbintree(t->rightchild,level+2);
}
}
7.输出所有叶子节点的路径
void bintreepath(bintree *bt)
{
printf("叶子节点的路径为:");
linkstack s;
initstack(s);
bintreepath(bt->root,s);
}
void bintreepath(binlink t,linkstack &s)
{
if(t)
{
pushstack(s,t);
if(!t->leftchild&&!t->rightchild)
{
printfstack(s);
printf("\n");
}
else
{
bintreepath(t->leftchild,s);
bintreepath(t->rightchild,s);
}
Elemtype x;
popstack(s,x);
}
}