数据结构02二叉树的创建和方法

二叉树的多种创建方式和功能的实现 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);
  }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值