求BST中第K大的元素

 此题有2种变形:

1、不能修改node结构,要求时间O(N).

2、可以修改node结构,要求时间O(logN).

这里对第一种变形作答。

思路就是先看右子树中是否有符合条件的node,再看自己是不是符合,再看左子树中是否有符合条件的node。

用递归的方法实现。

用一个counter来表示当前访问到了第几大的节点。

#include <iostream>
using namespace std;

//BST Node
struct Node{
    int data;
    Node *lchild;
    Node *rchild;
    void Init(int d, Node *l, Node *r){data = d; lchild = l; rchild = r;}
};

void LinkNode(Node* pRoot, Node *pLeft, Node *pRight){
    pRoot->lchild = pLeft;
    pRoot->rchild = pRight;
}

Node *FindKthLargestCore(Node *pRoot, int k, int &counter){
    if (!pRoot || k<1)//invalid input detection & recursion boundary
        return NULL;

    Node *p = FindKthLargestCore(pRoot->rchild, k, counter);
    if (p)
        return p;

    counter++;
    if (k==counter)//another recursion boundary
        return pRoot;

    Node *q = FindKthLargestCore(pRoot->lchild, k, counter);
    if (q)
        return q;

    return NULL;
}

Node *FindKthLargest(Node *pRoot, int k){
    int counter = 0;//count of nodes already traversed
    return FindKthLargestCore(pRoot, k, counter);
}

int main()
{
    Node *pNode = new Node[8];
    pNode[0].Init(4, NULL, NULL);
    pNode[1].Init(2, NULL, NULL);
    pNode[2].Init(6, NULL, NULL);
    pNode[3].Init(1, NULL, NULL);
    pNode[4].Init(3, NULL, NULL);
    pNode[5].Init(5, NULL, NULL);
    pNode[6].Init(7, NULL, NULL);
    pNode[7].Init(0, NULL, NULL);

    LinkNode(&pNode[0], &pNode[1], &pNode[2]);
    LinkNode(&pNode[1], &pNode[3], &pNode[4]);
    LinkNode(&pNode[2], &pNode[5], &pNode[6]);
    LinkNode(&pNode[3], &pNode[7], NULL);

    for (int k = 1; k <= 12; k++){
        Node *pNodeKth = FindKthLargest(pNode, k);
        if (pNodeKth)
            cout<<"The "<<k<<"th Element is : "<<pNodeKth->data<<endl;
        else
            cout<<"The "<<k<<"th Element does not exist!"<<endl;
    }
    
    delete []pNode;
    pNode = NULL;
    return 0;
}

EOF

原文地址:https://www.cnblogs.com/lihaozy/p/2814080.html