user-0 提问: c++二叉树

回复:
user: user-1
content: 建议用C++的新特性定义结构（和类其实区别不多） typedef struct ThrTreeNode {//线索化二叉树类型 int info;  int ltag, rtag;//左右线索 struct ThrTreeNode *llink, *rlink;//左右后继  ThrTreeNode()//new 的时候自动调用构造函数,减少重复代码 { info=0; ltag=0; rtag=0; llink=NULL; rlink=NULL; };  };

user: user-0
content: 好的谢谢两位大佬了，是我才疏学浅，万分感谢！

user: user-2
content: 指针是无法修改自身的，但你可以通过这个指针修改它的成员，我用递归写了两种方法你可以对比一下  #include <iostream> #define num 500//二叉树结点最大个数 using namespace std;  struct ThrTreeNode {//线索化二叉树类型 	int info; 	int ltag, rtag;//左右线索 	struct ThrTreeNode* llink, * rlink;//左右后继 };  ThrTreeNode* insertTree(struct ThrTreeNode**, int);//给二叉树赋值  int main() { 	struct ThrTreeNode* T = NULL;//创建空线索二叉树根 	int data[num]; 	int i; 	for (i = 0; i < num; i++) { 		data[i] = -1; 	} 	cout << "请输入您想存入此线索二叉树的一组数据（个数小于500）："; 	for (i = 0; i < num; i++) {//输入线索二叉树各结点的值 		cin >> data[i]; 		if (cin.get() == '\n') 			break; 	} 	i = 0; 	while (data[i] != -1) {//初始化二叉树 		T=insertTree(&T, data[i]); 		i++; 	} 	return 0; }  ThrTreeNode* insertTree(struct ThrTreeNode** T, int a) {//初始化二叉树 	if (*T == NULL)			//由于要修改T的值，所以用ThrTeeNode** 		*T = new ThrTreeNode({ a,0,0,NULL,NULL }); 	else { 		if (a > (*T)->info)  			(*T)->rlink = insertTree(&(*T)->rlink, a);	 		else 			(*T)->llink = insertTree(&(*T)->llink, a); 	} 	return *T; } [code=c] #include <iostream> #define num 500//二叉树结点最大个数 using namespace std;  struct ThrTreeNode {//线索化二叉树类型 	int info; 	int ltag, rtag;//左右线索 	struct ThrTreeNode* llink, * rlink;//左右后继 };  ThrTreeNode* insertTree(struct ThrTreeNode*, int);//给二叉树赋值  int main() { 	struct ThrTreeNode* T = NULL;//创建空线索二叉树根 	int data[num]; 	int i; 	for (i = 0; i < num; i++) { 		data[i] = -1; 	} 	cout << "请输入您想存入此线索二叉树的一组数据（个数小于500）："; 	for (i = 0; i < num; i++) {//输入线索二叉树各结点的值 		cin >> data[i]; 		if (cin.get() == '\n') 			break; 	} 	i = 0; 	while (data[i] != -1) {//初始化二叉树 		T=insertTree(T, data[i]); 		i++; 	} 	return 0; }  ThrTreeNode* insertTree(struct ThrTreeNode* T, int a) {//初始化二叉树 	if (T == NULL)		 		T = new ThrTreeNode({ a,0,0,NULL,NULL }); 	else { 		if (a > T->info)		//这里通过返回值修改T的左右孩子，并未修改T 			T->rlink = insertTree(T->rlink, a);	 		else 			T->llink = insertTree(T->llink, a); 	} 	return T; }   [/code]

user: user-1
content: 引用 楼主 jiliangsui 的回复:有没有大佬帮我看看我这个简单的二叉树赋值到底哪里不对啊，系统一直提示NULL指针的，但是我明明new分配空间了啊 ！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！1  #include <iostream> #define num 500//二叉树结点最大个数 using namespace std;  struct ThrTreeNode {//线索化二叉树类型 	int info; 	int ltag, rtag;//左右线索 	struct ThrTreeNode *llink, *rlink;//左右后继 };  void insertTree(struct ThrTreeNode*, int);//给二叉树赋值  int main(){ 	struct ThrTreeNode* T = NULL;//创建空线索二叉树根 	int data[num]; 	int i; 	for (i = 0; i < num; i++) { 		data[i] = -1; 	} 	cout << "请输入您想存入此线索二叉树的一组数据（个数小于500）："; 	for (i = 0; i < num; i++) {//输入线索二叉树各结点的值 		cin >> data[i]; 		if (cin.get() == '\n') 			break; 	} 	i = 0; 	while (data[i] != -1) {//初始化二叉树 		insertTree(T, data[i]); 		i++; 	} }  void insertTree(struct ThrTreeNode* T, int a) {//初始化二叉树 	struct ThrTreeNode* p = T; 	if (p == NULL) {//对线索二叉数的根赋值 		p = new struct ThrTreeNode; 		p->info = a; 		p->ltag = 0;//未线索化前，左右线索值默认为0 		p->rtag = 0; 		p->llink = NULL; 		p->rlink = NULL; 	} 	else {                      //添加临时指向父节点的指针                           struct ThrTreeNode* parent=NULL;                            int leftorright=0; 		while (p != NULL) { parent=p;  			if (a > p->info) {//若该值大于该结点值，进入其右子树                                 				p = p->rlink;                                                                 leftorright=0; 			} 			else//若该值小于等于该结点值，进入其左子树 			p = p->llink;                         leftorright=1; 		} p = new struct ThrTreeNode;  if(leftorright>0) { 		parent->llink=p; } else { 	        parent->rlink=p;  } 		p->info = a; 		p->ltag = 0;//未线索化前，左右线索值默认为0 		p->rtag = 0; 		p->llink = NULL; 		p->rlink = NULL; 	} }  p=p->llink;重新分配p并不影响原来p->llink的指向，他指向的还是NULL

user: user-0
content: T的info是正常的，但是T的llink和rlink全是NULL值

user: user-0

user: user-0
content: 大佬我照着你的这个做，还是报错NULL指针啊啊，我原来做的一个学生管理系统也是我这种方法做的，就可以。。。我也不知道为什么。。。

user: user-2
content: 引用 3 楼 jiliangsui 的回复:还有我照着你的改了用二重指针改一重指针，但还是报错null 你的操作就像是拿纸把图书馆的地址给记下来，然后自己用橡皮擦擦了纸上的内容重写，难道图书馆会因为你那张纸而改变地址？你这是在自欺欺人

user: user-2
content: p只是一个用来存地址的指针，你只是修改了p存的地址，不是修改所存地址的内容  #include <iostream> #define num 500//二叉树结点最大个数 using namespace std;  struct ThrTreeNode {//线索化二叉树类型 	int info; 	int ltag, rtag;//左右线索 	struct ThrTreeNode* llink, * rlink;//左右后继 };  void insertTree(struct ThrTreeNode**, int);//给二叉树赋值  int main() { 	struct ThrTreeNode* T = NULL;//创建空线索二叉树根 	int data[num]; 	int i; 	for (i = 0; i < num; i++) { 		data[i] = -1; 	} 	cout << "请输入您想存入此线索二叉树的一组数据（个数小于500）："; 	for (i = 0; i < num; i++) {//输入线索二叉树各结点的值 		cin >> data[i]; 		if (cin.get() == '\n') 			break; 	} 	i = 0; 	while (data[i] != -1) {//初始化二叉树 		insertTree(&T, data[i]); 		i++; 	} 	return 0; }  void insertTree(struct ThrTreeNode** T, int a) {//初始化二叉树 	struct ThrTreeNode* p = *T; 	if (p == NULL) {//对线索二叉数的根赋值 		p = new struct ThrTreeNode; 		p->info = a; 		p->ltag = 0;//未线索化前，左右线索值默认为0 		p->rtag = 0; 		p->llink = NULL; 		p->rlink = NULL; 		*T = p; 	} 	else { 		while (p != NULL) { 			if (a > p->info) {//若该值大于该结点值，进入其右子树 				p = p->rlink; 			} 			else//若该值小于等于该结点值，进入其左子树 				p = p->llink; 		} 		p = new struct ThrTreeNode; 		p->info = a; 		p->ltag = 0;//未线索化前，左右线索值默认为0 		p->rtag = 0; 		p->llink = NULL; 		p->rlink = NULL; 	} }

user: user-0
content: 还有我照着你的改了用二重指针改一重指针，但还是报错null

user: user-0
content: 这个时候难道不是p和T指向的是同一个结点吗，修改了p也就修改了T，我们老师原来这么说的，看了你的博文，我还是怎么觉得，qaq。。。

user: user-2
content: 修改insert函数，看注释，对指针的理解不是很清楚，其实把初始化和insert分开是最好的 我写了一篇简述指针的博文，你看一下有没有帮助 https://blog.csdn.net/qq_40946921/article/details/90047918  void insertTree(struct ThrTreeNode** T, int a) {	//因为根结点是new出来的，即修改了根节点的值，所以要用根节点的指针 	struct ThrTreeNode *p = *T; 	if (p == NULL) { 		p = new struct ThrTreeNode; 		p->info = a; 		p->ltag = 0; 		p->rtag = 0; 		p->llink = NULL; 		p->rlink = NULL; 		*T = p;		/*你这里需要修改T，因为上方你已经将p（不是T）重新赋值*/ 	} 	else { 		while (p != NULL) { 			if (a > p->info) { 				p = p->rlink; 			} 			else 				p = p->llink; 		} 		p = new struct ThrTreeNode; 		p->info = a; 		p->ltag = 0;//未线索化前，左右线索值默认为0 		p->rtag = 0; 		p->llink = NULL; 		p->rlink = NULL; 	} }