`
shinepengwei
  • 浏览: 45789 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

2-3树的插于及删除操作源代码

阅读更多

可以运行。设计了测试用例覆盖了所有的情况,测试后结果正确。

2-3树具体的讲解请看文档,文档是东南大学邓建明老师上课使用的。

 

 

测试插入{11,22,34,42,6,3,28,24,36 }


删除28:


删除36:


 

//f.h
#include <stdio.h>
#include <malloc.h>
#define NUM 10
#define INTERIOR 0
#define LEAF 1
#define FALSE 0
#define TRUE 1
typedef struct Node//节点
{
	int type;
	int key;
	int low2;
	int low3;
	struct Node * son1;
	struct Node * son2;
	struct Node * son3;
}TreeNode,*BiTree;
typedef struct sNode
{
	struct sNode *preNode;
	BiTree pTree;
}StackNode, *BiStack;
typedef struct stackn
{
	BiStack head;
	BiStack tail;
}Stacks,*Stack;
Stack stack;
void push(BiTree bt){
	BiStack bs=(BiStack)malloc(sizeof(StackNode));
	bs->preNode=stack->head;
	bs->pTree=bt;
	stack->head=bs;
}
BiTree pop(){
	if (stack->head == stack->tail)
	{
		return NULL;
	}
	BiTree bt=stack->head->pTree;
	BiStack bs=stack->head;
	if (bs!=stack->tail)
	{
		stack->head=bs->preNode;
	}
	free(bs);
	return bt;
}
void clean(){
	while(stack->head!=stack->tail){
		BiStack tmp=stack->head;
		stack->head=stack->head->preNode;
		free(tmp);
	}
}

BiTree createNode(int type,int key){
	BiTree t=(BiTree)malloc(sizeof(TreeNode));
	t->type=type;
	t->low2=t->low3=0;
	t->son1=t->son2=t->son3=NULL;
	t->key=key;
	return t;
}
/************************************************************************/
/* 
input:
	x		:	the leaf node to insert
	tp		:	the tree or the sun tree x will insert to
	pback:	:	null - the function is complete. if it is not null, it means
				a bother node of tp, it is created in the function because 
				tp has three sun node,so the function created it to stored 
				new node;It is used for father node(out function) to coordinate
				the tree;
				the node is right to tp
output:
	lowBack:	it is the least key number of the nodes of pback;
*/
/************************************************************************/
int addson(BiTree x,BiTree* tp_point,BiTree *pBack){
	BiTree tp=*tp_point;
	int low_back=0;
	if (tp->type == LEAF)
	{
		if (tp->key > x->key)
		{
			BiTree tmp=x;
			x=tp;
			(*tp_point)=tmp;
		}
		*pBack=x;
		return (*pBack)->key;
	}
	//tp node is a interior node
	int child;//it means which child node to insert;
	BiTree tp_next;
	if (x->key < tp->low2)
	{
		child =1;
		tp_next=tp->son1;
	}
	else if (x->key <tp->low3 || (tp->low3 ==0&&tp->son3 == NULL))
	{
		child =2;
		tp_next=tp->son2;
	}
	else
	{
		child =3;
		tp_next=tp->son3;
	}
	BiTree pNewBack=NULL;
	//set the tp_next as the tree to insert
	//iterate the function until dealing with the leaf node 
	int low_number=addson(x,&tp_next,&pNewBack);
	if (pNewBack != NULL)
	{
		if (tp->son3 == NULL)//if tp only have two child node, the new node which is create in the iteration function can be stored by tp node
		{
			if (child ==1)
			{
				tp->son3=tp->son2;
				tp->son2=pNewBack;
				tp->son1=tp_next;//tp_next is a pointer who point to the node/tree to insert
				tp->low3=tp->low2;
				tp->low2=low_number;
			}
			else//child == 2
			{
				tp->son3=pNewBack;
				tp->son2=tp_next;
				tp->low3=low_number;
			}

		}
		else{
			//tp have three child node so a new interior node(tp's right bother) should be create to store the new child node
			*pBack=createNode(INTERIOR,0);
			if (child ==1)
			{
				(*pBack)->son1=tp->son2;
				(*pBack)->son2=tp->son3;
				tp->son2=pNewBack;
				tp->son1=tp_next;

				tp->son3=NULL;

				(*pBack)->low2=tp->low3;
				low_back=tp->low2;

				tp->low2=low_number;
				tp->low3=0;
			}
			else if (child == 2)
			{
				(*pBack)->son1=pNewBack;
				(*pBack)->son2=tp->son3;
				tp->son2=tp_next;
				tp->son3=NULL;

				(*pBack)->low2=tp->low3;
				tp->low3=0;
				low_back=low_number;
			}
			else
			{
				//child ==3
				(*pBack)->son1=tp_next;
				(*pBack)->son2=pNewBack;
				tp->son3=NULL;
				(*pBack)->low2=low_number;
				low_back=tp->low3;
				tp->low3=0;
			}

		}
	}
	return low_back;
}
void insert(int key,BiTree *ts){
	BiTree tree=*ts;
	BiTree x=createNode(LEAF,key);
	if (tree == NULL)//如果2-3树为空树
	{
		*ts=x;
		return;
	}
	BiTree tp=tree;
	BiTree pBack=NULL;
	int low_number=addson(x,&tp,&pBack);
	if (pBack!=NULL)
	{
		//create a new interior node used as the new tree node
		BiTree newHead=createNode(INTERIOR,0);
		newHead->low2=low_number;
		newHead->son1=tp;
		newHead->son2=pBack;
		*ts=newHead;
	}
	return;
}
/************************************************************************/
/*
find the node to delete by key.On the same time,stack will store the router of nodes which have been searched.
intup:
	key		:	the key of the node which is supposed to delete
	tree	:	the tree to search for the node to delete
	p		:	point to a node whose low2 or low3 equal to the key to delete
output:
	if a node is searched successfully,return true;otherwise return false;
*/
/************************************************************************/
bool find_node(int key,BiTree tree,BiTree *p){
	if (tree==NULL)
	{
		return false;
	}
	push(tree);
	if (tree->type == LEAF)
	{
		if (tree->key == key)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	if (key==tree->low2 || key ==tree->low3)
	{
		*p=tree;
	}
	if (key<tree->low2)
	{
		find_node(key,tree->son1,p);
	}
	else if (key == tree->low2 || key<tree->low3||tree->low3==0)
	{
		find_node(key,tree->son2,p);
	}
	else{
		find_node(key,tree->son3,p);
	}
}
void changePpoint(BiTree a,BiTree p,int key){
	if (p->low2==a->key)
	{
		p->low2=key;
	}else{
		p->low3=key;
	}
}
int getLeastKey(BiTree t){
	if (t->type==INTERIOR)
	{
		return getLeastKey(t->son1);
	}else{
		return t->key;
	}
}
void deleteNode(BiTree *a_pointer,BiTree *f_pointer,BiTree *ff_pointer,BiTree p,BiTree *t_pointer){
	
	BiTree a=*a_pointer;
	printf("delete node begin! ");
	printf("node:%d %d %d %d\n",a->key,a->low2,a->low3,a->type);
	BiTree f=*f_pointer;
	BiTree ff=*ff_pointer;
	BiTree tLeft=NULL;
	BiTree tRight=NULL;
	int fchild=0;
	int achild=0;
	if (a==f->son1)
	{
		achild=1;
	}
	else if (a==f->son2)
	{
		achild=2;
	}
	else{
		achild=3;
	}
	if (f->low3!=0)//father node have three child node;
	{
		if (a==f->son3)
		{
			f->son3=NULL;
			f->low3=0;
			free(a);
		}
		else if (a==f->son2)
		{
			f->low2=f->low3;
			f->low3=0;
			f->son2=f->son3;
			f->son3=NULL;
			free(a);
		}
		else if (a==f->son1)
		{
			if (a->type==LEAF&&p!=NULL)
			{
				changePpoint(a,p,f->low2);
			}
			f->low2=f->low3;
			f->low3=0;
			f->son1=f->son2;
			f->son2=f->son3;
			f->son3=NULL;
			free(a);
		}
		else
		{
			printf("err:a不是f的子节点。\n");
		}
	}
	else{//father node have two child node,a =1,2
		BiTree b=NULL;
		if (achild ==1)
		{
			b=f->son2;
		}
		else{
			b=f->son1;
		}
		if (ff==NULL)//f is the root node
		{
			*t_pointer=b;
			free(a);
			free(f);
			return;
		}

		if (f==ff->son1)
		{
			tRight=ff->son2;
			fchild=1;
		}
		else if (f==ff->son2)
		{
			tLeft=ff->son1;
			tRight=ff->son3;
			fchild=2;
			//ff->low2=getLeastKey(f);
		}
		else if (f == ff->son3)
		{
			tLeft=ff->son2;
			fchild=3;
			//ff->low3=getLeastKey(f);
		}
		else{
			printf("err1:f not a child node of ff!\n");
		}

		//获得了父节点左右的分支,开始根据四种情况处理
		if (tLeft!=NULL&&tLeft->low3!=0)
		{//父节点由一个兄弟节点在左边,并且有三个子节点. done!
			f->son2=b;
			f->son1=tLeft->son3;
			tLeft->son3=NULL;
			if (a->type=LEAF&&a->key<b->key&&p!=NULL)
			{
				changePpoint(a,p,tLeft->low3);
			}
			int tmp=0;
			if (fchild==2)
			{
				tmp=ff->low2;
				ff->low2=tLeft->low3;
			}
			else{
				tmp=ff->low3;
				ff->low3=tLeft->low3;
			}
			if (achild=2)//如果a是父节点的第二个孩子,则b为第一个孩子,将b改为f的第二个字孩子以后,可以从ff中获得b的最小节点值。
			{
				f->low2=tmp;
			}
			tLeft->low3=0;
			free(a);
		}
		else if (tRight!=NULL&&tRight->low3!=0)
		{
			f->son1=b;
			f->son2=tRight->son1;
			tRight->son1=tRight->son2;
			tRight->son2=tRight->son3;
			tRight->son3=NULL;
			if (a->type=LEAF&&a->key<b->key&&p!=NULL)
			{
				changePpoint(a,p,b->key);
			}
			int tmp=0;
			if (fchild==1)
			{
				tmp=ff->low2;
				ff->low2=tRight->low2;
			}else{
				tmp=ff->low3;
				ff->low3=tRight->low2;
			}
			f->low2=tmp;
			if (tmp!=getLeastKey(f->son2))
			{
				printf("err:not equal to getLeastKey:2~");
			}
			//f->low2=getLeastKey(f->son2);
			tRight->low2=tRight->low3;
			tRight->low3=0;
			free(a);
		}
		else if (tLeft!=NULL)//左侧兄弟节点有两个儿子
		{
			tLeft->son3=b;
			if (achild==2)//修改tleft->low3
			{
				int tmp=0;
				if (fchild==2)
				{
					tmp=ff->low2;
				}
				else{
					tmp=ff->low3;
				}
				tLeft->low3=tmp;
			}
			else{
				tLeft->low3=f->low2;
			}
			*a_pointer=*f_pointer;
			*f_pointer=*ff_pointer;
			BiTree bitmp=pop();
			*ff_pointer=bitmp;
			free(a);
			deleteNode(a_pointer,f_pointer,ff_pointer,p,t_pointer);
		}
		else{//右侧兄弟节点有两个儿子
			tRight->son3=tRight->son2;
			tRight->son2=tRight->son1;
			tRight->son1=b;
			if (a->type=LEAF&&a->key<b->key&&p!=NULL)
			{
				changePpoint(a,p,b->key);
			}
			tRight->low3=tRight->low2;
			if (fchild==1)
			{
				tRight->low2=ff->low2;
			}else{
				tRight->low2=ff->low3;
			}
			*a_pointer=*f_pointer;
			*f_pointer=*ff_pointer;
			BiTree bitmp=pop();
			*ff_pointer=bitmp;
			free(a);
			deleteNode(a_pointer,f_pointer,ff_pointer,p,t_pointer);
		}
		

	}
	//删除节点的父节点的对于该节点的low信息不需要使用
}

int deletes(int key,BiTree *t){
	BiTree tree=*t;
	BiTree p=NULL;//point to a node whose low2 or low3 equal to the key to delete
	clean();
	if (tree==NULL||!find_node(key,tree,&p))
	{
		return FALSE;
	}
	if (tree->type=LEAF&&tree->key == key)
	{
		free(tree);
		*t=NULL;
	}
	BiTree a=pop();//the LEFT node
	BiTree f=pop();//father node
	BiTree ff=pop();//father node 's father node
	deleteNode(&a,&f,&ff,p,t);
	return TRUE;
}

//main.cpp

#include "f.h"
void main(){
	stack=(Stack)malloc(sizeof(Stacks));
	stack->tail=(BiStack)malloc(sizeof(StackNode));
	stack->tail->preNode=NULL;
	stack->tail->pTree=NULL;
	stack->head=stack->tail;
	//for the delete function
	BiTree t=NULL;//指向2-3树根节点
	int inputs=1;
	int input_set[10]={11,22,34,42,6,3,28,24,36,9};
	for (int i=0;i<10;i++)
	{
		insert(input_set[i],&t);
	}
	/*
	while (inputs!=0)
	{
		printf("\n请输入一个正整数插入到2-3树中:");
		scanf("%d",&inputs);
		if (inputs!=0)
		{
			insert(inputs,&t);
		}
	}*/
	int key=-1;
	int key_set[9]={28,36,24,34,6,3,22,42,11};
	deletes(11,&t);
	/*
	for (int i=0;i<6;i++)
	{
		if (i==14)
		{
			int sss=0;
		}
		if (!deletes(key_set[i],&t))
		{
			printf("there is no node in the tree you want to delete");
		}
	}
	/*
	while(key!=0){
		printf("\n请输入要删除节点的key值:");
		scanf("%d",&key);
		
		if (!deletes(key,&t))
		{
			printf("there is no node in the tree you want to delete");
		}
		
	}*/
	int s;
}
  • 大小: 18.9 KB
  • 大小: 22.7 KB
  • 大小: 18.5 KB
分享到:
评论

相关推荐

    算法-理论基础- 索引- 2-3 树(包含源程序).rar

    2-3树是B树的一种特殊形式,它在查找、插入和删除等操作中保持了数据的有序性,同时通过内部节点的2个或3个子节点来提高平衡性能。以下将详细介绍2-3树的概念、特性、操作以及在实际中的应用。 1. **2-3树的概念** ...

    B-树的源代码

    在这个“B-树的源代码”项目中,开发者使用C++语言实现了B-树的基本操作,包括构造、查找、插入和删除节点。C++是一种广泛应用的面向对象编程语言,具有高效和灵活的特点,适合编写这种底层数据结构的代码。 B-树的...

    B-树和B+树的源代码

    B-树(Balanced Tree)和B+树是两种常见的自平衡的多路搜索树,广泛应用于数据库和文件系统中,以优化大容量数据的访问效率。这两种数据结构都是为了在磁盘等慢速存储设备上实现高效的查找、插入和删除操作。 B-树...

    B- B-树算法实现

    B-树(B-tree)是一种自平衡的树数据结构,特别适用于大型数据库和文件系统,因为它能够保持数据有序,便于快速查找、插入和删除操作。在本项目中,我们将深入探讨B- B-树(通常指的是B-树或B+树)的实现,并以C语言...

    2-3-tree:2-3树数据结构的简单演示

    在给定的压缩包文件"2-3-tree-master"中,很可能包含了C++实现2-3树的源代码。这个代码库可能包括了节点类的定义、插入、查找和删除等操作的实现,以及相关的测试用例,帮助用户理解和学习2-3树的工作原理。 通过...

    b+/-树的实现源代码

    3. **平衡性质**:B-树的高度保持较低,确保查找、插入和删除操作的效率,时间复杂度接近O(log n)。 4. **叶子节点**:所有叶子节点都通过指针链相连,便于顺序遍历所有数据。 **B+树(B+Tree)** 1. **扩展B-树**...

    sqllite3源代码

    通过分析和理解这个源代码,开发者不仅可以定制SQLite3的行为,还可以深入学习数据库引擎的工作原理,如查询计划的生成、B树数据结构的实现、事务管理等。这对于数据库开发、软件工程以及嵌入式系统的开发者来说,都...

    红黑树-附C代码

    在"rbtree-master"这个压缩包中,很可能包含了红黑树的C语言实现源代码,包括数据结构定义、插入、删除、查找等操作的函数,以及可能的测试用例和示例。通过学习和理解这些源代码,你可以深入了解红黑树的内部工作...

    数据结构课程设计--文件索引(B-树)

    数据结构是计算机科学中的核心课程,它...KCSJ文件很可能是你的源代码或文档,对于学习和参考会有很大帮助。在实际开发中,结合数据库理论,B-树还可以应用于更复杂的数据索引场景,例如数据库的主键索引和区间查询。

    b+b-树c语言版

    在压缩包内的文件“140201021022张瑞强”中,很可能是包含了C语言实现的源代码。通过阅读和理解这些代码,你可以更深入地了解B+树的内部工作机制,以及如何在实际编程中应用这种数据结构。 总结,这个压缩包提供了...

    根据算法导论写的b-树源代码

    使用《算法导论》中的2-3-4树策略,使得删除操作相对于仅使用2-3树更简单,因为2-3-4树允许节点有更多种类的状态,简化了调整树结构的过程。 总之,这个项目为理解和实践B-树提供了一个很好的实例,对于学习数据...

    算法-理论基础- 树- 树的存储结构(包含源程序).rar

    这个压缩包"算法-理论基础- 树- 树的存储结构(包含源程序).rar"提供了一个关于树的存储结构的理论基础和实际源代码,对于学习和理解树的实现具有很高的价值。 树的基本概念: 树是一种非线性的数据结构,由一个或...

    字典源代码--JAVA关于小字典的几个源代码

    2. **HashMap**: HashMap是基于哈希表实现的,提供了快速的平均时间复杂度为O(1)的插入、删除和查找操作。键和值可以是任何对象,但键必须是唯一的。 3. **TreeMap**: TreeMap基于红黑树数据结构,保持键的自然排序...

    sqlite-source-3_6_20 C语言 源代码

    这个压缩包"sqlite-source-3_6_20"包含了SQLite在3.6.20版本时的完整源代码,这对于想要深入理解SQLite工作原理、进行定制开发或者在没有预编译库的情况下构建SQLite的人来说是宝贵的资源。 1. **btree.c**: 这个...

    数据结构c++-源代码

    在这个"数据结构C++-源代码"的压缩包中,我们很可能会找到一系列用于实现各种数据结构的C++源代码。 1. **数组**:数组是最基本的数据结构,它是一个元素类型相同的集合,可以通过索引访问。在C++中,数组可以是一...

    数据结构课程设计-源代码

    源代码可能会包括一维数组、二维数组的实现,以及关于数组操作的函数,如插入、删除、搜索等。 2. **链表**:链表是一种动态数据结构,每个元素(节点)包含数据和指向下一个节点的指针。链表分为单链表、双链表和...

    《数据结构》算法实现及解析--高一凡,书及源代码

    1. 可能包含每个数据结构(如链表、栈、队列、树、图等)的创建、插入、删除、查找等操作的代码示例。 2. 各种排序和查找算法的实现,以及性能测试。 3. 指针在实际数据结构实现中的应用,如用指针实现链表的动态...

    红黑树C源代码

    这个“红黑树C源代码”可能包含了红黑树节点结构定义、插入函数、删除函数、查找函数以及相关的平衡调整算法。通过阅读和理解源代码,可以深入学习红黑树的实现细节,对于理解和掌握数据结构与算法有着极大的帮助。...

    数据结构--各章节源代码

    1. `cdat`:这个文件可能是关于链表或树的数据结构实现,可能包含了创建、插入、删除等操作。链表是一种动态数据结构,而树则用于表示层次关系,如二叉搜索树、AVL树、红黑树等。 2. `bbknap.cpp`:这个名字暗示了...

Global site tag (gtag.js) - Google Analytics