国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C > 正文

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

2020-01-26 14:59:17
字體:
供稿:網(wǎng)友

算法分析

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

2015810120155494.jpg (344×246)

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

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

求跟節(jié)點到指定節(jié)點路徑:

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();}

求最低公共祖先節(jié)點:

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題目

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

    輸入: 
    輸入可能包含多個測試樣例。 
    對于每個測試案例,輸入的第一行為一個數(shù)n(0<n<1000),代表測試樣例的個數(shù)。 
    其中每個測試樣例包括兩行,第一行為一個二叉樹的先序遍歷序列,其中左右子樹若為空則用0代替,其中二叉樹的結(jié)點個數(shù)node_num<10000。 
    第二行為樹中的兩個結(jié)點的值m1與m2(0<m1,m2<10000)。 
    輸出: 
    對應(yīng)每個測試案例, 
    輸出給定的樹中兩個結(jié)點的最低公共祖先結(jié)點的值,若兩個給定結(jié)點無最低公共祖先,則輸出“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)然后求兩個棧第一個公共節(jié)點

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;       /**    * 根據(jù)前序序列遞歸構(gòu)建二叉樹    */   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);     }   }       /**    * 后序遍歷二叉樹,構(gòu)造遍歷棧    */   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
    ****************************************************************/ 

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

圖片精選

主站蜘蛛池模板: 瓮安县| 红河县| 台前县| 高阳县| 扶风县| 中牟县| 云安县| 津南区| 临海市| 盐源县| 视频| 文登市| 云南省| 增城市| 黑水县| 方城县| 浦城县| 专栏| 泰顺县| 莎车县| 吴忠市| 罗定市| 区。| 枣强县| 墨竹工卡县| 怀安县| 祁阳县| 汉阴县| 永和县| 乳源| 岳普湖县| 黄山市| 文安县| 贡山| 福建省| 南投市| 盘山县| 深州市| 博野县| 运城市| 溧阳市|