二叉搜索树转换成双向链表

  题目来源:《剑指offer》面试题27

  题目:输入是一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新节点,只能调整树种节点指针的指向。二叉树节点的定义如下:

struct BinaryTreeNode {
    int val;
    BinaryTreeNode* left;
    BinaryTreeNode* right
};

  分析:由于要求转换后的链表是排好序的,我们可以中序遍历树种的每个节点,这是因为中序遍历算法的特点是按照从小到大的顺序遍历二叉树的每个节点。当遍历到根节点的时候,我们就把它与左子树最大的节点连接起来,同时它还将和右子树最小的节点连接起来。

BinaryTreeNode* Convert(BinaryTreeNode* root) {
    BinaryTreeNode* lastNodeInList = NULL;
    ConverNode(root, &lastNodeInList);

    //lastNodeInlist指向双向链表
    //我们需要返回头节点
    BinaryTreeNode* head = lastNodeInList;
    while (head != NULL && head->left = NULL) {
        head = head->left;
    }

    return head;
}

void ConverNode(BinaryTreeNode* root, BinaryTreeNode** lastNodeInList) {
    if (root == NULL)
        return;

    if (root->left != NULL)
        ConverNode(root->left, lastNodeInList);

    root->left = *lastNodeInList;

    if (*lastNodeInList != NULL)
        (*lastNodeInList)->right = root;

    *lastNodeInList = root;

    if (root->right != NULL)
        ConverNode(root->right, lastNodeInList);
}

 

  下面是一个迭代的版本:

BinaryTreeNode* Convert(BinaryTreeNode* root) {
    if (root == NULL) return NULL;

    BinaryTreeNode* p = root;
    BinaryTreeNode* head = NULL;
    BinaryTreeNode* pre = NULL;

    stack<BinaryTreeNode*> s;

    while (p != NULL || !s.empty()) {
        if (p != NULL) {
            s.push(p);
            p = p->left;
        } else {
            p = s.top();
            if (head == NULL)
                head = p;
            if (pre == NULL) {
                p->left = pre;
            } else {
                pre->right = p;
                p->left = pre;
            }
            p = p->right;
        }
    }


    return head;
}

 

posted @ 2015-09-01 23:01  vincently  阅读(1469)  评论(0编辑  收藏  举报