数据结构课程设计-二叉树操作系统

二叉树基本操作(头文件):
//二叉树的创建
void CreateBiTree(BTNode **root)                ///二级指针作为函数参数
{                                                               ///void CreateBiTree(BiTree &root)       //引用类型的参数
    char ch;                                   ///要插入的数据
    scanf("\n%c", &ch);                    ///cin>>ch;
    if(ch=='#')                                                 ///BiTree *CreateBiTree()         //返回结点指针类型
        *root = NULL;
    else
    {
        *root = (BTNode *)malloc(sizeof(BTNode));
        (*root)->data = ch;
        CreateBiTree(&((*root)->lchild));
        CreateBiTree(&((*root)->rchild));
    }
}

void Pre_order_Creat_Btree(BTree *root)    //仿先序遍历创建二叉树
{
	DataType c;
	if((c=getchar())=='#')
		*root=NULL;
	else
	{
		*root=(BTNode *)malloc(sizeof(BTNode));
		(*root)->data=c;   //别以为把这行代码换下位置就成了中、后序遍历创建方式,肯定是错误的
		Pre_order_Creat_Btree(&((*root)->lchild));
		Pre_order_Creat_Btree(&((*root)->rchild));
	}
}   //我们首先创建的是根节点,先序首先操作的是根节点我们才能固定出一棵二叉树,中后序首先操作不是根节点,

//二叉树遍历递归算法
//-----------------------------先序遍历递归版---------------------------------
void Pre_order_Rec(BTree root)
{
	if(root)
	{
		printf("%c ",root->data);
		Pre_order_Rec(root->lchild);
		Pre_order_Rec(root->rchild);
	}
}
//-----------------------------中序遍历递归版----------------------------------
void In_order_Rec(BTree root)
{
	if(root)
	{
		In_order_Rec(root->lchild);
		printf("%c ",root->data);
		In_order_Rec(root->rchild);
	}
}
//------------------------------后序遍历递归版-----------------------------------
void Post_order_Rec(BTree root)
{
	if(root)
	{
		Post_order_Rec(root->lchild);
		Post_order_Rec(root->rchild);
		printf("%c ",root->data);
	}
}

//访问函数,可以定义声明作为函数指针使用
int visit(BTree Tree)
{
    if(Tree)
    {
        printf("%c ",Tree->data);       //访问节点函数
        return 1;
    }
    else
        return 0;
}

//层次遍历非递归算法
//------------------------------方法一C++STL实现---------------------------
void LevelOrder_First(BTree Tree)
{
    queue<BTree>Q;
    BTree p;
    p=Tree;
    if(visit(p)==1)    //只要当前的这棵树不为空,就访问该树根节点的信息并进行入队操作
        Q.push(p);
    while(!Q.empty())             //层次遍历利用了先进先出的性质,故想到了队列
    {
        p=Q.front();
        Q.pop();
        if(visit(p->lchild)==1)
            Q.push(p->lchild);
        if(visit(p->rchild)==1)
            Q.push(p->rchild);
    }
}
//-------------------------------方法二C语言实现--------------------------
void LevelOrder_Second(BTree Tree)
{
    BTNode *queue[1000];                //定义队列有十个空间  --- 这种方式可以说根本就没有用到队列,充其量只是思维上和队列一致
    if(Tree==NULL)        //空树则返回                      //很方便---我喜欢
        return;
    int front,rear;
    front=rear=0;
    queue[rear++]=Tree;
    while(front!=rear)                //如果队尾指针不等于对头指针时
    {
        cout<<queue[front]->data<<" ";  //输出遍历结果
        if(queue[front]->lchild!=NULL)  //将队首结点的左孩子指针入队列
        {
            queue[rear]=queue[front]->lchild;
            rear++;                                 //队尾指针后移一位
        }
        if(queue[front]->rchild!=NULL)
        {
            queue[rear]=queue[front]->rchild;    //将队首结点的右孩子指针入队列
            rear++;                         //队尾指针后移一位
        }
        front++;                       //对头指针后移一位
    }
}
//---------------------------------方法三-课本版-----------------------------------
void LevelOrder_Third(BTree root)
{
	Squeue queue;
	BTNode *p=NULL;
	if(NULL!=root)
	{
		p=root;
		Init_Squeue(queue);
		En_Squeue(queue,p);
		while(!Empty_Squeue(*queue))
		{
			De_Squeue(queue,&p);
			printf("%c ",p->data);
			if(p->lchild!=NULL)
				En_Squeue(queue,p->lchild);
			if(p->rchild!=NULL)
				En_Squeue(queue,p->rchild);
		}
	}
}
//计算二叉树的深度-递归版
//------------------------------------方法一--------------------------
int BTree_Depth_First(BTree root)
{
	if(root)
	{
		int h1=BTree_Depth_First(root->lchild);
		int h2=BTree_Depth_First(root->rchild);
		return (h1>h2?h1:h2)+1;
	}              //return (depth(T->lchild)>depth(T->rchild)?depth(T->lchild):depth(T->rchild))+1;
	return 0;
}
//-----------------------------------方法二----------------------------
void BTree_Depth_Second(BTree root,int Count,int &depth)
{
	if(root)
	{
		if(Count>depth)
			depth=Count;
		BTree_Depth_Second(root->lchild,Count+1,depth);
		BTree_Depth_Second(root->rchild,Count+1,depth);
	}
}

//计算二叉树的叶子节点数
void BTree_leave_num(BTree root,int &Count)
{
	if(root)             //这里你为什么要用引用。1、你没有返回值。2、实参到形参的传递只是赋值过程不改变原值 3、你也没用指针
	{
		if(!root->lchild&&!root->rchild)      //不改变二叉树的结构,我不应该用指针的
			Count++;
		BTree_leave_num(root->lchild,Count);
		BTree_leave_num(root->rchild,Count);
	}
}
//先中后二叉树遍历非递归版
//---------------------------先序遍历非递归算法----------------------
typedef BTree Elemtype;
void PreOrder_NonRec_First(BTree root)
{
	SqStack stack;
	StackInitiate(&stack);
	BTNode *p=NULL;
	if(root!=NULL)
	{
		stack.data[++stack.top]=root;
		while(stack.top>0)
		{
			p=stack.data[stack.top--];
			printf("%c ",p->data);
			if(NULL!=p->rchild)
				stack.data[++stack.top]=p->rchild;
			if(NULL!=p->lchild)
				stack.data[++stack.top]=p->lchild;
		}
	}
}
void PreOrder_NonRec_Second(BTree Tree)           //先序遍历的非递归
{
    if(!Tree)
        return ;
    stack<BTree>s;
    s.push(Tree);
    while(!s.empty())
    {
        BTree temp=s.top();                             //总结:关于先中后遍历的栈如何应用,你只需要根据先中后序访问顺序关系知道什么时候做出栈,什么时候做入栈
        cout<<temp->data<<" ";                         //然后判断出栈或者入栈的时候需不需要进行访问操作就明白了
        s.pop();
        if(temp->rchild)                   //这种和下面的两种有所不同,请读者自己体会
            s.push(temp->rchild);
        if(temp->lchild)
            s.push(temp->lchild);
    }
}
void PreOrder_NonRec_Third(BTree Tree)          //先序遍历的非递归---法一:只在入栈的时候做访问操作
{
    if(!Tree)
        return ;
    stack<BTree>s;
    BTree curr=Tree;
    while(curr!=NULL||!s.empty())
    {
        while(curr!=NULL)                         //根据先序的关系知先让最左边的孩子全部入栈(边入栈边访问),完后作出栈就好了再重复入栈就好了
        {
            cout<<curr->data<<" ";
            s.push(curr);
            curr=curr->lchild;
        }
        if(!s.empty())
        {
            curr=s.top();
            s.pop();
            curr=curr->rchild;
        }
    }
}
void PreOrder_NonRec_Fouth(BTree Tree)     //先序遍历的非递归
{
    if(!Tree)
        return ;
    stack<BTree> s;
    while(Tree)                                 //左子树上的节点全部压入到栈中
    {
        s.push(Tree);
        cout<<Tree->data<<" ";
        Tree=Tree->lchild;
    }
    while(!s.empty())
    {
        BTree temp=s.top()->rchild;            // 栈顶元素的右子树
        s.pop();                                    // 弹出栈顶元素
        while(temp)                           //栈顶元素存在右子树,则对右子树同样遍历到最下方
        {
            cout<<temp->data<<" ";
            s.push(temp);                 //这里也是在入栈的时候做访问操作(因为先序首先访问的就是每一棵树的根节点)
            temp=temp->lchild;
        }
    }
}
//-----------------------中序遍历非递归算法------------------------
void InOrder_NonRec_First(BTree root)
{
	SqStack stack;
	BTNode *p=NULL;
	StackInitiate(&stack);
	p=root;
	while(NULL!=p||stack.top>0)
	{
		while(NULL!=p)
		{
			stack.data[++stack.top]=p;
			p=p->lchild;
		}
		p=stack.data[stack.top--];
		printf("%c ",p->data);
		p=p->rchild;
	}
}
void InOrder_NonRec_Second(BTree T)           //中序遍历的非递归
{
    if(!T)
        return ;
    BTree curr=T;                   //指向当前要检查的节点
    stack<BTree>s;
    while(curr!=NULL||!s.empty())
    {
        while(curr!=NULL)
        {
            s.push(curr);
            curr=curr->lchild;
        }
        if(!s.empty())                          //中序遍历首先访问的是左节点再是根节点,所以是在出栈的时候做访问操作
        {												//同时入栈的左节点又充当根节点的作用
            curr=s.top();
            s.pop();
            cout<<curr->data<<" ";
            curr=curr->rchild;
        }
    }
}
void InOrder_NonRec_Third(BTree T)               //中序遍历的非递归
{
    if(!T)
        return ;
    stack<BTree>s;
    BTree curr=T->lchild;                      //指向当前要检查的节点
    s.push(T);
    while(curr!=NULL||!s.empty())
    {
        while(curr!=NULL)                     //一直向左走
        {
            s.push(curr);
            curr=curr->lchild;
        }
        curr=s.top();                                //还是入栈的时候不做访问操作,只在出栈的时候做访问操作
        s.pop();
        cout<<curr->data<<" ";
        curr = curr->rchild;
    }
}
void PostOrder_NonRec_Second(BTree T)         //后序遍历的非递归
{
    stack<BTree>S;
    BTree curr=T;                  //指向当前要检查的节点
    BTree previsited=NULL;                //指向前一个被访问的节点
    while(curr!=NULL||!S.empty())         //栈空时结束
    {
        while(curr!=NULL)               //一直向左走直到为空
        {
            S.push(curr);
            curr=curr->lchild;
        }
        curr=S.top();               // 当前节点的右孩子如果为空或者已经被访问,则访问当前节点
        if(curr->rchild==NULL||curr->rchild==previsited)
        {
            cout<<curr->data<<" ";                //这个思路很好,相比课本上的,显得精简活跃,当你无法具体理解代码时,你就画出一棵二叉树再对比代码的思路进行
            previsited=curr;                           //一步一步地跟踪
            S.pop();
            curr = NULL;
        }
        else
            curr=curr->rchild;      // 否则访问右孩子
    }
}
void PostOrder_NonRec_Third(BTree T)        //后序遍历的非递归     双栈法
{
    stack<BTree>s1,s2;
    BTree curr;                     //指向当前要检查的节点
    s1.push(T);
    while(!s1.empty())                //栈空时结束
    {
        curr=s1.top();
        s1.pop();
        s2.push(curr);
        if(curr->lchild)                       //这个方式就更加简单了,具有实际效率
            s1.push(curr->lchild);
        if(curr->rchild)
            s1.push(curr->rchild);
    }
    while(!s2.empty())
    {
        printf("%c ", s2.top()->data);
        s2.pop();
    }
}
//查找指定节点的孩子的算法
void Find_Child_Bnode(BTNode *p,BTNode **p_lchild,BTNode **p_rchild)
{
	if(p==NULL)
		return ;
	*p_lchild=p->lchild;
	*p_rchild=p->rchild;
	return ;
}
//查找指定节点的双亲的算法
typedef BTree Elemtype;

int Find_Parent_Bnode(BTree root,BTNode *p,BTNode **p_parent)
{
	SqStack stack;
	BTNode *q=NULL;
	*p_parent=NULL;
	if(p==root)
		return 0;
	stack.top=0;q=root;
	while(NULL!=q||stack.top>0)
	{
		while(NULL!=q)
		{
			stack.data[++stack.top]=q;
			q=q->lchild;
		}
		q=stack.data[stack.top--];
		if(p==q->lchild||p==q->rchild)
		{
			*p_parent=q;                //二叉树中一个节点最多只有一个父节点,别以为叫双亲你就以为是两个
			return 1;
		}
		q=q->rchild;
	}
	return 0;
}
//查找指点节点子孙节点的算法
typedef char DataType;
typedef BTree Elemtype;

void FindDescendants_Blist(BTNode *p)
{
	SqQueue queue;                    //队列的声明与定义
	BTNode *q=NULL;int count=0;
	if(p==NULL)
	{
		printf("当前输入的节点参数有错!!!\n");
		return ;
	}
	if(p->lchild==NULL&&p->rchild==NULL)
	{
		printf("当前输入的节点是叶子节点,无孩子节点!!!\n");
		return ;
	}
	queue.front=0;
	queue.rear=0;
	printf("%c节点的所有子孙节点如下所示:\n",p->data);
	queue.data[queue.rear]=p;
	queue.rear=(queue.rear+1)%MAX;
	while(queue.front!=queue.rear)
	{
		q=queue.data[queue.front];
		queue.front=(queue.front+1)%MAX;
		if(q!=p)
		{
			printf("%c ",q->data);
			count++;
			if(count==5)
				printf("\n");
		}
		if(NULL!=q->lchild)
		{
			queue.data[queue.rear]=q->lchild;
			queue.rear=(queue.rear+1)%MAX;
		}
		if(NULL!=q->rchild)
		{
			queue.data[queue.rear]=q->rchild;
			queue.rear=(queue.rear+1)%MAX;
		}
	}
	printf("\n");
	printf("节点%c共有%d个子孙节点.\n",p->data,count);
	return ;
}
//查找指定节点祖先的算法
void FindAncersors_Blist(BTree root,BTNode *p)       //这样子的所有祖先连起来就是折线(为什么这么说,想过吗)
{
	BTNode *p_parent=p;
	BTNode *q=NULL;
	if(p==root)
	{
		printf("输入的节点信息是根节点,无祖先可寻!!!\n");
		return ;
	}
	while(p_parent!=root)
	{
		q=p_parent;
		p_parent=NULL;
		Find_Parent_Bnode(root,q,&p_parent);
		printf("节点%c是节点%c的一个祖先节点.\n",p_parent->data,p->data);
	}
}
//基于后序遍历的二叉树各类结点统计递归算法
int count_leaf=0;
int count_onedegree=0;
int count_twodegree=0;

void NodeCount_Rec(BTree root)
{
	if(root!=NULL)
	{
		NodeCount_Rec(root->lchild);
		NodeCount_Rec(root->rchild);
		if(NULL==root->lchild&&NULL==root->rchild)
			count_leaf++;
		else if(NULL!=root->lchild&&NULL!=root->rchild)
			count_twodegree++;
		else
			count_onedegree++;
	}
}
//给某节点插入左节点
BTree Insert_LeftNode(BTree father,DataType x)
{
	BTree p=NULL,q=NULL;
	if(father==NULL)
		return NULL;            //注意在函数调用时NULL和0的区别(返回值的类型)
	q=father->lchild;
	p=(BTNode *)malloc(sizeof(BTNode));
	p->data=x;
	p->lchild=q;
	p->rchild=NULL;
	father->lchild=p;
	return father->lchild;
}
//给某节点插入右节点
BTree Insert_RightNode(BTree father,DataType x)
{
	BTree p=NULL,q=NULL;
	if(father==NULL)
		return NULL;
	q=father->rchild;
	p=(BTree)malloc(sizeof(BTNode));
	p->data=x;
	p->rchild=q;
	p->lchild=NULL;
	father->rchild=p;
	return father->rchild;
}
//通过释放节点达到销毁的目的
void Destroy_BTree(BTree *root)
{
	if((*root)!=NULL&&(*root)->lchild!=NULL)
		Destroy_BTree(&(*root)->lchild);
	if((*root)!=NULL&&(*root)->rchild!=NULL)
		Destroy_BTree(&(*root)->rchild);
	free(*root);                                      //这里有个BUG
}
//删除左子树
BTree Delete_LeftTree(BTree Node)
{
	if(NULL==Node->lchild&&NULL==Node->rchild)   //若要删除的为叶子节点则不删除
		return NULL;
	Destroy_BTree(&Node->lchild);   //删除该节点的左子树
	Node->lchild=NULL;
	return Node;
}
//删除右子树
BTree Delete_RightTree(BTree Node)
{
	if(NULL==Node->lchild&&NULL==Node->rchild)   若要删除的为叶子节点则不删除
		return NULL;
	Destroy_BTree(&Node->rchild);        //删除该节点的右子树
	Node->rchild=NULL;
	return Node;
}
//交换所有节点的左右子树
void Exchange_BTree(BTree root)
{
	if(root!=NULL)
	{
		Exchange_BTree(root->lchild);
		Exchange_BTree(root->rchild);       //首先不断的递归到最底层的二叉树,然后再不断的往上交换
		BTree p=root->lchild;
		root->lchild=root->rchild;
		root->rchild=p;
	}
}
void PreOrder(BTree root)   //输出后序遍历的逆序序列---想想这样为什么就解决了这个问题
{
	if(root)
	{
		printf("%f",root->data);
		PreOrder(root->rchild);
		PreOrder(root->lchild);
	}
}
//查找节点函数
int Insearch_BTree(BTree root,DataType x,BTree &p)
{
	if(!root)
	{
		p=NULL;
		return 0;
	}
	else
	{
		if(root->data==x)
		{
			printf("元素已找到,正在返回!!!\n");
			p=root;
			return 1;
		}
		if(Insearch_BTree(root->lchild,x,p))    //只要是棵二叉树(只有两个方向),这左右(方向)递归函数一起使用就能遍历整个二叉树
			return 1;
		else
			return Insearch_BTree(root->rchild,x,p);
	}
	return 0;
}
void Delay(char *p)              //延时函数的定义
{
	while(1)
	{
		if(*p!=0)
			printf("%c",*p++);
		else
			break;
		Sleep(10);               //延时控制间断语句
	}
}                        //有w存在时就表示要新建一个文件,其他情况都不会新建
void Basic_operation(BTree root)             //功能函数
{
	int n;
	char ch;BTree head,arrow,p_lchild,p_rchild;
	int count=0,depth=1;
	system("cls");
	printf("\t\t\t\t\t\t\t\t----------------------------------------------------\n");
	printf("\t\t\t\t\t\t\t\t+		  二叉树基本操作   			   +\n");
	printf("\t\t\t\t\t\t\t\t----------------------------------------------------\n");
	printf("\t\t\t\t\t\t\t\t\t*************************************\n");
	printf("\t\t\t\t\t\t\t\t       |\t  1、创建二叉树              |\n");
	printf("\t\t\t\t\t\t\t\t       |\t  2、插入左孩子              |\n");              //为什么不能在这里定义head指针---因为每次调用功能函数后,head指针又被重新初始化了
	printf("\t\t\t\t\t\t\t\t       |\t  3、插入右孩子              |\n");
	printf("\t\t\t\t\t\t\t\t       |\t  4、查找某节点              |\n");
	printf("\t\t\t\t\t\t\t\t       |\t  5、求叶子数目              |\n");
	printf("\t\t\t\t\t\t\t\t       |\t  6、求深度操作              |\n");
	printf("\t\t\t\t\t\t\t\t       |\t  7、先中后递归打印          |\n");
	printf("\t\t\t\t\t\t\t\t       |\t  8、先中后非递归打印        |\n");
	printf("\t\t\t\t\t\t\t\t       |\t  9、层次遍历                |\n");
	printf("\t\t\t\t\t\t\t\t       |\t 10、各类节点数              |\n");
	printf("\t\t\t\t\t\t\t\t       |\t 11、树左右互换              |\n");
	printf("\t\t\t\t\t\t\t\t       |\t 12、删除左子树              |\n");
	printf("\t\t\t\t\t\t\t\t       |\t 13、删除右子树              |\n");
	printf("\t\t\t\t\t\t\t\t       |\t 14、查找指定节点双亲        |\n");
	printf("\t\t\t\t\t\t\t\t       |\t 15、查找指定节点孩子        |\n");
	printf("\t\t\t\t\t\t\t\t       |\t 16、查找指定节点子孙        |\n");
	printf("\t\t\t\t\t\t\t\t       |\t 17、查找指定节点祖先        |\n");
	printf("\t\t\t\t\t\t\t\t       |\t 18、退出程序                |\n");
	printf("\t\t\t\t\t\t\t\t\t*************************************\n");
	printf("请输入你所需要完成的指令:\n");
	do{
		scanf("%d%*c",&n);
		if(n<1||n>18)
			printf("对不起,你输入的指令编号是无效的,请重新输入!!!\n");
	}while(n<1||n>18);
	switch(n)
	{
		case 1:
			Pre_order_Creat_Btree(&root);
			printf("创建成功!\n");
			system("pause");
			break;
		case 2:
			printf("请输入要插入的字母:\n");
			scanf("%c%*c",&ch);
			Insert_LeftNode(root,ch);
			printf("插入成功\n");
			system("pause");
			break;
		case 3:
			printf("请输入要插入的字母:\n");
			scanf("%c%*c",&ch);
			Insert_RightNode(root,ch);
			printf("插入成功\n");
			system("pause");
			break;
		case 4:
			printf("请输入要查找的节点元素:\n");
			scanf("%c%*c",&ch);
			head=root;
			Insearch_BTree(root,ch,head);
			if(head==NULL)
				printf("查找元素顶点不存在,查找失败!!!\n");
			else
				printf("%c\n",head->data);
			system("pause");
			break;
		case 5:
			BTree_leave_num(root,count);
			printf("二叉树叶子节点数目为:%d\n",count);
			system("pause");
			break;
		case 6:
			printf("二叉树的深度为:%d\n",	BTree_Depth_First(root));
			BTree_Depth_Second(root,1,depth);
			printf("二叉树的深度为:%d\n",depth);
			system("pause");
			break;
		case 7:
			printf("先序递归遍历后得到如下序列:\n");
			Pre_order_Rec(root);
			printf("\n");
			printf("中序遍历后得到如下序列:\n");
			In_order_Rec(root);
			printf("\n");
			printf("后序遍历后得到如下序列:\n");
			Post_order_Rec(root);
			printf("\n");
			system("pause");
			break;
		case 8:
			printf("第一种先序遍历非递归结果如下:\n");
			PreOrder_NonRec_First(root);
			printf("\n");
			printf("第二种先序遍历非递归结果如下:\n");
			PreOrder_NonRec_Second(root);
			printf("\n");
			printf("第三种先序遍历非递归结果如下:\n");
			PreOrder_NonRec_Third(root);
			printf("\n");
			printf("第四种先序遍历非递归结果如下:\n");
			PreOrder_NonRec_Fouth(root);
			printf("\n");
			printf("第一种中序遍历非递归结果如下:\n");
			InOrder_NonRec_First(root);
			printf("\n");
			printf("第二种中序遍历非递归结果如下:\n");
			InOrder_NonRec_Second(root);
			printf("\n");
			printf("第三种中序遍历非递归结果如下:\n");
			InOrder_NonRec_Third(root);
			printf("\n");
			printf("第一种后序遍历非递归结果如下:\n");
			PostOrder_NonRec_Second(root);
			printf("\n");
			printf("第二种后序遍历非递归结果如下:\n");
			PostOrder_NonRec_Third(root);
			printf("\n");
			system("pause");
			break;
		case 9:
			printf("第一种层次遍历后得到如下序列:\n");
			LevelOrder_First(root);
			printf("\n");
			printf("第二种层次遍历后得到如下序列:\n");
			LevelOrder_Second(root);
			printf("\n");
			printf("第三种层次遍历后得到如下序列:\n");
			LevelOrder_Third(root);
			printf("\n");
			system("pause");
			break;
		case 10:
			NodeCount_Rec(root);
			printf("0度节点数目为:%d\n",count_leaf);
			printf("1度节点数目为:%d\n",count_onedegree);
			printf("2度节点数目为:%d\n",count_twodegree);
			count_leaf=count_onedegree=count_twodegree=0;
			system("pause");
			break;
		case 11:
			Exchange_BTree(root);
			printf("左右子树交换成功!\n");
			system("pause");
			break;
		case 12:
			Delete_LeftTree(root);
			printf("删除左子树成功!\n");
			system("pause");
			break;
		case 13:
			Delete_RightTree(root);
			printf("删除右子树成功!\n");
			system("pause");
			break;
		case 14:
			head=arrow=root;
			printf("请输入你想要谁的父节点:\n");
			scanf("%c%*c",&ch);
			head=root;
			Insearch_BTree(root,ch,head);
			Find_Parent_Bnode(root,head,&arrow);
			if(arrow==NULL)
				printf("查找节点不存在或者为根节点!!!\n");
			else
				printf("节点%c的父节点是%c\n",head->data,arrow->data);
			system("pause");
			break;
		case 15:
			head=root;
			printf("请输入你想要谁的孩子节点:\n");
			scanf("%c%*c",&ch);
			head=root;
			Insearch_BTree(root,ch,head);
			Find_Child_Bnode(head,&p_lchild,&p_rchild);
			if(p_lchild==NULL&&p_rchild==NULL)
				printf("查找节点不存在或者为叶子节点!!!\n");
			else if(p_lchild!=NULL&&p_rchild==NULL)
				printf("节点%c的左孩子是%c\n",head->data,p_lchild->data);
			else if(p_lchild==NULL&&p_rchild!=NULL)
				printf("节点%c的右孩子是%c\n",head->data,p_rchild->data);
			else
				printf("节点%c的左右孩子分别为%c和%c\n",head->data,p_lchild->data,p_rchild->data);
			system("pause");
			break;
		case 16:
			head=root;
			printf("请输入你想要谁的子孙节点:\n");
			scanf("%c%*c",&ch);
			head=root;
			Insearch_BTree(root,ch,head);
			FindDescendants_Blist(head);
			system("pause");
			break;
		case 17:
			head=root;
			printf("请输入你想要谁的祖宗节点:\n");
			scanf("%c%*c",&ch);
			head=root;
			Insearch_BTree(root,ch,head);
			FindAncersors_Blist(root,head);
			system("pause");
			break;
		case 18:
			return ;
		default:
			Basic_operation(root);
	}
	Basic_operation(root);
}

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值