二叉排序树(B-Tree)-c实现
这个二叉排序树写完了,虽然还有些bug,但还是很高兴的。
主要实现二叉排序树的构建。(*表示稍微重要点)
二叉排序树的打印。
二叉排序树的删除。
代码里的三种情况都测了
顺便附送一个简单的中序遍历,递归。
代码现在还有很多内存泄漏,不想改了,明天或者下周改。
主要遇到的小问题:1.排序树的打印,本想链式结构打印出来,但是控制不好,就换了一种简单的方法。
2.内存malloc和free还有很大问题。tips:为什么一般malloc之后,内存释放后NULL指针,现在有点明白,free 那块malloc的内存,不然会形成很多内存碎片,而此时的指针还是指向原先的那块内存地址,只不过数据被free掉了,,p= NULL,这样把指针内容清掉。
3.最不该的错误是2个,一个笔误把=写成了==,找了半个小时的bug,另一个是类型转换,漏掉一个&, PrintBTree((BTREE*) &delNode);//here I forget the sybol &
#include <stdio.h>
#define ISLCHILD 1
#define ISRCHILD 2 typedef int DATATYPE;
typedef struct treenode
{
DATATYPE data;
struct treenode *parent;
struct treenode *lchild;
struct treenode *rchild;
}TreeNode; typedef TreeNode* BTREE;
TreeNode* InitBTree(DATATYPE oriData[], int size);
//TreeNode * GetRootNode(DATATYPE data);
TreeNode * GetRootNode(DATATYPE data, TreeNode* newTreeNode);
TreeNode *InsertNode(TreeNode* parNode, DATATYPE data);
TreeNode *GetFixNode(BTREE *btree, DATATYPE data);
void PrintBTree(BTREE* btree);
void PrintTreeNode(TreeNode* );
void PrintViewTreeNode(TreeNode* treeNode, int num);
void PrintNTab(int i);
void DeleteNode(BTREE* btree, DATATYPE delData);
int IsLeafNode(TreeNode* Node);
TreeNode* GetNodePos(BTREE* btree, DATATYPE Data);
int IsLchild(TreeNode* pareNode, DATATYPE sonNode);
int IsHasOneChlid(TreeNode *Node);
int IsHasTwoChlid(TreeNode *Node); TreeNode* GetMaxNodePos(BTREE* btree);
void PreTravel(BTREE *btree);
//中序遍历
void PreTravel(BTREE *btree)
{
TreeNode* curTreeNode = *btree;
if(IsLeafNode(curTreeNode))
{
printf("%d ", curTreeNode->data);
}
else
{
if((*btree)->lchild!=NULL)
{
PreTravel((BTREE*)&((*btree)->lchild));
}
printf("%d ", curTreeNode->data);
if((*btree)->rchild!=NULL)
{
PreTravel((BTREE*)&((*btree)->rchild));
} }
return ;
} TreeNode* GetMaxNodePos(BTREE* btree)
{
TreeNode* maxTreeNode = *btree;
while(maxTreeNode)
{
printf("NodeValue[%d]\n", maxTreeNode->data);
printf("NodeValue[%d]\n", maxTreeNode->data);
printf("NodeValue[%d]\n", maxTreeNode->data); if(maxTreeNode->rchild == NULL)
{
break;
//return maxTreeNode;
}else{
maxTreeNode = maxTreeNode->rchild;
}
}
return maxTreeNode;
} /*1=> has 2 childrean*/
int IsHasTwoChlid(TreeNode *Node)
{
return ((Node->lchild!=NULL)&&(Node->rchild!=NULL));
} int IsHasOneChlid(TreeNode *Node)
{
if((Node->lchild !=NULL)&&(Node->rchild == NULL))
return ISLCHILD;
if((Node->lchild ==NULL)&&(Node->rchild != NULL))
return ISRCHILD;
return ;
} /* 1——> isLchild */
int IsLchild(TreeNode* pareNode, DATATYPE sonNode)
{
return (pareNode->lchild->data == sonNode);
}
TreeNode* GetNodePos(BTREE* btree, DATATYPE data)
{
//TreeNode* curTreeNode = (TreeNode*)malloc(sizeof(TreeNode));
TreeNode* curTreeNode = *btree;
while(//(curTreeNode->data!= data )
&&(curTreeNode != NULL))
{
if(data == curTreeNode->data)
{
break;
}
else if(data> curTreeNode->data)
{
curTreeNode = curTreeNode->rchild;
}
else if(data < curTreeNode->data)
{
curTreeNode = curTreeNode->lchild;
} }
return curTreeNode;
} /*1 -> isleaf*/
int IsLeafNode(TreeNode* Node)
{
return ((Node->lchild == NULL)&&(Node->rchild == NULL));
} /*
RULE:其删除一个节点需要考虑对应节点的状态,具体的说就是,是否存在左右节点,等等。需要按照以下情况讨论。 1.查找待删除节点,在查找的同时需要记录一下待删除节点的父亲。 2.如果待删除节点的左右节点都不存在,那么直接删除(叶子节点)。 3.如果待删除节点左子树存在右子树不存在,或者左子树不存在右子树存在。直接将其子树中存在的一边候补上来即可。 4.如果待删除节点左右子树都在,这个情况是最复杂的。需要按照二叉排序树的性质从其左子树或者有子树中选择节点补到待删除节点的位置。 如果从左子树中选,就应该选择左子树中最右边的那个叶子节点(这里肯定是叶子,如果不是叶子,那么就不是最右边的节点) 如果从右子树中选,就应该选择有子树中最左边的那个叶子节点。
*/
void DeleteNode(BTREE* btree, DATATYPE delData)
{
TreeNode *delNode = GetNodePos(btree, delData); if(delNode == NULL)
{
printf("delNode not exist.\n");
return ;
}
/*叶子节点*/
if(IsLeafNode(delNode))
{
printf("delNode is leaf node,del directly.\n");
if(IsLchild(delNode->parent, delData))
{
/*in left tree*/
delNode->parent->lchild = NULL;
delNode = NULL;
}
else
{
delNode->parent->rchild = NULL;
delNode = NULL;
}
return ; } /*只有一个孩子节点,直接删除*/
if(IsHasOneChlid(delNode) == ISLCHILD)
{
delNode->lchild->parent = delNode->parent;
/*judge the del is the left or right*/
if(IsLchild(delNode->parent, delNode->data))
{
delNode->parent->lchild = delNode->lchild; }
else
{
delNode->parent->rchild = delNode->lchild;
}
delNode = NULL;
return ;
}
else if(IsHasOneChlid(delNode) == ISRCHILD)
{
delNode->rchild->parent = delNode->parent;
/*judge the del is the left or right*/
if(IsLchild(delNode->parent, delNode->data))
{
delNode->parent->lchild = delNode->rchild; }
else
{
delNode->parent->rchild = delNode->rchild;
} delNode = NULL;
return ;
}
//有左右孩子节点,找出左/右中的最大/小的,替换删除的节点
/*I chose the left max to replace the delnode*/
if(IsHasTwoChlid(delNode))
{
#if 0
printf("TTTTTTTTTTTTTTTTTTTTTTTB\n");
PrintBTree((BTREE*) &delNode);//here I forget the sybol &
printf("TTTTTTTTTTTTTTTTTTTTTTTE\n");
#else
TreeNode* maxTreeNode = GetMaxNodePos((BTREE*)&delNode);
printf("MaxTreeNode[%d]\n", maxTreeNode->data);
maxTreeNode->parent->rchild = NULL;//here = writes to == then ^ ^
maxTreeNode->parent = NULL;
delNode->data = maxTreeNode->data;
maxTreeNode = NULL;
#endif
return ;
}
} void PrintNTab(int num)
{
int i = ; while(i<num)
{
printf(" ");
i++;
}
} void PrintViewTreeNode(TreeNode* treeNode, int num)
{
num++;
printf("%d", treeNode->data);
if(treeNode->lchild == NULL)
{
printf("\n");
PrintNTab(num);
printf("*");
}
else
{ printf("\n");
PrintNTab(num);
PrintViewTreeNode(treeNode->lchild, num);
}
if(treeNode->rchild == NULL)
{
printf("\n");
PrintNTab(num);
printf("&"); }
else
{
printf("\n");
PrintNTab(num);
PrintViewTreeNode(treeNode->rchild, num); } } /*这个看不出来树的结构了,需要重新写打印方法。*/
void PrintTreeNode(TreeNode* treeNode)
{
if((treeNode->lchild == NULL)
&&(treeNode->rchild == NULL))
{
printf("%d\n", treeNode->data);
}
else
{
if((treeNode->lchild != NULL)
|| (treeNode->rchild != NULL))
{
printf("%d ", treeNode->data);
if(treeNode->lchild != NULL)
{
printf("--->");
PrintTreeNode(treeNode->lchild);
}
printf("%d ", treeNode->data);
if(treeNode->rchild != NULL)
{
printf("===>");
PrintTreeNode(treeNode->rchild);
}
}
}
return ;
} void PrintBTree(BTREE* btree)
{
int num = ;
if(btree==NULL)
{
printf("empty tree.\n");
}
printf("TreeView Rule---若一个节点有左右孩子节点,则父节点一行一列,左右孩子不同行同一列,若无做孩子,则打印的数据用*代替,如果无有孩子则打印的数据用&代替"
"另外树的层次用4个空格来体现,比如第1列代表第一层,第5列代表第二层。\n"
);
printf("***********TREE View BEGIN***********\n");
//PrintTreeNode((*btree));
PrintViewTreeNode(*btree, num);
printf("\n");
printf("***********TREE View END ***********\n");
printf("\n"); printf("***********TREE View BEGIN***********\n");
printf("rules:\n\t---> lchild.\n\t ===> rchild\n");
PrintTreeNode(*btree);
printf("\n");
printf("***********TREE View END ***********\n"); } TreeNode* InitBTree(DATATYPE oriData[], int size)
{
BTREE* btree = NULL;
btree = (BTREE*)malloc(sizeof(BTREE));
*btree = (TreeNode*)malloc(sizeof(TreeNode));
int pos = size;
GetRootNode(oriData[], *btree);
TreeNode *posNode = (TreeNode*)malloc(sizeof(TreeNode));
while(pos>)
{
printf("********begin one*************\n");
printf("pos = [%d] index =[%d] data[%d]\n", pos, size-pos+, oriData[size-pos+]);
posNode = GetFixNode(btree, oriData[size-pos+]);
printf("Parent = [%d] Insert data=[%d] \n", posNode->data, oriData[size-pos+] );
InsertNode(posNode, oriData[size-pos+]);
pos--;
printf("********end one*************\n\n"); } printf("********btree data %d*************\n\n", (*btree)->data); return *btree; } TreeNode * GetRootNode(DATATYPE data, TreeNode* newTreeNode)
{
//newTreeNode = (TreeNode*)malloc(sizeof(TreeNode));
newTreeNode->data = data;
newTreeNode->parent = NULL;
newTreeNode->lchild = NULL;
newTreeNode->rchild = NULL;
return newTreeNode;
}
//将一个值插入节点的L/R子树上
TreeNode *InsertNode(TreeNode* parNode, DATATYPE data)
{
if(data == parNode->data)
{
printf("invaild data %d\n", data);
printf("invaild para here at line %d.\n", __LINE__);
return NULL;
}
TreeNode* sonTreeNode = (TreeNode*)malloc(sizeof(TreeNode));
sonTreeNode->data = data;
sonTreeNode->lchild = NULL;
sonTreeNode->rchild = NULL;
sonTreeNode->parent = parNode;//这里要不要考虑这个链接???
if(data < parNode->data)
{
parNode->lchild = sonTreeNode;
}
else{
parNode->rchild = sonTreeNode;
}
return sonTreeNode;
}
//查找合适的位置来插入新元素(find parent)
TreeNode *GetFixNode(BTREE *btree, DATATYPE data)
{
if((btree == NULL ))
{
return NULL;
} if(((*btree)->lchild == NULL)
&&((*btree)->rchild == NULL))
{
//InsertNode(*btree ,data);
printf("insert under root \n");
return *btree;
}
TreeNode* curTreeNode = (TreeNode*)malloc(sizeof(TreeNode));
curTreeNode = *btree;
while( (curTreeNode->lchild != NULL)
||(curTreeNode->rchild !=NULL) )
{
if(data > curTreeNode->data)
{
//printf("insert R \n");
printf(" data=[%d] curData=[%d] insert R \n", data, curTreeNode->data);
if(curTreeNode->rchild != NULL)
{
printf("curTreeNode->rchild != NULL rchild[%d]\n", curTreeNode->rchild->data);
curTreeNode = curTreeNode->rchild; }else{ break;
}
}
else if(data < curTreeNode->data)
{
printf(" data=[%d] curData=[%d] insert L \n", data, curTreeNode->data);
if(curTreeNode->lchild != NULL)
{
curTreeNode = curTreeNode->lchild; }else{ break;
}
}
else
{
printf("invaild elem here at line %d.\n", __LINE__);
return NULL;
} }
return curTreeNode; } int main(void)
{
printf("\tHello World!\n");
int arr[]={, , , ,, , , , , , , }; //int arr[5]={22, 11, 33, 15, 9};
BTREE *btree = NULL;
btree = (BTREE*)malloc(sizeof(BTREE));
*btree = (TreeNode*)malloc(sizeof(TreeNode));
*btree = InitBTree(arr, );
//*btree = InitBTree(arr, 5);
PrintBTree(btree);
TreeNode* curTreeNode = (TreeNode*)malloc(sizeof(TreeNode)); DeleteNode(btree, );
PrintBTree(btree);
printf("中序遍历:\n");
PreTravel(btree); return ;
}
运行结构也贴上来:
Hello World!
********begin one*************
pos = [12] index =[1] data[5]
insert under root
Parent = [4] Insert data=[5]
********end one*************
********begin one*************
pos = [11] index =[2] data[2]
data=[2] curData=[4] insert L
Parent = [4] Insert data=[2]
********end one*************
********begin one*************
pos = [10] index =[3] data[1]
data=[1] curData=[4] insert L
Parent = [2] Insert data=[1]
********end one*************
********begin one*************
pos = [9] index =[4] data[3]
data=[3] curData=[4] insert L
data=[3] curData=[2] insert R
Parent = [2] Insert data=[3]
********end one*************
********begin one*************
pos = [8] index =[5] data[6]
data=[6] curData=[4] insert R
curTreeNode->rchild != NULL rchild[5]
Parent = [5] Insert data=[6]
********end one*************
********begin one*************
pos = [7] index =[6] data[8]
data=[8] curData=[4] insert R
curTreeNode->rchild != NULL rchild[5]
data=[8] curData=[5] insert R
curTreeNode->rchild != NULL rchild[6]
Parent = [6] Insert data=[8]
********end one*************
********begin one*************
pos = [6] index =[7] data[9]
data=[9] curData=[4] insert R
curTreeNode->rchild != NULL rchild[5]
data=[9] curData=[5] insert R
curTreeNode->rchild != NULL rchild[6]
data=[9] curData=[6] insert R
curTreeNode->rchild != NULL rchild[8]
Parent = [8] Insert data=[9]
********end one*************
********begin one*************
pos = [5] index =[8] data[7]
data=[7] curData=[4] insert R
curTreeNode->rchild != NULL rchild[5]
data=[7] curData=[5] insert R
curTreeNode->rchild != NULL rchild[6]
data=[7] curData=[6] insert R
curTreeNode->rchild != NULL rchild[8]
data=[7] curData=[8] insert L
Parent = [8] Insert data=[7]
********end one*************
********begin one*************
pos = [4] index =[9] data[22]
data=[22] curData=[4] insert R
curTreeNode->rchild != NULL rchild[5]
data=[22] curData=[5] insert R
curTreeNode->rchild != NULL rchild[6]
data=[22] curData=[6] insert R
curTreeNode->rchild != NULL rchild[8]
data=[22] curData=[8] insert R
curTreeNode->rchild != NULL rchild[9]
Parent = [9] Insert data=[22]
********end one*************
********begin one*************
pos = [3] index =[10] data[11]
data=[11] curData=[4] insert R
curTreeNode->rchild != NULL rchild[5]
data=[11] curData=[5] insert R
curTreeNode->rchild != NULL rchild[6]
data=[11] curData=[6] insert R
curTreeNode->rchild != NULL rchild[8]
data=[11] curData=[8] insert R
curTreeNode->rchild != NULL rchild[9]
data=[11] curData=[9] insert R
curTreeNode->rchild != NULL rchild[22]
Parent = [22] Insert data=[11]
********end one*************
********begin one*************
pos = [2] index =[11] data[33]
data=[33] curData=[4] insert R
curTreeNode->rchild != NULL rchild[5]
data=[33] curData=[5] insert R
curTreeNode->rchild != NULL rchild[6]
data=[33] curData=[6] insert R
curTreeNode->rchild != NULL rchild[8]
data=[33] curData=[8] insert R
curTreeNode->rchild != NULL rchild[9]
data=[33] curData=[9] insert R
curTreeNode->rchild != NULL rchild[22]
data=[33] curData=[22] insert R
Parent = [22] Insert data=[33]
********end one*************
********btree data 4*************
TreeView Rule---若一个节点有左右孩子节点,则父节点一行一列,左右孩子不同行同一列,若无做孩子,则打印的数据用*代替,如果无有孩子则打印的数据用&代替另外树的层次用4个空格来体现,比如第1列代表第一层,第5列代表第二层。
***********TREE View BEGIN***********
4
2
1
*
&
3
*
&
5
*
6
*
8
7
*
&
9
*
22
11
*
&
33
*
&
***********TREE View END ***********
***********TREE View BEGIN***********
rules:
---> lchild.
===> rchild
4 --->2 --->1
2 ===>3
4 ===>5 5 ===>6 6 ===>8 --->7
8 ===>9 9 ===>22 --->11
22 ===>33
***********TREE View END ***********
delNode is leaf node,del directly.
TreeView Rule---若一个节点有左右孩子节点,则父节点一行一列,左右孩子不同行同一列,若无做孩子,则打印的数据用*代替,如果无有孩子则打印的数据用&代替另外树的层次用4个空格来体现,比如第1列代表第一层,第5列代表第二层。
***********TREE View BEGIN***********
4
2
1
*
&
3
*
&
5
*
6
*
8
7
*
&
9
*
22
*
33
*
&
***********TREE View END ***********
***********TREE View BEGIN***********
rules:
---> lchild.
===> rchild
4 --->2 --->1
2 ===>3
4 ===>5 5 ===>6 6 ===>8 --->7
8 ===>9 9 ===>22 22 ===>33
***********TREE View END ***********
中序遍历:
1 2 3 4 5 6 7 8 9 22 33
二叉排序树(B-Tree)-c实现的更多相关文章
- [BinaryTree] 二叉搜索树(二叉查找树、二叉排序树)
二叉查找树(BinarySearch Tree,也叫二叉搜索树,或称二叉排序树BinarySort Tree)或者是一棵空树,或者是具有下列性质的二叉树: (1)若它的左子树不为空,则左子树上所有结点 ...
- 【LeetCode-面试算法经典-Java实现】【109-Convert Sorted List to Binary Search Tree(排序链表转换成二叉排序树)】
[109-Convert Sorted List to Binary Search Tree(排序链表转换成二叉排序树)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 ...
- 二叉排序树:HUD3999-The order of a Tree(二叉排序树字典序输出)
The order of a Tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 二叉排序树(Binary Sort Tree)
1.定义 二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree).其定义为:二叉排序树或者是空树,或者是满足如下性质的二叉树: ① 若它的左子树 ...
- PAT-1099(Build A Binary Search Tree)Java实现+二叉排序树的中序遍历和层次遍历
Build A Binary Search Tree PAT-1099 本题有意思的一个点就是:题目已经给出了一颗排序二叉树的结构,需要根据这个结构和中序遍历序列重构一棵二叉排序树. 解法:可以根据中 ...
- 二叉排序树(Binary Sort Tree)
参考文章:http://blog.csdn.net/ns_code/article/details/19823463 不过博主的使用第一种方法操作后的树已经不是二叉排序树了,值得深思!! #inclu ...
- Recover Binary Search Tree,恢复二叉排序树
问题描述:题意就是二叉树中有两个节点交换了,恢复结构. Two elements of a binary search tree (BST) are swapped by mistake. Recov ...
- 108. Convert Sorted Array to Binary Search Tree 109. Convert Sorted List to Binary Search Tree -- 将有序数组或有序链表转成平衡二叉排序树
108. Convert Sorted Array to Binary Search Tree Given an array where elements are sorted in ascendin ...
- 99. Recover Binary Search Tree -- 找到二叉排序树中交换过位置的两个节点
Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...
- 算法学习记录-查找——二叉排序树(Binary Sort Tree)
二叉排序树 也称为 二叉查找数. 它具有以下性质: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值. 它的左.右子树也分别 ...
随机推荐
- Pyhton学习——Day24
# #面向对象设计:# def dog(name,gender,type):# def jiao(dog):# print('One Dog[%s],wfwfwf'%dog['name'])# def ...
- video标签实现简单视频背景+遇到问题(视频无法显示,不能自动播放)
最近看网上有一些网站首页背景是炫酷的视频背景,就想模拟一个 1.video标签简介 video标签定义视频,就是可以在网页上实现视频的播放,详情见http://www.w3school.com.cn/ ...
- laydate日期范围控制
1.html <input type="text" id="startTime" name="startTime" class=&qu ...
- HTML 捕获window.close() 并做窗口关闭前的处理工作
转自:http://www.xinotes.net/notes/note/261/ <html> <head> <script language="JavaSc ...
- vue自定义select组件
1.目的 看了很多element-ui的源码,决定自己实现一个简单的select组件,遇到的几个难点,便记录下来. 2.难点一 element-ui中的select组件通过v-model可以绑定数据, ...
- js数字转换为float,取N个小数
javascript中的变量都是弱类型,所有的变量都声明为var,在类型转换过程中就没有java那么方便,它是通过 parseInt(变量).parseFloat(变量)等方法来进行类型转换的.注意: ...
- Mysql学习总结(33)——阿里云centos配置MySQL主从复制
1.安装jdk1.8 首先确定没有安装过jdk 2.yum –y list java*查询系统自带的jdk安装包情况. 3.安装jdk1.8 4. 验证安装结果. 安装mysql 1. rpm -Uv ...
- sql server 与 mysql在自定以数据类型的区别
sql server 中可以使用 create TYPE postal_code FORM varchar(6) not null; 用于限定邮编的数据位数,他基于varchar数据类型 注意: ...
- SQL SERVER-安装和卸载
卸载后无法正常安装SQL SERVER 删除了本机的SQL SERVER以后,我发现我本机的SQL SERVER 再也安装不上了,这个一个比较严重的问题,要每天定时备份数据库到指定的地方才能防止数据丢 ...
- Hadoop学习;測试;启动bug;secondary合并edits到fsimage
一个Hadoop集群拥有多个并行的计算机.用以存储和处理大规模的数据集 Hadoop强调代码向数据迁移 要执行的程序在规模上比数据小的多,更easy移动,此外通过网络移动数据比载入执行程序更花时间,这 ...