第五章 树与二叉树

一、数据结构定义

  1. 二叉树的顺序存储结构(要注意两点:每个节点要标记是否为空;数组下标隐含节点关系)
    typedef struct TreeNode{
    	int data;
    	bool isEmpty;
    } TreeNode;
    
    // 初始化顺序存储的二叉树,所有节点标记为空
    void InitSqBiTree(TreeNode t[], int length){
    	for (int i=0; i<length; i++){
    		t[i].isEmpty = true;
    	}
    }
    
    int main(){
    	TreeNode t[100]; // 定义一棵顺序存储的二叉树
    	InitSqBiTree(t, 100); //初始化为空树
    	...
    }
    
  2. 二叉树的链式存储结构(即二叉链表)(因为有两个指针所以是二叉链表,如果再加一个指向父节点的指针就是三叉链表)
    typedef struct BTNode{ // BT即Binary Tree,二叉树
    	int val;
    	struct BTNode *left, *right;
    } BTNode, *BTree;
    
  3. 线索二叉树的存储结构
    typedef struct ThreadBTNode{ // 线索二叉树
    	int val;
    	struct ThreadBTNode *left, *right;
    	bool ltag, rtag; // ltag和rtag为0表示有孩子,为1表示无孩子指向前驱/后继
    } ThreadBTNode, *ThreadBTree;
    
  4. 树的存储结构(不是上面说的二叉树,是可能有多个孩子的树)
    • 双亲表示法(节点仅保存其父节点信息,通过一个节点只能很快找到它的祖先。因此需要通过数组保存所有节点,才能实现对其遍历等操作,且效率较低,所以双亲表示法一般仅用在特殊场合,如并查集)
      第五章 树与二叉树_第1张图片
      typedef struct{
      	ElemType data;
      	int parent; // 存储其父节点在数组中存储的位置下标
      } PTNode;
      
      typedef struct{
      	PTNode *nodes;
      	int n;
      } PTree;
      
    • 孩子表示法(用一个数组存储所有节点,每个节点内存一个链表节点指针,指向其第一个孩子。链表节点内部保存两个域:孩子的下标和指向下一个孩子对应的链表节点的指针。孩子表示法可以很快找到所有孩子节点,但寻找双亲时必须遍历整棵树,效率较低)
      第五章 树与二叉树_第2张图片
      typedef struct Child{
      	int index; // 存储该孩子节点在数组中存储的位置下标
      	struct Child *next;
      } Child;
      
      typedef struct{
      	ElemType data;
      	Child *firstChild;
      } TreeNode; 
      
      typedef struct{
      	TreeNode *nodes;
      	int n;
      } CTree;
      
    • 孩子兄弟表示法
      • 可通过节点的左指针找到节点的第一个孩子,沿孩子的右指针可以找到该节点的所有孩子。孩子表示法中有组成树本身的节点和孩子链表节点共两种节点,孩子兄弟表示法通过两个指针,将孩子表示法中两种节点合为一种
      • 因为是两个指针,所以孩子兄弟表示法的树是以二叉链表作为存储结构的
      typedef struct CSNode{
      	ElemType data;
      	struct CSNode *firstChild, *nextSibling;
      } CSNode, *CSTree;
      
  5. 二叉排序树节点定义(与普通二叉树一致)
    typedef struct BSTNode{
    	int val;
    	struct BSTNode *left, *right;
    } BSTNode, *BSTree;
    
  6. 并查集的实现(初始化+查+并)
    // 初始化
    const int MAX_SIZE = 100; // 假设并查集的最大元素个数
    int parent[MAX_SIZE]; // 用于存储每个元素的父节点
    void Initial(){
    	for(int i=0; i<MAX_SIZE; i++)
    		parent[i] = -1;
    }
    
    // 查
    int Find(int x){
    	while(parent[x]>=0)
    		x = parent[x];
    	return x;
    
    // 并
    void Union(int x, int y){
    	int RootX = Find(x);
    	int RootY = Find(y);
    	
    	if (RootX!=RootY)
    		parent[RootX] = RootY;
    }
    

二、代码/算法

  1. 二叉树的基础算法
    • 查找节点
    • 删除二叉树
    • 输出树高
    • 统计二叉树节点数目
    • 判断是否是平衡二叉树
  2. 二叉树的遍历
    • 先序遍历
    • 中序遍历
    • 后序遍历
    • 三种遍历的非递归转换(ACE中未提到)
    • Morris遍历算法(只有竟成提到了)
    • 层序遍历(ACE:层序遍历需要用到队列,408中要求写代码的可能性比较小,所以这里的重点是层序遍历的过程)
  3. 由遍历序列构造二叉树(只有ACE给出了用前序+中序构造二叉树的代码)
    • 前序+中序
    • 后序+中序
    • 层序+中序
  4. 线索二叉树(408考纲是“线索二叉树的基本概念与构造”,没有提及遍历,可酌情观看)
    • 通过中序遍历构造线索二叉树
    • 中序线索二叉树的遍历
    • 先序和后续线索二叉树的构造
    • 先序线索二叉树的遍历
    • 后续线索二叉树的遍历
  5. 并查集的初始化、查、并(代码写在上面的数据结构定义中)
  6. 二叉排序树
    • 查找
    • 构建与插入
    • 删除
  7. 平衡二叉树(代码难度较高,初试可以不用管,机试有小概率会考)

你可能感兴趣的:(数据结构代码相关,数据结构,算法)