AIGC标识 数据结构(借鉴408)-树与二叉树

数据结构 树和二叉树

树

树的性质

存储形式

  • 双亲表示法
  • 孩子兄弟表示法
  • 孩子链表表示法

二叉树

有序树

二叉树的性质

  • 顺序存储结构 数组 一般只有完全二叉树才采用顺序结构进行存储

  • 链式存储结构

    //二叉树的链式存储结构
    typedef struct BTNode{
    ElemType data;
    struct BTNode *Lchild, *Rchild;
    }BTNode;

二叉树的遍历

  • 先序遍历
  • 中序遍历
  • 后序遍历
  • 层次遍历

先序遍历是入栈前访问
中序遍历是出栈之后访问

二叉树的生成:中序遍历区分左右子树,先序、后序、层次确定根

先序遍历

//递归 系统栈
void PreorderTraverse(BTNode *T){
if(T == NULL) return; //访问根结点
printf(T->data);
PreorderTraverse(T->Lchild);
PreorderTraverse(T->Rchild);
}
//非递归 用户栈

中序遍历

//递归 系统栈
void inorderTraverse(BTNode *T){
if(T == NULL) return; //访问根结点
inorderTraverse(T->Lchild);
printf(T->data);
inorderTraverse(T->Rchild);
}
//非递归 用户栈

后序遍历

//递归 系统栈
void postorderTraverse(BTNode *T){
if(T == NULL) return; //访问根结点
postorderTraverse(T->Lchild);
postorderTraverse(T->Rchild);
printf(T->data);
}
//非递归 用户栈

层次遍历

利用队列实现

define MAX_NODE 50

void LevelorderTraverse(BTNode *T){
BTNode *Queue[MAX_NODE], *p=T;
int front=0, rear=0;
if(p!=NULL){
Queue[rear++]=p; //根结点入队
while(front<rear){
p=Queue[front++];
visit(p->data);
if(p->Lchild != NULL)
Queue[rear++]=p->Lchild; //左结点入队
if(p->Rchild != NULL)
Queue[rear++]=p->Rchild; //右结点入队
}
}
}

线索二叉树

线索 遍历基础上,直接前驱或后继

树和二叉树的转换

树->二叉树 左孩右兄

哈夫曼树

WPL(带权路径长度)值最小的树,即哈夫曼树或最优树

构建:优先处理权值小的结点,自下向上进行构造
哈夫曼编码:左0右1

特点:

  • 哈夫曼树只有0度结点和2度结点 n0=n2+1
  • 哈夫曼树的WPL值最小
  • 哈夫曼树不唯一,因为其左右子树可以交换,但是WPL值唯一
  • 哈夫曼树本质上不属于二叉树,但考试中认为是
  • 哈夫曼树的上层结点的权值不小于下层结点的权值
  • 哈夫曼编码只讨论叶子的编码

平均编码长度 = WPL/(W的和)

并查集

Union-Find Sets
主要用于处理一些不相交集合的合并及查询问题

常见用途

  • 求连通子图
  • 求最小生成树的Kruskal算法
  • 求最近公共祖先(Least Common Ancestors,LCA)

操作时间复杂度 常数级

操作:

  • Make-Set(x) 建立一个新的并查集,其中包含元素x
  • Union(x,y) 把元素x和元素y所在的集合合并,要求x和y所在的集合不相交,若相交则不合并
  • Find-Set(x) 找到元素x所在的集合的代表,该操作也可以用于判断两个元素是否位于同一集合,只要将它们各自的代表比较一下就可以

实现原理:树表示集合,树的每个结点表示集合中的一个元素,根对应的元素就是该集合的代表。

路径压缩:每次查找时,令查找路径上的每个结点都直接指向根结点

按秩合并:使用秩表示树高度的上界,在合并时,从事将具有较小秩大的树根指向具有较大秩的树根(将比较矮的树作为子树,添加到较高树中)

按集合中包含的元素个数(或者树中的结点数)合并,并包含结点较少的树根指向包含结点较多的树根

本文修订依据:ISO/IEC JTC 1/SC 22/WG14 C11 委员会草案 N1570,§6.8.6 的 return expressionopt ; 语法及 §6.8.6.4 的无表达式 return 规则。本文仅在三个 void 遍历函数中的 if(T == NULL) return 后补上必需的分号,未改动遍历算法或其他教学内容。

AI 修改声明: 本文由 LLM 协助修订,最近修改时间:2026-09-25 14:18(UTC+08:00)。修订仅补齐三个 return 语句的 C 语法分号。

posted @ 2023-02-24 21:26  Theseus‘Ship  阅读(65)  评论(0)    收藏  举报
Live2D