Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

AVL木にてK番目に大きい数を返すアルゴリズムが必要です

解決したいこと

AVL木にてK番目に大きい数を返すアルゴリズムが必要です
n個のデータが与えられます、その中でK番目に大きい数を返しなさい。
(特に厳しい規制はないですが、できるだけ早いものが良いです)
ネットでいろいろ探したのですが、見つからず。。。

発生している問題・エラー

#include <iostream>

using namespace std;

#define INF 0x3f3f3f3f
#define INT_MAX 2147483647
#define INT_MIN -2147483648
#define LONG_MAX 9223372036854775807
#define LONG_MIN -9223372036854775808
#define ll long long

typedef struct AVLNode {
    int data;
    int height;
    struct AVLNode* lchild;
    struct AVLNode* rchild;
    int size;
} *AVLTree;

int Height(AVLTree T) {
    if (!T) return 0;
    return T->height;
}

int getSize(AVLTree Tree) {
    int cnt = 0;
    if (Tree->lchild)
        cnt = Tree->lchild->size + 1;
    else cnt = 1;
    if (Tree->rchild)
        cnt += Tree->rchild->size;
    return cnt;
}

void updateHeight(AVLTree& T) {
    if (!T) return;
    T->height = max(Height(T->lchild), Height(T->rchild)) + 1;
}

AVLTree LL_Rotation(AVLTree& T) {
    AVLTree temp = T->lchild;
    T->lchild = temp->rchild;
    temp->rchild = T;
    updateHeight(T);
    updateHeight(temp);
    temp->size = T->size;
    T->size = getSize(T);
    return temp;
}

AVLTree RR_Rotation(AVLTree& T) {
    AVLTree temp = T->rchild;
    T->rchild = temp->lchild;
    temp->lchild = T;
    updateHeight(T);
    updateHeight(temp);
    temp->size = T->size;
    T->size = getSize(T);
    return temp;
}

AVLTree LR_Rotation(AVLTree& T) {
    T->lchild = RR_Rotation(T->lchild);
    return LL_Rotation(T);
}

AVLTree RL_Rotation(AVLTree& T) {
    T->rchild = LL_Rotation(T->rchild);
    return RR_Rotation(T);
}

void adjust(AVLTree& T) {
    if (!T) return;
    if (Height(T->lchild) - Height(T->rchild) > 1) {
        if (Height(T->lchild->lchild) >= Height(T->lchild->rchild)) T = LL_Rotation(T);
        else T = LR_Rotation(T);
    }
    else if (Height(T->rchild) - Height(T->lchild) > 1) {
        if (Height(T->rchild->rchild) >= Height(T->rchild->lchild)) T = RR_Rotation(T);
        else T = RL_Rotation(T);
    }
}

AVLTree Insert(AVLTree& T, int x) {
    if (!T) {
        T = new AVLNode;
        T->lchild = T->rchild = NULL;
        T->data = x;
        T->height = 0;
        T->size = 1;
        return T;
    }
    if (T->data == x) return T;
    if (x < T->data) {
        T->lchild = Insert(T->lchild, x);
        T->size++;
    }
    else {
        T->rchild = Insert(T->rchild, x);
        T->size++;
    }
    updateHeight(T);
    adjust(T);
    return T;
}


int findKth(AVLTree Tree, int k) {
    return 0;
}



int main() {
    int n, x, k;
    scanf_s("%d", &n);
    scanf_s("%d", &k);
    AVLTree tree = NULL;
    for (int i = 1; i <= n; i++) {
        scanf_s("%d", &x);
        tree = Insert(tree, x);
        printf("%d ", findKth(tree, k));
    }
    return 0;
}

0

2Answer

左右の子のsizeを見れば、親の数が全体の何番目に大きいのかが分かります。
その順番とKを比較すれば、目的の「K番目に大きい数」が、左右どちらの子の先にあるか(もしくは親自身の数がそうなのか)が分かります。
そちらの子について同様に判定していけば、いずれ「K番目に大きい数」に到達します。

1Like

AVL木は二分木検索の親戚で1960年代当時、配列またはポインタに昇順に保存された数値を高速に検索するアルゴリズムです。

配列なら、x[0]=1,x[1]=5,....,x[-n]=98,x[n]=99
5番目は x[n-4]が答えです。

それが発展し、二分木検索をソートしながらグラフ理論の木の構造のようにデータをソートしながら保存するため、ポインタを用いたヒープ構造のデータ保存が考えてられました。私の解釈ではAVL木は高速検索するために保存時に足かせとしてノードの左右部分木の高さの差も1以下という条件を課しているのではと考えています。

原理は同じですがで、AVL木はチョットお得なので、5番目なら右のリーフを見つけてノード2個迄、辿れば見つかるとおもいます。(再帰関数で辿る)

0Like

Comments

  1. AVL木自体の説明のみで、「AVL木にてK番目に大きい数を返すアルゴリズム」が回答に含まれていないように見えます。任意のKで動作する方法を示してください。

Your answer might help someone💌