日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

十九、二叉树的最近的公共祖先

發布時間:2025/3/21 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 十九、二叉树的最近的公共祖先 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

十九、二叉樹的最近的公共祖先

文章目錄

  • 十九、二叉樹的最近的公共祖先
    • 題目描述
    • 解題思路
    • 上機代碼:

題目描述

設順序存儲的二叉樹中有編號為 i 和 j 的兩個結點,請設計算法求出它們最近的公共祖先結點的編號和值。

輸入:

? 輸入第1行給出正整數n(≤1000),即順序存儲的最大容量;
第2行給出n個非負整數,其間以空格分隔。其中0代表二叉樹中的空結點(如果第1個結點為0,則代表一棵空樹);
第3行給出一對結點編號 i 和 j 。
題目保證輸入正確對應一棵二叉樹,且1≤ i,j ≤n。

輸出:

如果i或j對應的是空結點,則輸出:ERROR: T[x] is NULL,其中 x 是 i 或 j 中先發現錯誤的那個編號;否則在一行中輸出編號為 i 和 j 的兩個結點最近的公共祖先結點的編號和值,其間以一個空格分隔。

測試輸入期待的輸出時間限制內存限制額外進程
測試用例 115
4 3 5 1 10 0 7 0 2 0 9 0 0 6 8
11 4
2 31秒64M0
測試用例 215
4 3 5 1 0 0 7 0 2 0 0 0 0 6 8
12 8
ERROR: T[12] is NULL1秒64M0
測試用例 315
4 3 5 1 0 0 7 0 2 0 0 0 0 6 8
8 12
ERROR: T[8] is NULL1秒64M0

解題思路

求解結點的最近公共祖先(Least Common Ancestors,LCA),做法如下:

從根節點開始遍歷

  • 如果node1和node2中的任一個和root匹配,那么root就是最低公共祖先。
  • 如果都不匹配,則分別遞歸左、右子樹,
  • 如果有一個節點出現在左子樹,并且另一個節點出現在右子樹,則root就是最低公共祖先.
  • 如果兩個節點都出現在左子樹,則說明最低公共祖先在左子樹中,否則在右子樹。

注意,如果 i、j 是空節點,直接輸出 ERROR。

上機代碼:

在二叉樹的存儲結構中,data是輸入序列中二叉樹結點的值,vis是按照完全二叉樹的順序對應二叉樹的結點的編號。通過 vis 可以更簡單地判斷二叉樹向下查找時有沒有超出邊界,同時通過打印 vis 可以知道二叉樹有沒有正確地建立。

下面代碼中的兩個函數 in_sequence()、print(),通過中序遍歷打印 data 和 vis 的值,我借此來判斷二叉樹有沒有正確建立,與本題關系不大。

#include<cstdio> #include<iostream> #include<queue> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; typedef struct NODE {int data; //結點的值int vis; //結點的序號struct NODE *lchild;struct NODE *rchild; }node, *Tree;queue<Tree>q; int n = 0, a[1010];//數組存儲結點信息void createTree() {int flag = 0;Tree T, N;T = (Tree)malloc(sizeof(node));cin >> n;for (int i = 1; i <= n; i++)cin >> a[i];//建立二叉樹while (!q.empty()){flag++;T = q.front();q.pop();T->data = a[flag];T->vis = flag;N = (Tree)malloc(sizeof(node));N->data = -1;N->vis = -1;//沒有訪問過T->lchild = N;q.push(N);N = (Tree)malloc(sizeof(node));N->data = -1;N->vis = -1;T->rchild = N;q.push(N);if (flag == n)break;} } void in_sequence(Tree T) {if (T->data != -1){in_sequence(T->lchild);cout << T->data << " ";in_sequence(T->rchild);}return; } void print(Tree T) {if (T->data != -1){print(T->lchild);cout << T->vis << " ";print(T->rchild);}return; } Tree LCA(Tree T,int u,int v) {if (T->vis == -1)//超出搜索范圍return T;if (T->vis == u || T->vis == v)//找到u,v的值return T;Tree cur = (Tree)malloc(sizeof(node));//遞歸左右子樹Tree left_lca = (Tree)malloc(sizeof(node));left_lca = LCA(T->lchild, u, v);if (left_lca->vis != -1){cur = LCA(left_lca->lchild, u, v);if (cur->vis != -1)cur = LCA(left_lca->rchild, u, v);if ((cur->vis == u && left_lca->vis == v) || (cur->vis == v && left_lca->vis == u))return T;}Tree right_lca = (Tree)malloc(sizeof(node));right_lca = LCA(T->rchild, u, v);if (right_lca->vis != -1){cur = LCA(right_lca->lchild, u, v);if (cur->vis != -1)cur = LCA(right_lca->rchild, u, v);if ((cur->vis == u && right_lca->vis == v) || (cur->vis == v && right_lca->vis == u))return T;}if (left_lca->vis != -1 && right_lca->vis != -1)return T;if (left_lca->vis == -1)return right_lca;elsereturn left_lca; } int main() {memset(a, -1, sizeof(a));Tree bit;bit = (Tree)malloc(sizeof(node));q.push(bit);createTree();/*in_sequence(bit);printf("\n");print(bit);printf("\n");*/int u = 0, v = 0;cin >> u >> v;if (a[u]==0){printf("ERROR: T[%d] is NULL\n", u);//system("pause");return 0;}else if (a[v]==0){printf("ERROR: T[%d] is NULL\n", v);//system("pause");return 0;}else{Tree tmp = (Tree)malloc(sizeof(node));tmp=LCA(bit, u, v);printf("%d %d\n", tmp->vis, tmp->data);}//system("pause");return 0; } 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的十九、二叉树的最近的公共祖先的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。