千家信息网

C语言中二叉树的常见操作是什么

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章主要讲解了"C语言中二叉树的常见操作是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"C语言中二叉树的常见操作是什么"吧!一、基本概念每个结
千家信息网最后更新 2026年11月04日C语言中二叉树的常见操作是什么

这篇文章主要讲解了"C语言中二叉树的常见操作是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"C语言中二叉树的常见操作是什么"吧!

一、基本概念

每个结点最多有两棵子树,左子树和右子树,次序不可以颠倒。

性质:

1、非空二叉树的第n层上至多有2^(n-1)个元素。

2、深度为h的二叉树至多有2^h-1个结点。

满二叉树:所有终端都在同一层次,且非终端结点的度数为2。

在满二叉树中若其深度为h,则其所包含的结点数必为2^h-1。

完全二叉树:除了最大的层次即成为一颗满二叉树且层次最大那层所有的结点均向左靠齐,即集中在左面的位置上,不能有空位置。

对于完全二叉树,设一个结点为i则其父节点为i/2,2i为左子节点,2i+1为右子节点。

二、存储结构

顺序存储:

将数据结构存在一块固定的数组中。

#define LENGTH 100typedef char datatype;typedef struct node{  datatype data;  int lchild,rchild;  int parent;}Node;Node tree[LENGTH];int length;int root;

虽然在遍历速度上有一定的优势,但因所占空间比较大,是非主流二叉树。二叉树通常以链式存储。

链式存储:

typedef char datatype;typedef struct BinNode{  datatype data;  struct BinNode* lchild;  struct BinNode* rchild;}BinNode;typedef BinNode* bintree;     //bintree本身是个指向结点的指针

三、二叉树的遍历

遍历即将树的所有结点访问且仅访问一次。按照根节点位置的不同分为前序遍历,中序遍历,后序遍历。

前序遍历:根节点->左子树->右子树

中序遍历:左子树->根节点->右子树

后序遍历:左子树->右子树->根节点

例如:求下面树的三种遍历

前序遍历:abdefgc

中序遍历:debgfac

后序遍历:edgfbca

四、遍历的实现

递归实现(以前序遍历为例,其他的只是输出的位置稍有不同)

void preorder(bintree t){  if(t){    printf("%c ",t->data);    preorder(t->lchild);    preorder(t->rchild);  }}

非递归的实现

因为当遍历过根节点之后还要回来,所以必须将其存起来。考虑到后进先出的特点,选用栈存储。数量确定,以顺序栈存储。

#define SIZE 100typedef struct seqstack{  bintree data[SIZE];  int tag[SIZE];  //为后续遍历准备的  int top;   //top为数组的下标}seqstack;void push(seqstack *s,bintree t){  if(s->top == SIZE){    printf("the stack is full\n");  }else{    s->top++;    s->data[s->top]=t;  }}bintree pop(seqstack *s){  if(s->top == -1){    return NULL;  }else{    s->top--;    return s->data[s->top+1];  }}

1、前序遍历

void preorder_dev(bintree t){  seqstack s;  s.top = -1;   //因为top在这里表示了数组中的位置,所以空为-1  if(!t){    printf("the tree is empty\n");  }else{    while(t || s.stop != -1){      while(t){  //只要结点不为空就应该入栈保存,与其左右结点无关         printf("%c ",t->data);        push(&s,t);        t= t->lchild;      }      t=pop(&s);      t=t->rchild;    }  }}

2、中序遍历

void midorder(bintree t){  seqstack s;  s.top = -1;  if(!t){    printf("the tree is empty!\n");  }else{    while(t ||s.top != -1){      while(t){        push(&s,t);        t= t->lchild;      }      t=pop(&s);      printf("%c ",t->data);      t=t->rchild;    }  }}

3、后序遍历

因为后序遍历最后还要要访问根结点一次,所以要访问根结点两次。采取夹标志位的方法解决这个问题。

这段代码非常纠结,对自己有信心的朋友可以尝试独立写一下。反正我是写了很长时间。逻辑不难,我画了一张逻辑图:

代码:

void postorder_dev(bintree t){  seqstack s;  s.top = -1;  if(!t){    printf("the tree is empty!\n");  }else{    while(t || s.top != -1){  //栈空了的同时t也为空。      while(t){        push(&s,t);        s.tag[s.top] = 0;  //设置访问标记,0为第一次访问,1为第二次访问        t= t->lchild;      }      if(s.tag[s.top] == 0){ //第一次访问时,转向同层右结点        t= s.data[s.top];  //左走到底时t是为空的,必须有这步!        s.tag[s.top]=1;        t=t->rchild;      }else {        while (s.tag[s.top] == 1){ //找到栈中下一个第一次访问的结点,退出循环时并没有pop所以为其左子结点          t = pop(&s);          printf("%c ",t->data);        }        t = NULL; //必须将t置空。跳过向左走,直接向右走      }    }  }}

4、层次遍历:即每一层从左向右输出

元素需要储存有先进先出的特性,所以选用队列存储。

队列的定义:

#define MAX 1000typedef struct seqqueue{  bintree data[MAX];  int front;  int rear;}seqqueue;void enter(seqqueue *q,bintree t){  if(q->rear == MAX){    printf("the queue is full!\n");  }else{    q->data[q->rear] = t;    q->rear++;  }}bintree del(seqqueue *q){  if(q->front == q->rear){    return NULL;  }else{    q->front++;    return q->data[q->front-1];  }}

遍历实现

void level_tree(bintree t){  seqqueue q;  bintree temp;  q.front = q.rear = 0;  if(!t){    printf("the tree is empty\n");    return ;  }  enter(&q,t);  while(q.front != q.rear){    t=del(&q);    printf("%c ",t->data);    if(t->lchild){      enter(&q,t->lchild);    }    if(t->rchild){      enter(&q,t->rchild);    }  }}

5、利用前序遍历的结果生成二叉树

//递归调用,不存点,想的时候只关注于一个点,因为还会回来的,不要跟踪程序运行,否则容易多加循环void createtree(bintree *t){  datatype c;  if((c=getchar()) == '#')    *t = NULL;  else{    *t = (bintree)malloc(sizeof(BinNode));    (*t)->data = c;    createtree(&(*t)->lchild);    createtree(&(*t)->rchild);  }}

6、二叉树的查找

bintree search_tree(bintree t,datatype x){  if(!t){    return NULL;  }  if(t->data == x){    return t;  }else{    if(!search_tree(t->lchild,x)){      return search_tree(t->rchild,x);    }    return t;  }}

7、统计结点个数

int count_tree(bintree t){  if(t){    return (count_tree(t->lchild)+count_tree(t->rchild)+1);  }  return 0;}

8、比较两个树是否相同

int is_equal(bintree t1,bintree t2){  if(!t1 && !t2){   //都为空就相等    return 1;  }  if(t1 && t2 && t1->data == t2->data){   //有一个为空或数据不同就不判断了    if(is_equal(t1->lchild,t2->lchild))      if(is_equal(t1->rchild,t2->rchild)){        return 1;      }  }  return 0;}

9、求二叉树的深度

int hight_tree(bintree t){  int h,left,right;  if(!t){    return 0;  }  left = hight_tree(t->lchild);  right = hight_tree(t->rchild);  h = (left>right?left:right)+1;  return h;}

感谢各位的阅读,以上就是"C语言中二叉树的常见操作是什么"的内容了,经过本文的学习后,相信大家对C语言中二叉树的常见操作是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

结点 子树 节点 存储 位置 常见 语言 层次 不同 数组 深度 第一次 递归 学习 最大 代码 元素 内容 数据 终端 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 有格互联网科技 新华互联网科技 广州大一互联网络科技有限公司 互联网佳科技有限公司 科技金融是不是互联网金融 互联网金融 金融科技 中国 科技 互联网 互联网科技公司怎么样 有马互联网科技 苏州大垚互联网科技 山东吉时兔互联网科技有限公司 现代科技和互联网有关系吗 栖莱科技互联网股份有限公司 湖北码尼互联网科技有限公司电话 武汉健翔互联网络科技有限公司 互联网与医疗科技 河南住房之家互联网科技 江苏苏星互联网科技有限公司 中国互联网公司的科技投入 广州三三互联网科技有限公司 上海睿民互联网科技有限公司 互联网是第几次科技革命的成果 科技互联网政务服务 互联网科技公司招聘 互联网教育科技公司vipkid 互联网科技公司实习生 链环科技传统企业怎么转型互联网 华中科技大学互联网的牛人 美国互联网科技实力 昆明中奇联合互联网科技
0