【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
前面我们谈到了排序二叉树,还没有熟悉的同学可以看一下这个,二叉树基本操作、二叉树插入、二叉树删除1、删除2、删除3。但是排序二叉树也不是没有缺点,比如说,如果我们想在排序二叉树中删除一段数据的节点怎么办呢?按照现在的结构,我们只能一个一个数据查找验证,首先看看在不在排序二叉树中,如果在那么删除;如果没有这个数据,那么继续查找。那么有没有方法,可以保存当前节点的下一个节点是什么呢?这样就不再需要进行无谓的查找了。其实这样的方法是存在的,那就是在排序二叉树中添加向前向后双向节点。
现在数据结构定义如下:
typedef struct _TREE_NODE
{
int data;
struct _TREE_NODE* prev;
struct _TREE_NODE* next;
struct _TREE_NODE* left;
struct _TREE_NODE* right;
}TREE_NODE;
拿节点的添加来说,我们可能需要添加prev、next的处理步骤。
void set_link_for_insert(TREE_NODE* pParent, TREE_NODE* pNode)
{
if(NULL == pParent || NULL == pNode)
return;
if(pNode = pParent->left){
pNode->prev = pParent->prev;
if(pParent->prev)
pParent->prev->next = pNode;
pNode->next = pParent;
pParent->prev = pNode;
}else{
pNode->next = pParent->next;
if(pParent->next)
pParent->next->prev = pNode;
pNode->prev = pParent;
pParent->next = pNode;
}
return;
}
STATUS add_node_into_tree(TREE_NODE** ppTreeNode, int data)
{
TREE_NODE* pHead;
TREE_NODE* pNode;
if(NULL == ppTreeNode)
return FALSE;
if(NULL == *ppTreeNode){
*ppTreeNode = create_new_node(data);
return TRUE;
}
if(NULL != find_data_in_tree(*ppTreeNode, data))
return FALSE;
pHead = *ppTreeNode;
while(1){
if(data < pHead->data){
if(pHead->left){
pHead = pHead->left;
}else{
pNode = create_new_node(data);
pHead->left = pNode;
break;
}
}else{
if(pHead->right){
pHead = pHead->right;
}else{
pNode = create_new_node(data);
pHead->right = pNode;
break;
}
}
}
set_link_for_insert(pHead, pNode);
return TRUE;
}
添加节点如此,删除节点的工作也不能马虎。
void set_link_for_delete(TREE_NODE* pNode)
{
if(pNode->prev){
if(pNode->next){
pNode->prev->next = pNode->next;
pNode->next->prev = pNode->prev;
}else
pNode->prev->next = NULL;
}else{
if(pNode->next)
pNode->next->prev = NULL;
}
}
TREE_NODE* _delete_node_from_tree(TREE_NODE* root, TREE_NODE* pNode)
{
TREE_NODE* pLeftMax;
TREE_NODE* pLeftMaxParent;
TREE_NODE* pParent = get_parent_of_one(root, pNode);
if(NULL == pNode->left && NULL == pNode->right){
if(pNode == pParent->left)
pParent->left = NULL;
else
pParent->right = NULL;
}else if(NULL != pNode->left && NULL == pNode->right){
if (pNode == pParent->left)
pParent->left = pNode->left;
else
pParent->right = pNode->left;
}else if(NULL == pNode->left && NULL != pNode->right){
if(pNode == pParent->left)
pParent->left = pNode->right;
else
pParent->right = pNode->right;
}else{
pLeftMax = get_max_node_of_one(pNode->left);
if(pLeftMax == pNode->left){
pNode->left->right = pNode->right;
if(pNode == pParent->left)
pParent->left = pNode->left;
else
pParent->right = pNode->left;
}else{
pLeftMaxParent = get_parent_of_one(root, pLeftMax);
pNode->data = pLeftMax->data;
pLeftMaxParent->right = NULL;
pNode = pLeftMax;
}
}
return pNode;
}
STATUS delete_node_from_tree(TREE_NODE** ppTreeNode, int data)
{
TREE_NODE* pNode;
TREE_NODE* pLeftMax;
TREE_NODE* pLeftMaxParent;
if(NULL == ppTreeNode || NULL == *ppTreeNode)
return FALSE;
if(NULL == (pNode = find_data_in_tree(*ppTreeNode, data)))
return FALSE;
if(pNode == *ppTreeNode){
if(NULL == pNode->left && NULL == pNode->right)
*ppTreeNode = NULL;
else if(NULL != pNode->left && NULL == pNode->right)
*ppTreeNode = pNode->left;
else if(NULL == pNode->left && NULL != pNode->right)
*ppTreeNode = pNode->right;
else {
pLeftMax = get_max_node_of_one(pNode->left);
if(pNode->left == pLeftMax){
pNode->left->right = pNode->right;
*ppTreeNode = pNode->left;
}else{
pLeftMaxParent = get_parent_of_one(*ppTreeNode, pLeftMax);
pNode->data = pLeftMax->data;
pLeftMaxParent->right = NULL;
pNode = pLeftMax;
}
}
goto final;
}
pNode = _delete_node_from_tree(*ppTreeNode, pNode);
final:
set_link_for_delete(pNode);
free(pNode);
return TRUE;
}
其中,寻找最大值节点和寻找父节点的代码如下所示:
TREE_NODE* get_max_node_of_one(TREE_NODE* pNode)
{
if(NULL == pNode)
return NULL;
while(pNode->right)
pNode = pNode->right;
return pNode;
}
TREE_NODE* get_parent_of_one(TREE_NODE* root, TREE_NODE* pNode)
{
if(NULL == root || NULL == pNode)
return NULL;
while(root){
if(pNode == root->left || pNode == root->right)
return root;
else if(pNode->data < root->data)
root = root->left;
else
root = root->right;
}
return NULL;
}
总结:
(1)排序二叉树的序列化关键就是在二叉树节点添加前向指针和后继指针
(2)排序二叉树是空间换时间的典型案例
(3)排序二叉树是很多结构的基础,写多少遍都不为多,有机会朋友们应该多加练习
(4)测试用例的编写是代码编写的关键,编写程序的目的就是为了消除bug,特别是低级bug
分享到:
相关推荐
数据结构很讲究算法,我这个写的很好!!用C#语言写的,试试看,相信给你好处的。
一些算法的 flash动画演示:B树的删除,B树的生长过程,三元组表的转置,中序线索化二叉树,串的顺序存储,二分查找,二叉排序树的删除,二叉排序树的生成,二叉树的建立,克鲁斯卡尔算法构造最小生成树,冒泡排序,...
寻找中序线索化二叉树指定结点的前驱 寻找中序线索化二叉树指定结点的后继 构造哈夫曼树的算法模拟 构造哈夫曼树过程 树、森林和二叉树的转换 开放定址法建立散列表 拉链法创建散列表 朴素串匹配算法过程示意 图的...
中序线索化二叉树.swf 串的顺序存储.swf 二分查找.swf 二叉排序树的删除.swf 二叉排序树的生成.swf 二叉树的建立.swf 克鲁斯卡尔算法构造最小生成树.swf 冒泡排序.swf 分块查找.swf 单链表结点的删除.swf 单链表结点...
稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫...排序树(BST)、AVL树、线索二叉树、赫夫曼树、赫夫曼编码、多路查找树(B树B+树和B*树)、图、图的DFS算法和BFS、程序员常用10大算法、二分查找...
二叉树 5.1 二叉树概念、性质 5.2 完全二叉树概念、性质 5.3 满二叉树定义、性质 5.4 二叉树的遍历算法实现(递归与非递归)、线索二叉树的操作 5.5二叉搜索树概念及查找、插入、删除算法 5.6 AVL树概念;...
在二叉树线索化的过程中,图中指针 p 指向当前层二叉树的根结点,指针 pre 指向当前被访问的结点的前驱。在演示线索树的插入和删除过程时,图示窗口的下方还包括“输入行”和“提示行”。 18. 按先序序列建二叉链表...
6.4.3 中根次序线索化算法 6.4.4 在中根线索树上检索某结点的前趋或后继 6.4.5 在中根线索树上遍历二叉树 6.5 二叉树、 树和森林 6.5.1 树的存储结构 6.5.2 树与二叉树之间的转换 6.5.3 森林与二叉树的转换 ...
数据结构各种算法实现,有示例程序。 包括顺序表 单链表 双向链表 循环链表 顺序栈 链式栈 顺序队列 链式队列 串 二叉树 线索二叉树 堆 哈夫曼树 B+树 图 排序算法
第一章绪论、算法衡量指标、第二章线性表、顺序表、链表、第三章栈和队、栈、栈的应用举例、队列、循环队列、第四章串、串的模式匹配、第五章数组和广义表、稀疏矩阵的压缩存储方法:、广义表、第六章树和二叉树、...
算法6.5是中序遍历线索二叉树的非递归算法,要对其源码进行测试,可首先调用算法6.6及6.7建立中序线索二叉树。以下是测试程序的源码,相关类型和辅助函数定义在文件include06.h和include06.cpp中,此略。
8. 线索二叉树 34 9. 树和森林 35 10. 赫夫曼树及其应用 36 二、 习题 37 第7章 图 39 一、 基础知识和算法 39 1. 图的有关概念 39 2. 图的存储结构 39 3. 图的遍历 42 4. 最小生成树 44 5. 拓扑排序 46 6. 关键路径...
知道线索二叉树,会对二叉树进行线索化 树、森林和二叉树的转化,会遍历树和森林 赫夫曼树及其应用 算法: 递归遍历二叉树及其应用(P) 构造赫夫曼树和赫夫曼编码(A) 树和二叉树的转换(A) 森林和二叉树的...
(3)线索二叉树 (4)树的存储结构 (5)树、二叉树与森林的转化方法 (6)哈夫曼树 (7)二叉排序树及平衡化 (8)堆排序树 (9)B-树 4.图形结构 (1)图的定义及存储结构 (2)图的深度优先和广度优先遍历。 ...
二叉树的线索化 先序遍历(Pre_order) 中序遍历(In_order) 后序遍历(Post_order) (2) 按先序建二叉树(CrtBT_PreOdr) (3) 线索二叉树 二叉树的线索化 生成先序线索(前驱或后继) (Pre_thre) ...
线索二叉树 ………………………… 应用 …………………………………… 本章小结 …………………………………… 习题…………………………………………… 第 章 集合 ………………………………… 以集合为基础的抽象...
5.3 遍历二叉树和线索二叉树 103 5.3.1 遍历二叉树 103 5.3.2 线索二叉树 109 5.4 树和森林 114 5.4.1 树的存储结构 114 5.4.2 森林与二叉树的转换 116 5.4.3 树和森林的遍历 116 5.5 赫夫曼树及其...
数据结构各种算法实现(C++模板) 顺序表 单链表 双向链表 循环链表 顺序栈 链式栈 顺序队列 链式队列 优先级队列 串 二叉树 线索二叉树 堆 哈夫曼树 树 B+树 图 排序
B树的删除.rar B树的生长过程.rar 三元组表的转置.rar 中序线索化二叉树.rar 串的顺序存储.rar 二分查找.rar 二叉排序树的删除.rar 二叉排序树的生成.rar 二叉树的建立.rar 克鲁斯卡尔...
06-005二叉树的前序、中序和后序遍历的递归与非递归算法 06-006统计二叉树中叶子结点个数、按给定的先序序列建立二叉链表 06-007线索链表的建立与遍历 06-008树的存储结构、森林和二叉树的转换、树和森林的遍历 06-...