user-0 提问: b-树传参问题

回复:
user: user-1
content: 因为我原以为SearchBtree中修改p时本来就需要修改传进来的*t

user: user-0
content: 引用 2 楼 zhao4zhong1 的回复:略改，不一定对，还需进一步调试： #include<stdio.h> #include<stdlib.h>  #define MAXM 10 typedef int KeyType; typedef struct node//B-树节点类型定义 { 	int	keynum; 	KeyType	key[MAXM];//key[1....keynum]存放关键字，key[0]不用 	struct node	*parent; 	struct node	*ptr[MAXM];//孩子节点指针数组ptr[0...keynum] }BTNode;  typedef struct//B-树的查找结果类型 { 	BTNode *pt;//指向找到的节点 	int	i;//1..m在节点中中的关键字序号 	int	tag;//1:查找成功 0:查找失败 }Result;    int m;   //m阶B-树 int Max; //m阶B-树每个节点的至多关键字个数，max=m-1; int Min;//m阶B-树非叶子节点的至少关键字个数，min=(m-1)/2  int Search(BTNode *p, KeyType k) { 	//在p->key[1.keynum]中查找i,使得p->key[i]<=k<p->key[i+1] 	int	i =	0; 	for	(i = 0;	i <	p->keynum&&p->key[i	+ 1] <=	k; i++); 	return i; }  Result SearchBTree(BTNode **t, KeyType k) { 	BTNode *p =	*t; 	BTNode *q =	NULL; 	int	found =	0,i	= 0; 	Result r; 	while (p !=	NULL&&found	== 0) 	{ 		i =	Search(p, k);//在p->key[1..keynum]中查找i,使得p->key[i]<=k<p->key[i+1] 		if (i>0	&& p->key[i] ==	k) 		{ 			found =	1; 		} 		else 		{ 			q =	p; 			p =	p->ptr[i];             *t=p; 		} 	} 	r.i	= i; 	if (found == 1)//查找成功 	{ 		r.pt = p; 		r.tag =	1; 	} 	else		 //查找失败，返回k的插入位置信息 	{ 		r.pt = q; 		r.tag =	0; 	} 	return r; }  void Insert(BTNode **q, int i, KeyType x, BTNode *ap) { 	int	j; 	for	(j = (*q)->keynum; j > i; j--) 	{ 		(*q)->key[j	+ 1] = (*q)->key[j]; 		(*q)->ptr[j	+ 1] = (*q)->ptr[j]; 	} 	(*q)->key[i	+ 1] = x; 	(*q)->ptr[i	+ 1] = ap;  	if (ap != NULL) 	{ 		ap->parent = *q; 	} 	(*q)->keynum++; }  void Split(BTNode **q, BTNode **ap) { 	//将节点q分裂成两个节点，前一半保留，后一半移入新生节点qp 	int	i, s = (m +	1) / 2; 	(*ap) =	(BTNode	*)malloc(sizeof(BTNode)); 	(*ap)->ptr[0] =	(*q)->ptr[s]; 	for	(i = s + 1;	i <= m;	i++) 	{ 		(*ap)->key[i - s] =	(*q)->key[i]; 		(*ap)->ptr[i - s] =	(*q)->ptr[i]; 		if ((*ap)->ptr[i - s] != NULL) 		{ 			(*ap)->ptr[i - s]->parent =	*ap; 		} 	} 	(*ap)->keynum =	(*q)->keynum - s; 	(*ap)->parent =	(*q)->parent; 	for	(i = 0;	i <	(*q)->keynum - s; i++) 	{ 		if ((*ap)->ptr[i] != NULL) 		{ 			(*ap)->ptr[i]->parent =	*ap; 		} 	} 	(*q)->keynum = s - 1; } BTNode NewRoot(BTNode **t,BTNode *p,KeyType x,BTNode *ap) { 	(*t) = (BTNode *)malloc(sizeof(BTNode)); 	(*t)->keynum = 1; 	(*t)->ptr[0] = p; 	(*t)->ptr[1] = ap; 	(*t)->key[1] = x; 	if (p != NULL) 	{ 		p->parent =	*t;//是*t 	} 	if (ap != NULL) 	{ 		ap->parent = *t; 	} 	(*t)->parent = NULL; }  void InsertBTree(BTNode **t,KeyType k,BTNode *q,int i) { 	BTNode *ap; 	int	finished, needNewRoot, s; 	KeyType	x; 	if (q == NULL) 	{ 		NewRoot(t,	NULL, k, NULL);//tshi空树，生成只含关键字k的根节点*t 	} 	else 	{ 		x =	k; 		ap = NULL; 		finished = needNewRoot = 0; 		while (needNewRoot == 0	&& finished	== 0) 		{ 			Insert(&q, i, x, ap); 			if (q->keynum <= Max) 			{ 				finished = 1; 			} 			else 			{ 				////分裂结点*q,将q->key[s+1..m],q->ptr[s..m]和q->recptr[s+1..m]移入新结点*ap 				s =	(m + 1)	- 2; 				Split(&q, &ap); 				x =	q->key[s]; 				if (q->parent) 				{ 					q =	q->parent; 					i =	Search(q, x); 				} 				else needNewRoot = 1; 			} 		} 		if (needNewRoot	== 1) 		{ 			NewRoot(t,	q, x, ap); 		} 	} }  void DispBTree(BTNode *t) { 	int	i; 	if (t != NULL) 	{ 		printf("["); 		for	(i = 1;	i <	t->keynum; i++) 		{ 			printf("%d", t->key[i]); 		} 		printf("%d", t->key[i]); 		printf("]"); 		if (t->keynum>0) 		{ 			if (t->ptr[0] != 0) 			{ 				printf("("); 			} 			for	(i = 0;	i <	t->keynum; i++) 			{ 				DispBTree(t->ptr[i]); 				if (t->ptr[i + 1] != NULL) printf(","); 			} 			DispBTree(t->ptr[t->keynum]); 			if (t->ptr[0] != 0)	printf(")"); 		} 	} }  int main() { 	BTNode *t =	NULL; 	Result s; 	int	j, n = 10; 	KeyType	a[]	= {	4, 9, 0, 1,	8, 6, 3, 5,	2, 7 }; 	KeyType	k; 	m =	3; 	Max	= m	- 1; 	Min	= (m - 1) /	2; 	printf("创建一颗%d阶的B-树:\n", m); 	for	(j = 0;	j <	n; j++) 	{ 		s =	SearchBTree(&t,	a[j]); 		if (s.tag == 0) 		{ 			InsertBTree(&t,a[j],s.pt,s.i); 		} 		printf("第%d步，插入%d", j + 1, a[j]); 		DispBTree(t); 		printf("\n"); 	} 	system("pause"); 	return 0;  } 谢谢赵四老师 把你给的代码里SearchBtree里的 加的那句*t=p删掉就正确了

user: user-1
content: 略改，不一定对，还需进一步调试： #include<stdio.h> #include<stdlib.h>  #define MAXM 10 typedef int KeyType; typedef struct node//B-树节点类型定义 { 	int	keynum; 	KeyType	key[MAXM];//key[1....keynum]存放关键字，key[0]不用 	struct node	*parent; 	struct node	*ptr[MAXM];//孩子节点指针数组ptr[0...keynum] }BTNode;  typedef struct//B-树的查找结果类型 { 	BTNode *pt;//指向找到的节点 	int	i;//1..m在节点中中的关键字序号 	int	tag;//1:查找成功 0:查找失败 }Result;    int m;   //m阶B-树 int Max; //m阶B-树每个节点的至多关键字个数，max=m-1; int Min;//m阶B-树非叶子节点的至少关键字个数，min=(m-1)/2  int Search(BTNode *p, KeyType k) { 	//在p->key[1.keynum]中查找i,使得p->key[i]<=k<p->key[i+1] 	int	i =	0; 	for	(i = 0;	i <	p->keynum&&p->key[i	+ 1] <=	k; i++); 	return i; }  Result SearchBTree(BTNode **t, KeyType k) { 	BTNode *p =	*t; 	BTNode *q =	NULL; 	int	found =	0,i	= 0; 	Result r; 	while (p !=	NULL&&found	== 0) 	{ 		i =	Search(p, k);//在p->key[1..keynum]中查找i,使得p->key[i]<=k<p->key[i+1] 		if (i>0	&& p->key[i] ==	k) 		{ 			found =	1; 		} 		else 		{ 			q =	p; 			p =	p->ptr[i];             *t=p; 		} 	} 	r.i	= i; 	if (found == 1)//查找成功 	{ 		r.pt = p; 		r.tag =	1; 	} 	else		 //查找失败，返回k的插入位置信息 	{ 		r.pt = q; 		r.tag =	0; 	} 	return r; }  void Insert(BTNode **q, int i, KeyType x, BTNode *ap) { 	int	j; 	for	(j = (*q)->keynum; j > i; j--) 	{ 		(*q)->key[j	+ 1] = (*q)->key[j]; 		(*q)->ptr[j	+ 1] = (*q)->ptr[j]; 	} 	(*q)->key[i	+ 1] = x; 	(*q)->ptr[i	+ 1] = ap;  	if (ap != NULL) 	{ 		ap->parent = *q; 	} 	(*q)->keynum++; }  void Split(BTNode **q, BTNode **ap) { 	//将节点q分裂成两个节点，前一半保留，后一半移入新生节点qp 	int	i, s = (m +	1) / 2; 	(*ap) =	(BTNode	*)malloc(sizeof(BTNode)); 	(*ap)->ptr[0] =	(*q)->ptr[s]; 	for	(i = s + 1;	i <= m;	i++) 	{ 		(*ap)->key[i - s] =	(*q)->key[i]; 		(*ap)->ptr[i - s] =	(*q)->ptr[i]; 		if ((*ap)->ptr[i - s] != NULL) 		{ 			(*ap)->ptr[i - s]->parent =	*ap; 		} 	} 	(*ap)->keynum =	(*q)->keynum - s; 	(*ap)->parent =	(*q)->parent; 	for	(i = 0;	i <	(*q)->keynum - s; i++) 	{ 		if ((*ap)->ptr[i] != NULL) 		{ 			(*ap)->ptr[i]->parent =	*ap; 		} 	} 	(*q)->keynum = s - 1; } BTNode NewRoot(BTNode **t,BTNode *p,KeyType x,BTNode *ap) { 	(*t) = (BTNode *)malloc(sizeof(BTNode)); 	(*t)->keynum = 1; 	(*t)->ptr[0] = p; 	(*t)->ptr[1] = ap; 	(*t)->key[1] = x; 	if (p != NULL) 	{ 		p->parent =	*t;//是*t 	} 	if (ap != NULL) 	{ 		ap->parent = *t; 	} 	(*t)->parent = NULL; }  void InsertBTree(BTNode **t,KeyType k,BTNode *q,int i) { 	BTNode *ap; 	int	finished, needNewRoot, s; 	KeyType	x; 	if (q == NULL) 	{ 		NewRoot(t,	NULL, k, NULL);//tshi空树，生成只含关键字k的根节点*t 	} 	else 	{ 		x =	k; 		ap = NULL; 		finished = needNewRoot = 0; 		while (needNewRoot == 0	&& finished	== 0) 		{ 			Insert(&q, i, x, ap); 			if (q->keynum <= Max) 			{ 				finished = 1; 			} 			else 			{ 				////分裂结点*q,将q->key[s+1..m],q->ptr[s..m]和q->recptr[s+1..m]移入新结点*ap 				s =	(m + 1)	- 2; 				Split(&q, &ap); 				x =	q->key[s]; 				if (q->parent) 				{ 					q =	q->parent; 					i =	Search(q, x); 				} 				else needNewRoot = 1; 			} 		} 		if (needNewRoot	== 1) 		{ 			NewRoot(t,	q, x, ap); 		} 	} }  void DispBTree(BTNode *t) { 	int	i; 	if (t != NULL) 	{ 		printf("["); 		for	(i = 1;	i <	t->keynum; i++) 		{ 			printf("%d", t->key[i]); 		} 		printf("%d", t->key[i]); 		printf("]"); 		if (t->keynum>0) 		{ 			if (t->ptr[0] != 0) 			{ 				printf("("); 			} 			for	(i = 0;	i <	t->keynum; i++) 			{ 				DispBTree(t->ptr[i]); 				if (t->ptr[i + 1] != NULL) printf(","); 			} 			DispBTree(t->ptr[t->keynum]); 			if (t->ptr[0] != 0)	printf(")"); 		} 	} }  int main() { 	BTNode *t =	NULL; 	Result s; 	int	j, n = 10; 	KeyType	a[]	= {	4, 9, 0, 1,	8, 6, 3, 5,	2, 7 }; 	KeyType	k; 	m =	3; 	Max	= m	- 1; 	Min	= (m - 1) /	2; 	printf("创建一颗%d阶的B-树:\n", m); 	for	(j = 0;	j <	n; j++) 	{ 		s =	SearchBTree(&t,	a[j]); 		if (s.tag == 0) 		{ 			InsertBTree(&t,a[j],s.pt,s.i); 		} 		printf("第%d步，插入%d", j + 1, a[j]); 		DispBTree(t); 		printf("\n"); 	} 	system("pause"); 	return 0;  }

user: user-2
content: 代码太长了，懒得看啊。。。你直接说说你的需求不行么。