user-0 提问: 判断该二叉树是否存在一个节点含有2个父节点

回复:
user: user-1
content: 上面贴错了。 struct Node{ Node *pLeft; Node *pRight; int Data; };  //pTree为要查找的树，pParent为pNode的父结点，pNode为根时pParent 为NULL //若pTree 中存在具有两个父结点的点返回真，否则返回假 bool CheckTwoParent( Node *pTree, Node *pParent, Node *pNode) {     Node *pTemp = NULL;     bool result;     if ( pNode == NULL ) return false;     if ( pParent == NULL )  //根结点     {         if ( pTree->pLeft != NULL )         {            pTree->pLeft = NULL;            result = FindNode( pTree, pNode ); //FindNode为在pTree树中查看PNode结点存在与否，若存在返回true,否则返回false，这个很简单，可以自己写            pTree->Left = pNode;            if ( result ) return true;         }          if ( pTree->pRight != NULL )         {             pTree->pRight = NULL;             result = FindNode( pTree, pNode );             pTree->pRight = pNode;             if ( result ) return true;         }         if ( CheckTwoParent( pTree, pNode, pNode->pLeft) ) return true;        return CheckTwoParent( pTree, pNode, pNode->pRight);      }     else     {         if ( pParent->pLeft == pNode )  //若当前结点为左孩子         {             pParent->pLeft = NULL;             result = FindNode( pTree, pNode ); //FindNode为在pTree树中查看PNode结点存在与否，若存在返回true,否则返回false，这个很简单，可以自己写             pParent->Left = pNode;             if ( result ) return true;         }         else         {             pParent->pRight = NULL;             result = FindNode( pTree, pNode ); //FindNode为在pTree树中查看PNode结点存在与否，若存在返回true,否则返回false，这个很简单，可以自己写             pParent->pRight = pNode;             if ( result ) return true;         }         if ( CheckTwoParent( pTree, pNode, pNode->pLeft) ) return true;        return CheckTwoParent( pTree, pNode, pNode->pRight);     }  }

user: user-1
content: 可以这样，要检测一个结点是否有两个父亲时，先把从该结点开始的结点与原树分离，分成两部分，然后再从原树再查找该结点，如果找到那就是有两个结点，如果没有则递归查找。 struct Node{ Node *pLeft; Node *pRight; int Data; };  //pTree为要查找的树，pParent为pNode的父结点，pNode为根时pParent 为NULL //若pTree 中存在具有两个父结点的点返回真，否则返回假 bool CheckTwoParent( Node *pTree, Node *pParent, Node *pNode) {     Node *pTemp = NULL;     bool result;     if ( pNode == NULL ) return false;     if ( pParent == NULL )  //根结点     {         if ( pTree->pLeft != NULL )         {            pTree->pLeft = NULL;            result = FindNode( pTree, pNode ); //FindNode为在pTree树中查看PNode结点存在与否，若存在返回true,否则返回false，这个很简单，可以自己写            pTree->Left = pNode;            if ( result ) return true;         }          if ( pTree->pRight != NULL )         {             pTree->pRight = NULL;             result = FindNode( pTree, pNode );             pTree->pRight = pNode;             if ( result ) return true;         }         if ( CheckTwoParent( pTree, pNode, pNode->pLeft) ) return true;        return CheckTwoParent( pTree, pNode, pNode->pRight);      }     else     {         if ( pParent->pLeft == pNode )  //若当前结点为左孩子         {             pParent->pLeft = NULL;             result = FindNode( pTree, pNode ); //FindNode为在pTree树中查看PNode结点存在与否，若存在返回true,否则返回false，这个很简单，可以自己写             pTree->Left = pNode;             if ( result ) return true;         }         else         {             pParent->pRight = NULL;             result = FindNode( pTree, pNode ); //FindNode为在pTree树中查看PNode结点存在与否，若存在返回true,否则返回false，这个很简单，可以自己写             pTree->pRight = pNode;             if ( result ) return true;         }         if ( CheckTwoParent( pTree, pNode, pNode->pLeft) ) return true;        return CheckTwoParent( pTree, pNode, pNode->pRight);     }  }  代码没有调试。

user: user-2
content: 引用 4 楼 lbp889 的回复:应该可以用哈希表来存储每个节点的父节点吧，然后找出有多个父节点的节点，这样是吗  你这种方法，也可以做出来，但个人认为不是更好的方法。 可以先将自己的想法实现出来，然后再思考下，问题的根本，尝试下有没有更好一点的方法！  PS：作业题自己多思考一定会有好处的。记得大一的时候遇到过一个比较简单的题目：一个数组，不允许再开辟数组，只遍历一次数组，将数组中的某个字符去除。 当时觉得好难，但我就是想自己搞定，然后在上其他课程的时候也一直在思考，最后终于找到了思路。因为我相信这样会对我有帮助的。 如果最终是在想不到方法，可以先google（一定要google，用中文/英文分别搜索），如果还找不到答案，再来和大家一起讨论。再撤个额外的“提问的智慧”

user: user-2
content: 如果你已经学会了上面的基本操作：那么我给一个本人的思路提示： 采用一个容器（具体采用什么方式效率高，楼主自己斟酌下），存储遍历过的节点。

user: user-3
content: 仅供参考#include <iostream> #include <stack> #include <queue> #include <locale.h> using namespace std; typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int CreateBiTree(BiTree &T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         T = NULL;     } else {         T = (BiTree)malloc(sizeof(BiTNode));         T->data = data;         //生成根结点         CreateBiTree(T->lchild);//构造左子树         CreateBiTree(T->rchild);//构造右子树     }     return 0; } void Visit(BiTree T) {//输出     if (T->data != '#') {         printf("%c ",T->data);     } } void PreOrder(BiTree T) {//先序遍历     if (T != NULL) {         Visit(T);               //访问根节点         PreOrder(T->lchild);    //访问左子结点         PreOrder(T->rchild);    //访问右子结点     } } void InOrder(BiTree T) {//中序遍历     if (T != NULL) {         InOrder(T->lchild);     //访问左子结点         Visit(T);               //访问根节点         InOrder(T->rchild);     //访问右子结点     } } void PostOrder(BiTree T) {//后序遍历     if (T != NULL) {         PostOrder(T->lchild);   //访问左子结点         PostOrder(T->rchild);   //访问右子结点         Visit(T);               //访问根节点     } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后，将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，再先序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈             stack.pop();             p = p->rchild;          //访问右子树         }     } } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈，访问根节点             printf("%c ",p->data);             stack.pop();             p = p->rchild;          //访问右子树         }     } }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     stack<BiTreePost> stack;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack.push(BT);             p = p->lchild;         }         while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点             BT = stack.top();             stack.pop();//退栈             printf("%c ",BT->biTree->data);         }         if (!stack.empty()) {//遍历右子树             BT = stack.top();             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     } }  void LevelOrder(BiTree T) {//层次遍历     if (T == NULL) return;     BiTree p = T;     queue<BiTree> queue;//队列     queue.push(p);//根节点入队     while (!queue.empty()) {    //队列不空循环         p = queue.front();      //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         queue.pop();            //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue.push(p->lchild);         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue.push(p->rchild);         }     } } int main() {     BiTree T;      setlocale(LC_ALL,"chs");     CreateBiTree(T);      printf("先序遍历        ：");PreOrder  (T);printf("\n");     printf("先序遍历(非递归)：");PreOrder2 (T);printf("\n");                                                printf("\n");     printf("中序遍历        ：");InOrder   (T);printf("\n");     printf("中序遍历(非递归)：");InOrder2  (T);printf("\n");                                                printf("\n");     printf("后序遍历        ：");PostOrder (T);printf("\n");     printf("后序遍历(非递归)：");PostOrder2(T);printf("\n");                                                printf("\n");     printf("层次遍历        ：");LevelOrder(T);printf("\n");      return 0; } //ABC##DE#G##F### //先序遍历        ：A B C D E G F //先序遍历(非递归)：A B C D E G F // //中序遍历        ：C B E G D F A //中序遍历(非递归)：C B E G D F A // //后序遍历        ：C G E F D B A //后序遍历(非递归)：C G E F D B A // //层次遍历        ：A B C D E F G //  ///       A ///      / ///     B ///    / \ ///   C   D ///      / \ ///     E   F ///      \ ///       G

user: user-0
content: 应该可以用哈希表来存储每个节点的父节点吧，然后找出有多个父节点的节点，这样是吗

user: user-4
content: 遍历应该可以，如果一个结点有两个父结点，那么在遍历序列中肯定会重复出现。