• [CareerCup] 17.13 BiNode 双向节点


    17.13 Consider a simple node-like data structure called BiNode, which has pointers to two other nodes. The data structure BiNode could be used to represent both a binary tree (where nodel is the left node and node2 is the right node) or a doubly linked list (where nodel is the previous node and node2 is the next node). Implement a
    method to convert a binary search tree (implemented with BiNode) into a doubly linked list. The values should be kept in order and the operation should be performed in place (that is, on the original data structure).

    这道题定义了一个双向节点BiNode的类,其既可以表示二叉树的结构,也可以表示为双向链表的结构,让我们把一个二叉树的结构转化为双向链表的结构。我们有很多种方法可以实现,首先来看一种建立一种新数据结构NodePair类,保存了链表的首节点和尾节点,用递归的方法来实现压平二叉树,参见代码如下:

    解法一:

    class BiNode {
    public:
        BiNode *node1;
        BiNode *node2;
        int data;
        BiNode(int d): data(d), node1(NULL), node2(NULL) {}
    };
    
    class NodePair {
    public:
        BiNode *head;
        BiNode *tail;
        NodePair(BiNode *h, BiNode *t): head(h), tail(t) {}
    };
    
    void concat(BiNode *x, BiNode *y) {
        x->node2 = y;
        y->node1 = x;
    }
    
    NodePair* convert(BiNode *root) {
        if (!root) return NULL;
        NodePair *part1 = convert(root->node1);
        NodePair *part2 = convert(root->node2);
        if (part1) concat(part1->tail, root);
        if (part2) concat(root, part2->head);
        return new NodePair(part1 ? part1->head : root, part2 ? part2->tail : root);
    }

    我们也可以不使用别的数据结构,那么我们如何返回链表的首结点和尾结点呢,我们可以返回首结点,然后通过遍历链表来找到尾结点,参见代码如下:

    解法二:

    int cnt = 0;
    class BiNode {
    public:
        BiNode *node1;
        BiNode *node2;
        int data;
        BiNode(int d): data(d), node1(NULL), node2(NULL) {}
    };
    
    
    void concat(BiNode *x, BiNode *y) {
        x->node2 = y;
        y->node1 = x;
    }
    
    BiNode* get_tail(BiNode *node) {
        if (!node) return NULL;
        while (node->node2) {
            ++cnt;
            node = node->node2;
        }
        return node;
    }
    
    BiNode* convert(BiNode *root) {
        if (!root) return NULL;
        BiNode *part1 = convert(root->node1);
        BiNode *part2 = convert(root->node2);
        if (part1) concat(get_tail(part1), root);
        if (part2) concat(root, part2);
        return part1 ? part1 : root;
    }

    还有一种方法是创建一个循环链表,当我们建立了循环链表,那么我们返回首结点时,尾结点可以通过head->node1直接找到,参见代码如下:

    解法三:

    class BiNode {
    public:
        BiNode *node1;
        BiNode *node2;
        int data;
        BiNode(int d): data(d), node1(NULL), node2(NULL) {}
    };
    
    void concat(BiNode *x, BiNode *y) {
        x->node2 = y;
        y->node1 = x;
    }
    
    BiNode* convert_to_circular(BiNode *root) {
        if (!root) return NULL;
        BiNode *part1 = convert_to_circular(root->node1);
        BiNode *part3 = convert_to_circular(root->node2);
        if (!part1 && !part3) {
            root->node1 = root;
            root->node2 = root;
            return root;
        }
        BiNode *tail3 = part3 ? part3->node1 : NULL;
        // Join left to root
        if (!part1) concat(part3->node1, root);
        else concat(part1->node1, root);
        // Join right to root
        if (!part3) concat(root, part1);
        else concat(root, part3);
        // Join right to left
        if (part1 && part3) concat(tail3, part1);
        return part1 ? part1 : root;
    }
    
    BiNode* convert(BiNode *root) {
        BiNode *head = convert_to_circular(root);
        head->node1->node2 = NULL;
        head->node1 = NULL;
        return head;
    }

    CareerCup All in One 题目汇总

  • 相关阅读:
    SQL表结构
    Mssql 行转列
    动态Order by
    Nopi Excel导入
    使用SyncToy 同步两台机器上的文件夹
    ueditor1.4.3 在IE8下的 BUG
    WebService国内省市县接口
    AsyncTask的参数介绍
    Json分割并解析
    JQuery iframe页面操作父页面中的元素与方法
  • 原文地址:https://www.cnblogs.com/grandyang/p/5445488.html
Copyright © 2020-2023  润新知