a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C > 正文

使用C語言求二叉樹結點的最低公共祖先的方法

2020-01-26 14:59:17
字體:
來源:轉載
供稿:網友

算法分析

我們直接來分析O(n)的算法。

2015810120155494.jpg (344×246)

比如求節點F和節點H的最低公共祖先,先求出從根節點A到F的路徑,再求出A到H的路徑,那么最后一個相同的節點就是最低公共祖先。A->B->D->F和A->B->E->H,最后相同的節點事B,所以最低公共祖先是B節點。求根節點到指定節點的算法先前已經更新過了,復雜度是O(n),所以總的時間復雜度是O(n)。
條件細化:
(1)樹如果是二叉樹,而且是二叉排序樹。
             這中條件下可以使用二叉排序樹的搜索功能找到最低公共祖先。
(2)樹不是二叉排序樹,連二叉樹都不是,就是普通的樹。
      1,如果樹中有指向父節點的指針。
              這問題可以將問題轉化為兩個鏈表相交,求兩個鏈表的第一個交點。
      2,如果樹中沒有指向父節點的指針。
              這問題就有點麻煩了。
      
      
具體來看獲取從根節點到指定節點的函數代碼:

struct BinaryNode{ char value; BinaryNode *left; BinaryNode *right;};

求跟節點到指定節點路徑:

bool GetNodePath(BinaryNode *pRoot,BinaryNode *pNode,vector<BinaryNode*> &v){ if(pRoot==NULL)  return false; v.push_back(pRoot); if(pRoot==pNode)  return true; bool found=GetNodePath(pRoot->left,pNode,v); if(!found)  found=GetNodePath(pRoot->right,pNode,v); if(!found)  v.pop_back();}

求最低公共祖先節點:

BinaryNode* GetCommonParent(BinaryNode *pRoot,BinaryNode *pNode1,BinaryNode *pNode2){ if(pRoot==NULL || pNode1==NULL || pNode2==NULL)  return NULL; vector<BinaryNode*> v1,v2; GetNodePath(pRoot,pNode1,v1); GetNodePath(pRoot,pNode2,v2); BinaryNode *pLast=pRoot; vector<BinaryNode*>::iterator ite1=v1.begin(); vector<BinaryNode*>::iterator ite2=v2.begin(); while(ite1!=v1.end() && ite2!=v2.end()) {  if(*ite1==*ite2)   pLast=*ite1;  ite1++;  ite2++; } return pLast;}

來看一道具體的ACM題目

    題目描述: 
    給定一棵樹,同時給出樹中的兩個結點,求它們的最低公共祖先。

    輸入: 
    輸入可能包含多個測試樣例。 
    對于每個測試案例,輸入的第一行為一個數n(0<n<1000),代表測試樣例的個數。 
    其中每個測試樣例包括兩行,第一行為一個二叉樹的先序遍歷序列,其中左右子樹若為空則用0代替,其中二叉樹的結點個數node_num<10000。 
    第二行為樹中的兩個結點的值m1與m2(0<m1,m2<10000)。 
    輸出: 
    對應每個測試案例, 
    輸出給定的樹中兩個結點的最低公共祖先結點的值,若兩個給定結點無最低公共祖先,則輸出“My God”。 
    樣例輸入: 
    2 
    1 2 4 6 0 0 7 0 0 5 8 0 0 9 0 0 3 0 0 
    6 8 
    1 2 4 6 0 0 7 0 0 5 8 0 0 9 0 0 3 0 0 
    6 12 
    樣例輸出: 
    2 
    My God 


思路
這道題我考慮的思路是

(1)后序遍歷的思想,用棧保存到查找點的路徑
(2)然后求兩個棧第一個公共節點

AC代碼

  #include <stdio.h>   #include <stdlib.h>       #define N 7000       typedef struct btree {     struct btree *lchild, *rchild;     int data;   } btree;       typedef struct stack {     int top;     btree* data[N];   } stack;       stack *first, *second;   int oneflag, secflag;       /**    * 根據前序序列遞歸構建二叉樹    */   void createBtree(btree **t)   {     int data;     scanf("%d", &data);         if (data == 0) {       *t = NULL;     } else {       *t = (btree *)malloc(sizeof(btree));       (*t)->data = data;       createBtree(&(*t)->lchild);       createBtree(&(*t)->rchild);     }   }       /**    * 后序遍歷二叉樹,構造遍歷棧    */   void postTraverse(btree *t, stack *s, int srcnum, int *flag)   {     if (t != NULL) {       btree *pre;       pre = NULL;           s->data[s->top ++] = t;       while (s->top > 0 || t) {         if (t) {           s->data[s->top ++] = t;           if (t->data == srcnum) {             *flag = 1;             break;           }           t = t->lchild;         } else {           t = s->data[-- s->top];           if (t->rchild == NULL || t->rchild == pre) {             pre = t;             t = NULL;           } else {             s->data[s->top ++] = t;             t = t->rchild;           }         }       }     }   }       /**    * 查找兩個棧第一個公共元素    *    * T = O(n)    *    */   void stackCommonData(stack *f, stack *s)   {     int top, data, flag;         top = (f->top > s->top) ? s->top : f->top;         while (top > 0) {       if (f->data[top - 1]->data == s->data[top - 1]->data) {         data = f->data[top - 1]->data;         flag = 1;         break;       } else {         top --;       }     }         if (flag) {       printf("%d/n", data);     } else {       printf("My God/n");     }   }       /**    * 清理二叉樹    *    */   void cleanBtree(btree *t)   {     if (t) {       cleanBtree(t->lchild);       cleanBtree(t->rchild);       free(t);     }   }           int main(void)   {     int n, sf, se;     btree *t;         scanf("%d", &n);     while (n --) {       createBtree(&t);       scanf("%d %d", &sf, &se);               first = (stack *)malloc(sizeof(stack));       first->top = 0;       oneflag = 0;       postTraverse(t, first, sf, &oneflag);           second = (stack *)malloc(sizeof(stack));       second->top = 0;       secflag = 0;       postTraverse(t, second, se, &secflag);           if (oneflag == 0 || secflag == 0 || first->top == 0 || second->top == 0) {         printf("My God/n");         cleanBtree(t);         continue;       } else {         stackCommonData(first, second);         cleanBtree(t);       }     }     return 0;   } 

    /**************************************************************
        Problem: 1509
        User: wangzhengyi
        Language: C
        Result: Accepted
        Time:150 ms
        Memory:110212 kb
    ****************************************************************/ 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 久久国产精品免费视频 | 日韩一区二区福利视频 | 91视频播放 | 久久久久亚洲 | 亚洲乱码一区二区三区在线观看 | 日本在线免费电影 | 天堂av中文| 成人精品一区二区三区中文字幕 | 中文字幕三级在线看午夜 | 久久aⅴ国产欧美74aaa | 欧美日韩一区二区三区在线观看 | 国产在线小视频 | 中文在线播放 | 欧美一区二区在线观看 | 99精品电影 | 亚洲三区在线观看 | 日韩在线高清视频 | 中文字幕亚洲一区二区三区 | 久久天堂 | 黄色网址av | 免费av网页 | 久久蜜桃av | 中国人xxxx片99ww| 国产成人精品久久二区二区91 | 国产精品国色综合久久 | 一级毛片免费播放 | 天天操天天舔天天爽 | 日本久久久久久久 | 成人亚洲视频 | 欧美精品一区二区三区一线天视频 | 精品一区二区三区不卡 | 欧美一级免费大片 | 99久久精品无免国产免费 | 国产精品第一国产精品 | 国产三级日本三级美三级 | 高清av网站 | 国产欧美一区二区精品久久 | 日本精品久久久一区二区三区 | 久久久久久久久久久高潮 | 91精品国产综合久久久久久软件 | 色综合色|