二叉树
实现一个二叉查找树,并且支持插入、删除、查找操作
//实现一个二叉查找树,并且支持插入、删除、查找操作
typedef char datatype
typedef struct Bnode
{
datatype data;
struct Bnode *Lchild, *Rchild;
}Btnode, *BTptr;
CreateLBtree(BTptr BT) //建立以BT为根节点指针的二叉链表结构
{
datatype ch; int i = 0;
BTptr p, q;
Clearqueue(Q); //置队Q为空
BT = NULL; //置空树
ch = getchar(); //读入数据
while(ch != '#')
{
p = NULL; //p为新节点的地址,但空节点地址为NULL
if(ch != '@')
{
p = (BTptr)malloc(sizeof(BTnode)); //申请新节点
p -> data = ch; //存入数据
p -> Lchild = p -> Rchild = NULL;
}
i++; //节点序号计数
Enqueue(q, p); //新节点地址或虚节点地址(NULL)进队
if(i == 1) BT = p; //第一输入节点为根
else
{
q = Getqtop(Q); //取队头元素
if(p && q) //若新节点及父几点均存在
if(1 % 2 == 0) q -> Lcchild = p; //i为偶数,p是双亲的左子
else q -> Rchild = p; //i为奇数,p是双亲的右子
if(i % 2 == 1) Delqueue(Q, q); //当前双亲处理完出队
}
ch = getchar(); //输入下一数据
}
return (BT);
}
实现查找二叉查找树中某个节点的后继、前驱节点
//实现查找二叉查找树中某个节点的后继、前驱节点
//线索二叉树
typedef struct Bnode
{
short int Ltag, Rtag;
datatype data;
struct Bnode *Lchild, *Rchild;
} BTnode, *BTptr;
BTptr pre = NULL;
void Inthreadbt(BTptr BT) //对二叉树BT的线索华的算法
{
if(BT)
{
Inthreadbt(BT -> Lchild); //线索化左子树
if(BT -> Lchild == NULL) //左指针空闲时
{ //本节点前驱为中序遍历下前一个节点
BT -> Ltag = 1;
BT -> Lchild == pre;
}
if(BT -> Rchild == NULL) //右指针空闲时
BT -> Rtag = 1; //记录下此点有空闲指针
if(pre && pre->Rtag == 1) //上一个节点有空的后继指针时,
pre -> Rchild = BT; //该指针指向其后继(本节点)
pre = BT; //次节点已访问,更新为前驱
Inthreadbt(BT -> Rchild); //线索化右子树
}
}
BTptr Inpre(BTptr p) //求中序线索二叉树中p节点前驱的算法
{
BTptr pre;
if(p == NULL) return(NULL);
pre = p -> Lchild; //p有左子时pre为p的左子,否则取p前驱
if(p -> Ltag == 0) //p有左子树时
while(pre->Rtag == 0) //取该子树最右边的节点,即为p的前驱
pre = pre -> Rchild;
return(pre); //返回p的前驱
}
BTptr Insucc(BTptr p) //求中序线索二叉树中p节点后继的算法
{
BTptr s;
if(p == NULL) return(NULL);
s = p -> Lchild; //p有右子时s为p的右子,否则取p后继
if(p -> Ltag == 0) //p有左子树时
while(s->Rtag == 0) //取该子树最左边的节点,即为p的后继
s = s -> Rchild;
return(pre); //返回p的后继
}
实现二叉树前、中、后序以及按层遍历
//实现二叉树前、中、后序以及按层遍历
void preorder(BTptr T) //对当前根节点指针为T的二叉树按前序遍历的算法
{
if(T)
{
visit(T); //访问T的所有节点
preorder(T -> Lchild); //前序遍历T的左子树
preorder(T -> Rchild); //前序遍历T的右子数
}
}
void inorder(BTptr T) //对当前根节点指针为T的二叉树按中序遍历的算法
{
if(T)
{
inorder(T -> Lchild); //中序遍历T的左子树
visit(T); //访问T的所有节点
inorder(T -> Rchild); //中序遍历T的右子数
}
}
void postorder(BTptr T) //对当前根节点指针为T的二叉树按后序遍历的算法
{
if(T)
{
postorder(T -> Lchild); //后序遍历T的左子树
pstorder(T -> Rchild); //后序遍历T的右子数
visit(T); //访问T的所有节点
}
}
void Layerorder(BTptr T) //对二叉树按层次遍历的算法
{
BTptr p;
if(T)
{
Clearqueue(Q); //置队Q空
Enqueue(Q, T); //先将指针进队
while(!Emptyqueue(Q))
{
p = Dequeue(Q); //出队,队头元素指向p
visit(p); //访问p节点
if(p -> Lchild) Enqueue(Q, p -> Lchild); //左子指针进队
if(p -> Rchild) Enqueue(Q, p -> Rchild); //右子指针进队
}
}
}
堆
实现一个小顶堆、大顶堆、优先级队列
实现堆排序
void Heapsort(sqfile F) //对顺文件F的堆排序算法
{
int i;
Retype temp;
for(i = F.len / 2; i >= 1; i--)
Adjust(F, i, F.len); //调整(R[i]...R[n])为堆
for(i = F.len; i >= 2; i--) //选择n-1次
{
temp = F.R[1]; //根与当前最后一个节点互换
F.R[1] = F.R[i];
F.R[i] = temp;
Adjust(F, 1, i-1); //互换后再建堆
}
}
利用优先级队列合并 K 个有序数组
求一组动态数据集合的最大 Top K