数据结构第六讲:树与二叉树详解

需积分: 0 2 下载量 135 浏览量 更新于2024-07-14 收藏 895KB PPT 举报
"该资源是关于数据结构课程的第六讲,主要讲解了树与二叉树的相关知识,包括树的基本概念、二叉树、二叉树遍历、线索二叉树、树和森林以及哈夫曼树与哈夫曼编码等。其中,还展示了创建二叉树节点的代码示例,以及树的各种基本操作如初始化、创建、销毁等。" 在数据结构中,树是一种非常重要的非线性数据结构,它是由若干个结点按照特定规则组织起来的集合。每个结点包含一个数据元素和若干指向其子树的指针。在树的定义中,有一个特殊的结点称为根结点,它是树的起点,没有前驱只有后继。除了根结点,其余结点可以分为若干个互不相交的子树,这些子树本身也满足树的定义。 二叉树是树的一个特殊类型,每个结点最多有两个子结点,分别称为左子结点和右子结点。二叉树的遍历主要有三种方式:前序遍历(根-左-右)、中序遍历(左-根-右)和后序遍历(左-右-根)。这些遍历方法在处理二叉树问题时非常关键,例如在查找、排序等算法中都有应用。 线索二叉树是一种为了方便进行二叉树遍历而进行特殊标记的二叉链表,通过线索可以实现对二叉树的双向遍历。这种数据结构使得在非递归情况下也能高效地遍历二叉树。 树和森林是由一棵或多棵二叉树组成的集合,它们之间的转换关系是数据结构中的重要概念。森林到二叉树的转换常常用于解决某些问题,比如二叉搜索树的构造。 哈夫曼树是一种带权路径长度最短的二叉树,也称为最优二叉树。哈夫曼编码是利用哈夫曼树构造的一种前缀编码,用于数据压缩,它能确保每个字符的编码不会是其他字符编码的前缀,从而避免解码时的歧义。 在实际编程中,处理树通常会涉及一系列操作函数,如初始化(InitTree)、创建(CreateTree)、销毁(Destroy)、清除(Clear)树,以及定位结点(Locate)、判断是否为空(Empty)、获取深度(Depth)、定位根结点(Root)、读取或设置结点元素值(GetRoot, GetElem, SetElem)等。在提供的代码片段中,可以看到创建二叉树根结点的过程,通过输入数据元素创建新结点,并为其分配左右子树。 理解并掌握树与二叉树的概念和操作对于学习和应用数据结构至关重要,它们在计算机科学的多个领域都有广泛的应用,如编译器设计、数据库系统、图形学、网络路由等。

#include<iostream> using namespace std; #include <stack> // 定义树节点结构体 typedef struct TreeNode { char val;//数据域 TreeNode* left;//左孩子 TreeNode* right;//右孩子 }*Tree, TreeNode; void CreateTree(Tree& T) { char x; cin >> x; if (x =='*') { T = NULL; return; } else { T = new TreeNode; T->val = x; CreateTree(T->left); CreateTree(T->right); } } // 先序遍历二叉树 void preOrderTraversal(TreeNode* root) { if (root == NULL) return; cout << root->val << endl; preOrderTraversal(root->left); preOrderTraversal(root->right); } // 中序遍历二叉树 void inOrderTraversal(TreeNode* root) { if (root == NULL) return; inOrderTraversal(root->left); cout << root->val << endl; inOrderTraversal(root->right); } void inOrderS(TreeNode* root) { stack<TreeNode*> S; TreeNode *p = root; while (p || !S.empty()){ if(p->left){ S.push(p); p = p->left; } else{ cout << S.top()->val; p = S.top()->right; S.pop(); } } } // 后序遍历二叉树 void postOrderTraversal(TreeNode* root) { if (root == NULL) return; postOrderTraversal(root->left); postOrderTraversal(root->right); cout << root->val <<endl;} int main() { TreeNode* root = NULL; cout << "请输入二叉树的先序遍历序列,以*表示空节点" << endl; CreateTree(root); stack<int> S; //cout << "先序遍历结果为:"<< endl; //preOrderTraversal(root); cout << endl << "中序遍历结果为:" << endl; inOrderS(root); //cout << endl << "后序遍历结果为:" << endl; //postOrderTraversal(root); cout << endl; return 0; } 纠错

2023-05-22 上传

#include <iostream> #include <cstdio> #include<stdlib.h> using namespace std; typedef char Datatype; int cnt; struct TNode { Datatype data; TNode* rchild; TNode* lchild; }; void CreatTree(TNode* &root) //递归法先序创建树 { char ndata; cin>>ndata; if(ndata=='#') root=NULL; else { root=new TNode;root->data=ndata; CreatTree(root->lchild); CreatTree(root->rchild); } } void preOrderTraver(TNode*& root) //递归法先序遍历 { if(root!=NULL) { cout<<root->data<<" "; preOrderTraver(root->lchild); preOrderTraver(root->rchild); } } void InOrderTraver(TNode*& root) //递归法中序遍历 { if(root!=NULL) { InOrderTraver(root->lchild); cout<<root->data<<" "; InOrderTraver(root->rchild); } } void posOrderTraver(TNode*& root)//递归法后序遍历 { if(root!=NULL) { posOrderTraver(root->lchild); posOrderTraver(root->rchild); cout<<root->data<<" "; } } int BTHeight(TNode *t)//计算二叉树的深度 { int ans = 0; if(t == NULL) return 0; else if(t != NULL) ans += max(ans,max(BTHeight(t->lchild),BTHeight(t->rchild))+1); return ans; } int BTLeafNode(TNode *t)//计算二叉树的叶子节点数 { if(t != NULL) { if(t->lchild == NULL && t->rchild == NULL) { printf("%c",t->data); cnt++; } else { BTLeafNode(t->lchild); BTLeafNode(t->rchild); } } return cnt; } int main() { TNode *root=NULL; cout<<"请输入该二叉树的先序遍历结果:\n"; CreatTree(root); cout<<"先序遍历结果"<<endl; preOrderTraver(root);cout<<endl; cout<<"中序遍历结果:"<<endl; InOrderTraver(root);cout<<endl; cout<<"后序遍历结果:"<<endl; posOrderTraver(root);cout<<endl; printf("\n输出二叉树的深度:"); int sum = BTHeight(root); cout << sum << endl; printf("输出二叉树的叶子结点:"); int ans = BTLeafNode(root); printf("\n输出二叉树的叶子结点的个数:"); cout << ans << endl; system(“pause”); return 0; }每一段有什么作用

2023-06-08 上传
2023-05-30 上传
2023-05-18 上传