数据结构 · 综合题
一、树
给定树的两种遍历序列确定树
1)遍历方式操作
限定先左后右 | |||
先序遍历 DLR | 访问根结点 | 先序遍历根结点的左子树 | 先序遍历根结点的右子树 |
中序遍历 LDR | 中序遍历根结点的左子树 | 访问根结点 | 中序遍历根结点的右子树 |
后序遍历 LRD | 后序遍历根结点的左子树 | 后序遍历根结点的右子树 | 访问根结点 |
层序遍历 | 按二叉树的层序编号的次序访问各结点 |
2)已知树的两种遍历序列确定树
先建立根节点,然后确定左右子树。
A.已知一棵二叉树的先序序列和另一序列
①根据先序序列的第一个元素建立根结点;
②在另一序列中找到该元素,确定根结点的左右子树的序列;
③在另一序列中确定左右子树的序列;
④由左子树的先序序列和另一序列建立左子树;
⑤由右子树的先序序列和另一序列建立右子树。
B.已知一棵二叉树的中序序列和后序序列
①根据后序序列的最后一个元素建立根结点;
②在中序序列中找到该元素,确定根结点的左右子树的序列;
③在中序列中确定左右子树的序列;
④由左子树的后序序列和另一序列建立左子树;
⑤由右子树的后序序列和另一序列建立右子树。
二、堆
1. 定义
定义 | 一棵完全二叉树的任意一个非终端结点的元素 | ||
不小于 ≥ | 其左儿子结点和右儿子结点元素 | 最大堆/大顶堆/大根堆 | |
不大于 ≤ | 最小堆/小顶堆/小根堆 | ||
结论 | 最大堆的根结点元素在整个堆中最大 | ||
最小堆的根结点元素在整个堆中最小 | |||
堆的根结点也称为堆顶 |
完全二叉树:满二叉树从最后一个结点开始,连续去掉任意个结点构成的二叉树。
非终端结点:非叶子结点(树枝)。
2. 相关的基本操作
//最大堆的类型定义
#define Maxsize 200
typedef struct
{
int key; //排序关键字,max
/* other fields */
}elementtype;
typedef struct
{
elementtype elements[Maxsize];
int n;
}HEAP;
//堆的基本操作(以最大堆为例)
void MaxHeap(HEAP heap) //创建一个空堆
{
heap.n=0;
}
bool HeapFulls(HEAP heap) //判断堆是否为满
{
return(heap.n==MaxSize-1);
}
bool HeapEmpty(HEAP heap) //判断堆是否为空
{
return(!heap.n);
}
void Insert(HEAP heap,Elementtype element) //插入一个元素 复杂度O(log₂n)
{
int i; //记录最终插入位置
if(!HeapFull(heap))
{
i=heap.n+1; //最初插入位置
while((i!=1)&&(element>heap.elements[i/2])) //结点i的双亲结点为 i/2
{
heap.elements[i]=heap.elements[i/2]; //将双亲复制到现在i的位置
i/=2; //更新插入位置i变为原双亲所在位置 i/2
}
}
heap.elements[i]=element;
}
void DeleteMax(HEAP heap) //删除最大元素
{
int parent=1,child=2; //双亲位置从根节点开始
Elementype element, tmp; //element存储需要删除的元素,tmp存储最后元素
if(!HeapEmpty(heap))
element=heap.elements[1];
tmp=heap.elements[heap.n--]; //删除后少一个元素,n--
while(child<=heap.n)
{
if