ADT
Note
ADT 二叉树(Binary tree) Data
Binary tree是一种n(n >= 0)个节点的有限集。该集合或者为空集(n=0) 或者由一个根节点和两颗互不相交的、分别称为根节点的左子树和右子树的二叉树构成。
- 每个节点最多两颗子树,二叉树不存在度数大于二的节点。(但有一颗或没有也行)
- 左右子树有次序。
Operation
endADT
二叉树状态
- 空树
- 只有根节点
- 根节点加左子树
- 根节点加右子树
- 根节点加左右子树
Note
二叉树五状态图解
⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠
Text Elements
A
A
B
A
C
A
B
C
指向原始笔记的链接
特殊二叉树
斜树
Note
斜树图解
⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠
Text Elements
A
B
C
A
B
C
指向原始笔记的链接
满二叉树
又称完美二叉树
- 所有分支节点都有左子树和右子树(度数一定是2)
- 叶子都在同一层(最下一层)
- 同样深度的二叉树中,满二叉树的节点个数最多,同时叶子也最多
Note
满二叉树图解
⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠
Text Elements
A
B
C
D
E
F
G
指向原始笔记的链接
严格二叉树
- 对一颗具有n个结点的二叉树,其节点度数要么是2要么是0
完全二叉树
- 对一颗具有n个结点的二叉树按层序编号,如果编号为i(1<=i<=n)的节点与同样深度的满二叉树中编号为i的节点位置完全相同,则这个二叉树称为完全二叉树。
- 叶子节点只会在最下两层
- 最下层叶子一定集中在左部连续位置
- 倒数第二层,若有叶子节点,一定都在右部连续位置
- 完全二叉树是满二叉树的生成树,满二叉树一定是完全二叉树,反之不一定
- 如果节点度为1,则该节点只有左孩子
- 同样结点树的二叉树,完全二叉树深度最小
Note
完全二叉树图解
⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠
Text Elements
A
B
D
E
C
指向原始笔记的链接
性质
- 二叉树的第i层至多有2
- 深度为k的二叉树至多有(2^k) - 1个节点(k>=1)
- 任意二叉树T,终端节点n0,度为2的节点数为n2,则n0 = n2+1
- 具有n个节点的完全二叉树的深度为
二叉树存储结构
-
顺序存储:即用数组存储,但顺序存储方式适用性不强。
-
二叉树链式存储,二叉链表
具体实现
树体
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;创建
//前序遍历输入数据
void createBinTree(BiTree **T)
{
char c;
scanf("%c", &c);
if(' ' == c)
{
*T = NULL;
}
else
{
*T = (BinTNode*)malloc(sizeof(BiTNode));
(*T)->data = c;
CreateBinTree(&(*T)->lchild);
CreateBinTree(&(*T)->rchild);
}
}
createBinTree(&T);node* root = NULL;
node* insert(root)
node* create(int *arr, int n)
{
for(int i = 0; i < n; i++)
{
insert(root, data[i]);
}
//return root;
}
/*root =*/create(arr, n); 二叉树的遍历
(traversing binary tree)
- 前序
又可以是树的深度优先搜索(DFS, Depth-first Search) 根->左->右
void preOrderTraverse(BiTree T, int level)
{
if(T)
{
visit(T->data, level);//访问节点的具体操作
preOrderTraverse(T->lchild, level + 1);
preOrderTraverse(T->rchild, level + 1);
}
}- 中序 左->根->右
void inOrderTraverse(BiTree T, int level)
{
if(T)
{
inOrderTraverse(T->lchild, level + 1);
visit(T->data, level);//访问节点的具体操作
inOrderTraverse(T->rchild, level + 1);
}
}- 后序 左->右->根
void proOrderTraverse(BiTree T, int level)
{
if(T)
{
proOrderTraverse(T->lchild, level + 1);
proOrderTraverse(T->rchild, level + 1);
visit(T->data, level);//访问节点的具体操作
}
}- 层序 层序遍历属于广度优先搜索(BFS, Breadth-first Search),但是广度优先搜索(可以从右子树开始)不一定是树的层序遍历
void levelOrder(Node* t_root)
{
if(t_root == NULL)return;
queue<Node*> Q;
Q.push(t_root);
while(!Q.empty())
{
Node* curr = Q.front();
cout << curr->data << " ";
if(curr->left != NULL)
Q.push(curr->left);
if(curr->right != NULL)
Q.push(curr->right);
Q.pop();
}
}获取树的高度
int FindHeight(Node* t_root)
{
if(t_root == NULL)
{
return -1;
}
return max(FindHeight(t_root->left), FindHeight(t_root->right)) + 1;
}树的深度优先搜索
特殊实现
Morris 遍历:用最小的开支完成树的前中后序遍历
线索二叉树
二叉搜索树(BST)
struct BstNode
{
int data;
BstNode* left;
BstNode* right;
};
BstNode* GetNewNode(int data)
{
BstNode* newNode = new BstNode();
newNode->data = data;
newNode->left = newi->right = NULL;
}
BstNode* Insert(BstNode* t_root, int t_data)
{
if(root == NULL)
{
root = GetNewNode(t_data);
return root;
}
/*
void Insert(BstNode** t_root, int t_data)
{
if(*t_root == NULL)
{
*t_root = GetNewNode(t_data);
}
}
Insert(&root, data);
*/
else if(t_data <= t_root->data)
{
t_root->left = Insert(t_root->left, t_data);
}
else
{
t_root->right = Insert(t_root->right, t_data);
}
return root;
}
bool Search(BstNode* t_root, int t_data)
{
if(t_root = NULL)
return false;
else if(t_root->data == t_data)
return true;
else if(t_data <= t_root->data)
return Search(t_root->left, t_data);
else
return Search(t_root->right, t_data);
}
int main()
{
BstNode* root;
root = NULL;
Insert(root, 15);
Insert(root, 10);
Insert(root, 20);
}查找最大最小值
int findMin(BstNode* t_root)
{
if(t_root == NULL)
{
cout << "Error:Tree is Empty\n";
return -1;
}
BstNode* curr = t_root;
while(curr->left != NULL)
{
curr = curr->left;
}
return curr->data;
/*
else if(t_root->left == NULL)
{
return t_root->data;
}
return t_root->data;
*/
}
int findMax(BstNode* t_root)
{
if(t_root == NULL)
{
cout << "Error:Tree is Empty\n";
return -1;
}
BstNode* curr = t_root;
while(curr->right != NULL)
{
curr = curr->right;
}
return curr->data;
}平衡二叉树