树的遍历算法(完美C语言)

合集下载

判断一棵树是否为满二叉树的算法c语言

判断一棵树是否为满二叉树的算法c语言

判断一棵树是否为满二叉树的算法c语言

判断一棵树是否为满二叉树的算法(C语言)

满二叉树是一种特殊的二叉树,每个节点要么没有子节点,要么有两个子节点。判断一棵树是否为满二叉树的算法可以通过以下步骤实现:

1. 定义二叉树的数据结构

在C语言中,可以使用结构体定义二叉树的节点。每个节点包含一个数据域和两个指针域,分别指向左子节点和右子节点。

```c

struct TreeNode {

int data;

struct TreeNode* left;

struct TreeNode* right;

};

```

2. 实现判断函数

编写一个递归函数,用于判断给定二叉树是否为满二叉树。函数的输入参数为根节点指针,返回值为布尔类型。

```c

int isFullBinaryTree(struct TreeNode* root) {

// 如果根节点为空,则返回真

if (root == NULL) {

return 1;

}

// 如果只有一个子节点或没有子节点,则返回假

if ((root->left == NULL && root->right != NULL) ||

(root->left != NULL && root->right == NULL)) {

return 0;

}

// 递归判断左子树和右子树

return isFullBinaryTree(root->left) && isFullBinaryTree(root->right);

}

```

3. 测试样例

可以编写一些测试样例来验证判断函数的正确性。例如,下面是一个满二叉树和一个非满二叉树的示例:

二叉树的遍历及常用算法

二叉树的遍历及常用算法

⼆叉树的遍历及常⽤算法

⼆叉树的遍历及常⽤算法

遍历的定义:

按照某种次序访问⼆叉树上的所有结点,且每个节点仅被访问⼀次;

遍历的重要性:

当我们需要对⼀颗⼆叉树进⾏,插⼊,删除,查找等操作时,通常都需要先遍历⼆叉树,所有说:遍历是⼆叉树的基本操作;

遍历思路:

⼆叉树的数据结构是递归定义(每个节点都可能包含相同结构的⼦节点),所以遍历也可以使⽤递归,即结点不为空则继续递归调⽤

每个节点都有三个域,数据与,左孩⼦指针和右孩⼦之指针,每次遍历只需要读取数据,递归左⼦树,递归右⼦树,这三个操作

三种遍历次序:

根据访问三个域的不同顺序,可以有多种不同的遍历次序,⽽通常对于⼦树的访问都按照从左往右的顺序;

设:L为遍历左⼦树,D为访问根结点,R为遍历右⼦树,且L必须位于R的前⾯

可以得出以下三种不同的遍历次序:

先序遍历

操作次序为DLR,⾸先访问根结点,其次遍历根的左⼦树,最后遍历根右⼦树,对每棵⼦树同样按这三步(先根、后左、再右)进⾏

中序遍历

操作次序为LDR,⾸先遍历根的左⼦树,其次访问根结点,最后遍历根右⼦树,对每棵⼦树同样按这三步(先左、后根、再右)进⾏

后序遍历

操作次序为LRD,⾸先遍历根的左⼦树,其次遍历根的右⼦树,最后访问根结点,对每棵⼦树同样按这三步(先左、后右、最后根)进⾏

层次遍历

层次遍历即按照从上到下从左到右的顺序依次遍历所有节点,实现层次遍历通常需要借助⼀个队列,将接下来要遍历的结点依次加⼊队列中;

遍历的应⽤

“遍历”是⼆叉树各种操作的基础,可以在遍历过程中对结点进⾏各种操作,如:对于⼀棵已知⼆叉树

遍历二叉树的非递归算法

遍历二叉树的非递归算法

又都可以转化为一棵等价的二叉树 B —T e 。在这里二叉树的定义为: i re 或者
为空、 或者 由根与两棵互不相交, 称为根结点左子树和右子树的二权树组成 , 即二叉树本身还是由二叉树组成;由此 可见二权树的定义是递归的 R c r eu— S v 。二 叉 树具 有 结 构简 单 、 ie 操作 方 便 的优 点 , 够 在 遍 历 T a e s 过 程 中 能 rvre 建立二权树的链式存储结构; 使一个非线性结构 的管理 问题线性化。 从而使很 多管理领域中的问题 ,都可 以在二叉树的建立与遍 历过程 中得到解 决 , 因
就会不同。
)A r ys q e c [a ] ra , eu n eM x
t p d f tu t y e e s r c
树, 它有 4 个结点。为了便于理解遍历思想 , 暂时为每个没有 予树 的结点都

e ely e b s 1 Ⅱ p 赤 a e: t e e t p *t p' lmye o ,

) l m ye e e tp :
t p d f st u t r a y e e r e A r y

c a d t h r a a: i t h: n x
个线性序列 。由于二叉树有左、 右子树, 以遍历的次序不同, 所 得到的结果 在 介绍遍历算法之前 ,先介绍一下遍历 的具体方法。例如有一棵二叉

c语言哈夫曼树的构造及编码

c语言哈夫曼树的构造及编码

c语言哈夫曼树的构造及编码

一、哈夫曼树概述

哈夫曼树是一种特殊的二叉树,它的构建基于贪心算法。它的主要应用是在数据压缩和编码中,可以将频率高的字符用较短的编码表示,从而减小数据存储和传输时所需的空间和时间。

二、哈夫曼树的构造

1. 哈夫曼树的定义

哈夫曼树是一棵带权路径长度最短的二叉树。带权路径长度是指所有叶子节点到根节点之间路径长度与其权值乘积之和。

2. 构造步骤

(1) 将待编码字符按照出现频率从小到大排序。

(2) 取出两个权值最小的节点作为左右子节点,构建一棵新的二叉树。

(3) 将新构建的二叉树加入到原来排序后队列中。

(4) 重复上述步骤,直到队列只剩下一个节点,该节点即为哈夫曼树的根节点。

3. C语言代码实现

以下代码实现了一个简单版哈夫曼树构造函数:

```c

typedef struct TreeNode {

int weight; // 权重值

struct TreeNode *leftChild; // 左子节点指针

struct TreeNode *rightChild; // 右子节点指针

} TreeNode;

// 构造哈夫曼树函数

TreeNode* createHuffmanTree(int* weights, int n) {

// 根据权值数组构建节点队列,每个节点都是一棵单独的二叉树

TreeNode** nodes = (TreeNode**)malloc(sizeof(TreeNode*) * n);

for (int i = 0; i < n; i++) {

nodes[i] = (TreeNode*)malloc(sizeof(TreeNode));

c语言数据结构树的基本操作

c语言数据结构树的基本操作

c语⾔数据结构树的基本操作

树的基本操作有创建,插⼊,删除,以及各种遍历的应⽤,如:利⽤后序遍历求⾼度,利⽤前序遍历求层数的结点

基本算法思路:创建⼆叉树函数参数必须接受⼆级指针!如果使⽤同级指针,⽆法返回创建后的结果,利⽤递归malloc函数完成创建

插⼊(检索树):根据检索树特性,在插⼊必须判断根节点左右两边的值来完成插⼊

删除:如果删除的是节点是叶结点,直接free。如果有⼀个⼦树,将其⽗节点指向删除节点的⼉⼦。如果两个⼦树,遍历右节点找到最⼤的data,将他的data复制给删除data,然后删除该节(重复第⼀⼆种情况)

更多应⽤举例请看代码(普通⼆叉树,检索树)

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<iostream>

#include<conio.h>

struct tree1 {

char data;//数据域

struct tree1* light;//指向左孩⼦的指针

struct tree1* right;//指向右孩⼦的指针

};

char ch;

struct tree1* root;

struct tree1 *del_node1= NULL;//需要删除的节点

void create(struct tree1** p);//创造⽽叉树

void create_tree();//创造检索树

void front(struct tree1* p);//前序遍历

数据结构-C语言-树和二叉树

数据结构-C语言-树和二叉树

a
b
c
d
e
f
g
单支树
特点: 结点间关系蕴含在其存储位置中 浪费空间,适于存满二叉树和完全二叉树
二叉树的链式存储
PARENT
DATA
LCHILD
RCHILD
二叉链表
A B CD EF
G
A^
B
^ C^
D
^E
^F ^
^ G^
typedef struct BiNode{ TElemType data; struct BiNode *lchild,*rchild; //左右孩子指针
基本术语
双亲 ——即上层的那个结点(直接前驱) 孩子 ——即下层结点的子树的根(直接后继) 兄弟 ——同一双亲下的同层结点(孩子之间互称兄弟) 堂兄弟 ——即双亲位于同一层的结点(但并非同一双亲) 祖先 ——即从根到该结点所经分支的所有结点 子孙 ——即该结点下层子树中的任一结点
基本术语
结点 ——即树的数据元素 结点的度 ——结点挂接的子树数 结点的层次 ——从根到该结点的层数(根结点算第一层) 终端结点 ——即度为0的结点,即叶子 分支结点 ——即度不为0的结点(也称为内部结点)
二叉树的性质和存储结构
性质5: 对完全二叉树,若从上至下、从左至右
编号,则编号为i 的结点,其左孩子编号必为2i, 其右孩子编号必为2i+1;其双亲的编号必为i/2。

c语言二叉树的先序,中序,后序遍历

c语言二叉树的先序,中序,后序遍历

c语言二叉树的先序,中序,后序遍历

1、先序遍历

先序遍历可以想象为,一个小人从一棵二叉树根节点为起点,沿着二叉树外沿,逆时针走一圈回到根节点,路上遇到的元素顺序,就是先序遍历的结果

先序遍历结果为:A B D H I E J C F K G

2、中序遍历

中序遍历可以看成,二叉树每个节点,垂直方向投影下来(可以理解为每个节点从最左边开始垂直掉到地上),然后从左往右数,得出的结果便是中序遍历的结果

中遍历结果为:H D I B E J A F K C G

3、后序遍历

后序遍历就像是剪葡萄,我们要把一串葡萄剪成一颗一颗的。

还记得我上面提到先序遍历绕圈的路线么?(不记得翻上面理解)就是围着树的外围绕一圈,如果发现一剪刀就能剪下的葡萄(必须是一颗葡萄)(也就是葡萄要一个一个掉下来,不能一口气掉超过1个这样),就把它剪下来,组成的就是后序遍历了。

后序遍历中,根节点默认最后面

后序遍历结果:H I D J E B K F G C A

4、口诀

先序遍历:先根再左再右

中序遍历:先左再根再右

后序遍历:先左再右再根

这里的根,指的是每个分叉子树(左右子树的根节点)根节点,并不只是最开始头顶的根节点,需要灵活思考理解

5、代码展示

#include<stdio.h>

#include<stdlib.h>

typedef struct Tree{

int data; // 存放数据域struct Tree *lchild; // 遍历左子树指针struct Tree *rchild; // 遍历右子树指针

}Tree,*BitTree;

关于树的各种C语言代码

关于树的各种C语言代码
case 10: k = TreeDepth(bt); printf("二叉树的深度为%d\n",k); break;
case 11: PrintTree(bt,nlayer); printf("二叉树打印成功\n"); break;
case 12: PreOrderTree(bt); printf("非递归先序遍历二叉树成功\n"); break;
{ count = Leaf(bt->lchild) + Leaf(bt->rchild);
} return count; }
void Degree1Node(BiTree bt) /*7.输出度为一的结点*/ {
if (bt != NULL) {
if (((bt->lchild != NULL) || (bt->rchild != NULL)) && (!((bt->lchild != NULL) && (bt->rchild != NULL))))
top++; Stack[top] = p; p = p->lchild; } if (top > 0) { p = Stack[top]; if ((p->rchild == NULL) || (p->rchild == q)) {

C语言DFS(深度优先搜索算法)详解

C语言DFS(深度优先搜索算法)详解

C语言DFS(深度优先搜索算法)详解

DFS(深度优先)是一种用于遍历或图形或树结构的算法。它从起点

开始,沿着一条路径尽可能远地遍历图形,直到无法继续前进为止,然后

返回到上一个节点,探索其他路径。DFS基本上是一个递归的过程,它使

用栈来实现。

DFS的基本思想是递归地遍历图形。算法通过维护一个visited数组

来跟踪已经访问过的节点,以避免无限循环。首先,我们访问起点节点,

并将其标记为已访问。然后,对于起点的每个未访问的邻居节点,我们递

归地调用DFS。这样,我们沿着一条路径一直走到无法继续为止,然后返

回上一个节点继续探索其他未访问的邻居。我们重复这个过程,直到我们

访问了所有的节点。

在实现DFS时,我们需要用到一个栈来存储节点。首先,将起点节点

入栈。然后,当栈不为空时,我们将栈顶节点出栈,并将其标记为已访问。接下来,我们将栈顶节点的所有未访问邻居入栈。重复这个过程,直到栈

为空。需要注意的是,在使用栈时,我们应该按照相反的顺序将邻居节点

入栈,这样在出栈时才能按照正确的顺序进行访问。

DFS可以用来解决很多问题,例如图的连通性、寻找路径、生成所有

可能的子集等。对于连通性问题,如果我们可以从起点节点访问到所有的

节点,那么该图是连通的。对于寻找路径问题,我们可以使用DFS来找到

从起点到终点的路径。对于生成所有可能的子集问题,我们可以使用DFS

来枚举所有的子集。

下面是一个用C语言实现的DFS的示例代码:

```c

#include <stdio.h>

#define MAX_SIZE 10

int graph[MAX_SIZE][MAX_SIZE];

二叉树遍历稿ppt课件

二叉树遍历稿ppt课件

已知后序遍历:D E C B H G F AA
如果是先序序列
和中序A序列呢?
B
F
C
G
D EH
(B D C (E)D C E) ( F H G)
烧伤病人的治疗通常是取烧伤病人的 健康皮 肤进行 自体移 植,但 对于大 面积烧 伤病人 来讲, 健康皮 肤很有 限,请 同学们 想一想 如何来 治疗该 病人
基础知识-遍历规则
二叉树由根、左子树、右子树构成,定义为D、 L、R
❖ D、 L、R的组合定义了六种可能的遍历方案:
LDR, LRD, DLR, DRL, RDL, RLD
❖ 若限定先左后右,则有三种实现方案:
DLR
LDR
LRD
先序遍历 中序遍历
后序遍历
注:“先、中、后”的意思是指访问的结点D是先于子树出 现还是后于子树出现。
基础知识-中序遍历
பைடு நூலகம்
中序遍历(LDR):
L
D
R
A
A
LD R
L DR
B
C
D
B
讨论中序遍历 L D R
C
思想及算法?
中序遍历序列:B D A C D
特点:根结点左右分别为左右子树的所有结点.
烧伤病人的治疗通常是取烧伤病人的 健康皮 肤进行 自体移 植,但 对于大 面积烧 伤病人 来讲, 健康皮 肤很有 限,请 同学们 想一想 如何来 治疗该 病人

关于树的各种C语言代码

关于树的各种C语言代码

集合了树的各种算法,已经运行过,本人亲自所写,先序,后序,等全包括

#include<stdio.h>

#include<malloc.h>

#define Max 100

typedef int Status;

typedef struct BiTNode

{

char data;

struct BiTNode *lchild,*rchild;

}BiTNode,*BiTree;

int count;

Status CreatBiTree(BiTree *bt) /*1.按先序遍历序列创造二叉树的二叉链表*/ {

char ch;

getchar();

scanf("%c",&ch);

if (ch == ' ')

{

*bt = NULL;

}

else

{

*bt = (BiTree)malloc(sizeof(BiTNode));

(*bt)->data = ch;

printf("\n\t请输入%c结点的左孩子:",(*bt)->data);

CreatBiTree(&((*bt)->lchild));

printf("\n\t请输入%c结点的右孩子:",(*bt)->data);

CreatBiTree(&((*bt)->rchild));

}

return 1;

}

void PreOrder(BiTree bt) /*2.先序遍历二叉树*/

{

if (bt != NULL)

{

printf("%c\n",bt->data);

PreOrder(bt->lchild);

《数据结构——C语言描述》第6章:树

《数据结构——C语言描述》第6章:树

二叉树的性质:
性质5 对于具有n个结点的完全二叉树, 如果对其结点按层次编号,则对任一结点 i(1≤i≤n),有:
(1) 如果i=1,则结点i是二叉树的根,无双 亲;如果i>1,则其双亲是【i/2】 (2) 如果2i>n,则结点i无左孩子;如果2i≤n, 则其左孩子是2i (3) 如果2i+1>n,则结点i无右孩子;如果 2i+1≤n,则其右孩子是2i+1
后根遍历算法 void PostOrder(Btree root) { if(root!=NULL) { PostOrder(root->Lchild); PostOrder(root->Rchild); Visit(root ->data); } }
线索二叉树:利用二插链表剩余的n+1个空 指针域来存放遍历过程中结点的前驱和后继 的指针,这种附加的指针称为“线索”,加 上了线索的二叉链表称为线索链表,相应的 二叉树称为线索二叉树。 为了区分结点的指针域是指向其孩子的指 针,还是指向其前驱或后继的线索,可在二 叉链表的结点中,再增设2个标志域。
Lchild Ltag Data Rtag Rchild
0
Ltag= 1
Lchild 域 指 示 结 点 的 左 孩 子
Lchild域指示结点的遍历前驱
0
Rtag=

二叉树遍历C语言六种算法

二叉树遍历C语言六种算法

二叉树遍历C语言六种算法

二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点。在二叉树的遍历过程中,我们按照一定的方式访问每个节点。常用的遍历方式包括前序遍历、中序遍历、后序遍历、层次遍历等。其中,前序遍历、中序遍历和后序遍历是三种常用的深度优先遍历方法,层次遍历是广度优先遍历的一种方法。

在C语言中,我们可以使用递归和非递归两种方法来实现二叉树的遍历。下面将分别介绍这六种遍历算法,并给出相应的代码示例。

1.前序遍历(递归):

前序遍历先访问根节点,然后递归地遍历左子树和右子树。具体的实现代码如下:

```c

//前序遍历(递归)

void preorderTraversal(TreeNode* root)

if (root == NULL) return;

printf("%d ", root->val); // 访问根节点

preorderTraversal(root->left); // 递归遍历左子树

preorderTraversal(root->right); // 递归遍历右子树

```

2.前序遍历(非递归):

我们可以使用栈来实现前序遍历的非递归算法。具体的实现代码如下:```c

//前序遍历(非递归)

void preorderTraversal(TreeNode* root)

if (root == NULL) return;

Stack* stack = createStack(; // 创建一个栈

push(stack, root); // 根节点入栈

while (!isEmpty(stack))

C语言 二叉树的建立,撤销与遍历

C语言 二叉树的建立,撤销与遍历

C语言二叉树的建立,撤销与遍历

二叉树是一种特殊的树,每个节点只能有最多二个孩子节点,或者没有孩子节点。建立,与撤销或遍历二叉树主要是靠递归的方法。

#include

#include

typedef struct stud/*定义二叉树的结构,只有一个数据项,和两个孩子节点*/

{

char data;

struct stud *left;

struct stud *right;

} bitree;

void destroy(bitree **root)/*撤销二叉树,这里用的是递归和二级指针*/ {

if(*root!=NULL&&(*root)->left!=NULL)/*当前结点与左子树不空,递归撤销左子树*/

destroy(&(*root)->left);

if(*root!=NULL&&(*root)->right!=NULL)/*当前结点与右子树不空,递归撤销右子树*/

destroy(&(*root)->right);

free(*root);/*左右子树都为空,撤销该节点,并递归撤销其上的所有节点*/ }

void inititate(bitree **root)/*初始化二叉树的头结点,并分配空间*/ {

*root=(bitree *)malloc(sizeof(bitree ));

(*root)->left=NULL;

(*root)->right=NULL;

}

bitree *insert_left(bitree *curr,char x)/*在左子树插入数据*/

{

bitree *s,*t;

c语言经典算法题

c语言经典算法题

c语言经典算法题

C语言经典算法题目涵盖了多个领域,包括排序、查找、递归、动态规划等。以下是一些经典的C语言算法题目,它们对于提高编程能力和理解算法思想都是很有帮助的:

1. 冒泡排序:

实现冒泡排序算法,对一个数组进行升序或降序排序。

2. 快速排序:

实现快速排序算法,对一个数组进行升序或降序排序。

3. 选择排序:

实现选择排序算法,对一个数组进行升序或降序排序。

4. 二分查找:

实现二分查找算法,在有序数组中查找一个特定的元素。

5. 递归:

编写一个递归函数,计算斐波那契数列的第n 个数字。

6. 动态规划:

解决经典的动态规划问题,比如背包问题、最长公共子序列等。

7. 链表反转:

反转一个单链表或双链表。

8. 树的遍历:

实现二叉树的前序、中序和后序遍历。

9. 图的深度优先搜索(DFS)和广度优先搜索(BFS):

实现图的深度优先搜索和广度优先搜索算法。

10. 最短路径算法:

实现Dijkstra算法或Floyd-Warshall算法来求解图中的最短路径。

11. 素数判断:

编写一个函数判断一个给定的数是否是素数。

12. 最大公约数和最小公倍数:

实现求两个数的最大公约数和最小公倍数的算法。

这些题目旨在帮助你熟悉常见的算法思想和数据结构,提高编程和问题求解的能力。解决这些题目时,不仅要注重正确性,还要考虑算法的效率和优化。

c语言二叉树的算法代码

c语言二叉树的算法代码

c语言二叉树的算法代码

C语言二叉树的算法代码

二叉树是一种常用的数据结构,它由节点组成,每个节点最多有两个子节点:左子节点和右子节点。在C语言中,我们可以使用指针来表示二叉树的节点,并通过指针的操作来实现对二叉树的插入、删除、查找等操作。

我们需要定义一个二叉树节点的结构体,它包含一个数据域和两个指针域,分别指向左子节点和右子节点。代码如下:

```c

struct TreeNode {

int data; // 数据域

struct TreeNode* left; // 左子节点指针

struct TreeNode* right; // 右子节点指针

};

```

接下来,我们可以实现二叉树的插入操作。插入操作的主要思路是,首先确定要插入的节点位置,然后创建一个新节点,并将其链接到正确的位置上。代码如下:

```c

struct TreeNode* insertNode(struct TreeNode* root, int

value) {

if (root == NULL) {

// 如果树为空,则创建一个新节点并返回

struct TreeNode* newNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));

newNode->data = value;

newNode->left = NULL;

newNode->right = NULL;

return newNode;

}

if (value < root->data) {

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

{
printf(“\n Please Input Weight : w=?”);
scanf(“%d”, &w) ;HT[k].weight=w ;
}
/* 输入时,所有叶子结点都有权值 */
else HT[k].weight=0; /* 非叶子结点没有权值 */
HT[k].Parent=HT[k].Lchild=HT[k].Rchild=0 ;
if (top==0) bool=0 ; else if (S2[top]==0) {
p=S1[top]->Rchild ; S2[top]=1 ; } else { p=S1[top] ; top-- ; visit( p->data ) ; p=NULL ; /* 使循环继续进行而不至于死循环 */ } } while (bool!=0) ; } }
stack[++top]=q ;
p=p->Lchild ;
if (p==NULL) { p=stack[top] ; top-- ; }
}
while (p!=NULL) ;
}
}
二叉树的中序遍历:
递归算法:
void InorderTraverse(BTNode *T)
{
if (T!=NULL)
{
PreorderTraverse(T->Lchild) ;
② 从根结点开始遍历整棵二叉树,求得每个叶子结点对应字符的 Huffman 编码。 由 Huffman 树的生成知,n 个叶子结点的树共有 2n-1 个结点,叶子结点存储在数组
HT 中的下标值为 1∽n。 ① 编码是叶子结点的编码,只需对数组 HT[1…n]的 n 个权值进行编码; ② 每个字符的编码不同,但编码的最大长度是 n。
visit(T->data) ;
/* 访问根结点 */
PreorderTraverse(T->Rchild) ;
}
} 非递归遍历:
设 T 是指向二叉树根结点的指针变量,非递归算法是: 若二叉树为空,则返回;否则,令 p=T ⑴ 若 p 不为空,p 进栈, p=p->Lchild ; ⑵ 否则(即 p 为空),退栈到 p,访问 p 所指向的结点; ⑶ p=p->Rchild ,转(1); 直到栈空为止。
算法实现
void Huff_coding(unsigned n , Hnode HT[] , unsigned m) /* m 应为 n+1,编码的最大长度 n 加 1 */
{
int k , sp ,fp ;
char *cd , *HC[m] ; cd=(char *)malloc(m*sizeof(char)) ; cd[n]=‘\0’ for (k=1 ; k<n+1 ; k++)
{
BTNode *Stack[MAX_NODE] ,*p=T ;
int top=0 , bool=1 ; if (T==NULL) printf(“ Binary Tree is Empty!\n”) ;
else
{
do
{
while (p!=NULL)
{
stack[++top]=p ;
p=p->Lchild ;
} HTNode ;
void Create_Huffman(unsigned n, HTNode HT[ ], unsigned m)
/* 创建一棵叶子结点数为 n 的 Huffman 树 */
{
unsigned int w ; int k , j ;
for (k=1 ; k<m ; k++)
{
if (k<=n)
设 T 是指向二叉树根结点的指针变量,非递归算法是: 若二叉树为空,则返回;否则,令 p=T; ⑴ 访问 p 所指向的结点; ⑵ q=p->Rchild ,若 q 不为空,则 q 进栈; ⑶ p=p->Lchild ,若 p 不为空,转(1),否则转(4); ⑷ 退栈到 p ,转(1),直到栈空为止。
} /* 初始化向量 HT */
for (k=n+1; k<m ; k++)
{
unsigned w1=32767 , w2=w1 ; /* w1 , w2 分别保存权值最小的两个权值 */
int p1=0 , p2=0 ;
/* p1 , p2 保存两个最小权值的下标 */
for (j=1 ; j<=k-1 ; j++)
{
if (HT[k].Parent==0) /* 尚未合并 */
{
if (HT[j].Weight<w1)
{
w2=w1 ; p2=p1 ;
w1=HT[j].Weight ; p1=j ;
}
else if (HT[j].Weight<w2)
{
w2=HT[j].Weight ; p2=j ;
}
} /* 找到权值最小的两个值及其下标 */
/* 动态分配求编码的工作空间 */ /* 编码的结束标志 */ /* 逐个求字符的编码 */
{
sp=n ; p=k ; fp=HT[k].parent ; for ( ; fp!=0 ;p=fp , fp=HT[p].parent) /* 从叶子结点到根逆向求编码 */
if (HT[fp].parent==p) cd[--sp]=‘0’ ; else cd[--sp]=‘1’ ; HC[k]=(char *)malloc((n-sp)*sizeof(char)) ; /* 为第 k 个字符分配保存编码的空间
----------------------------------------------------------------------------------------------------------------------
#define MAX_NODE 50
void InorderTraverse( BTNode *T)
{Baidu Nhomakorabea
BTNode *Stack[MAX_NODE] ,*p=T, *q ;
int top=0 ;
if (T==NULL) printf(“ Binary Tree is Empty!\n”) ;
else
{
do
{
visit( p-> data ) ;
q=p->Rchild ;
if ( q!=NULL )
trcpy(HC[k] , &cd[sp]) ;
}
free(cd) ;
}
BTNode *S1[MAX_NODE] ,*p=T ; int S2[MAX_NODE] , top=0 , bool=1 ; if (T==NULL) printf(“Binary Tree is Empty!\n”) ; else {
do {
while (p!=NULL) {
S1[++top]=p ; S2[top]=0 ; p=p->Lchild ; }
---------------------------------------------------------------------------------------------------------------------define MAX_NODE 50 void PostorderTraverse( BTNode *T) {
}
HT[k].Lchild=p1 ; HT[k].Rchild=p2 ;
HT[k].weight=w1+w2 ;
HT[p1].Parent=k ; HT[p2].Parent=k ;
}
}
Huffman 编码算法
根据出现频度(权值)Weight,对叶子结点的 Huffman 编码有两种方式: ① 从叶子结点到根逆向处理,求得每个叶子结点对应字符的 Huffman 编码。
}
if (top==0)
bool=0 ;
else
{
p=stack[top] ; top-- ;
visit( p->data ) ; p=p->Rchild ;
}
}
while (bool!=0) ; } }
二叉树的后序遍历:
后序遍历的递归算法:
void PostorderTraverse(BTNode *T)
二叉树的先序遍历:
递归算法:
void PreorderTraverse(BTNode *T)
{
if (T!=NULL)
{ visit(T->data) ;
/* 访问根结点 */
PreorderTraverse(T->Lchild) ;
PreorderTraverse(T->Rchild) ;
}
} 非递归遍历:
p 进栈 S1 , tag 赋值 0,进栈 S2,p=p->Lchild 。 ⑵ 若 p 不为空,转(1),否则,取状态标志值 tag :
⑶ 若 tag=0:对栈 S1,不访问,不出栈;修改 S2 栈顶元素值(tag 赋值 1) ,取 S1 栈顶元 素的右子树,即 p=S1[top]->Rchild ,转(1); ⑷ 若 tag=1:S1 退栈,访问该结点; 直到栈空为止。
{ if (T!=NULL)
{ PostorderTraverse(T->Lchild) ;
PostorderTraverse(T->Rchild) ;
visit(T->data) ;
/* 访问根结点 */
} } /*图 6-8(a) 的二叉树,输出的次序是: cgefdba */
非递归遍历: 设 T 是指向根结点的指针变量,非递归算法是: 若二叉树为空,则返回;否则,令 p=T; ⑴ 第一次经过根结点 p,不访问:
----------------------------------------------------------------------------------------------------------------------
#define MAX_NODE 50
void PreorderTraverse( BTNode *T)
Huffman 树的生成---算法实现:
结点类型定义:
#define MAX_NODE 200 /* Max_Node>2n-1 */
typedef struct
{ unsigned int Weight ;
/* 权值域 */
unsinged int Parent , Lchild , Rchild ;
相关文档
最新文档