搜索二叉树转为有序双向链表

觉得有必要定期做一些简单算法题,这样做的好处至少有四:

1. 提高代码能力

2. 通过解释解决方案,锻炼表达能力

3. 形成习惯,锻炼坚持和专注的能力

4. 在这个过程中,积累博客的内容,以备不时之需,如某些公司招聘


分析:

搜索二叉树的特点是节点左边的所有后代小于该节点,左边的所有后代大于该节点。因此分别将左子树和右子树转换为有序双向链表,再和根节点连接起来就得到了整个搜索树对应的有序双向链表。这是一个明显的递归过程。

#include <iostream>
using namespace std;

/**
Node of binary search tree.
*/
struct BSTreeNode
{
  int m_nValue;
  BSTreeNode *m_pLeft;
  BSTreeNode *m_pRight;
  BSTreeNode(int value) {
    m_nValue = value;
    m_pLeft = m_pRight = 0;
  }
};

void printBSTree(BSTreeNode *tree) {
    if(tree->m_pLeft != NULL) {
        printBSTree(tree->m_pLeft);
    }
    cout << tree->m_nValue << " ";
    if(tree->m_pRight != NULL) {
        printBSTree(tree->m_pRight);
    }
}

/**
Node of double linked list.
*/
struct DLList
{
    BSTreeNode *m_pHead;
    BSTreeNode *m_pTail;
};

void printDLList(DLList *list) {
    BSTreeNode *p = list->m_pHead;
    while(true) {
        cout << p->m_nValue << " ";
        if(p == list->m_pTail) break;
        p = p->m_pRight;
    }
}

DLList* tranBSTreeToDLList(BSTreeNode* tree) {
    if(tree == NULL) {
        return NULL;
    }
	DLList *left = tranBSTreeToDLList(tree->m_pLeft);
	DLList *right = tranBSTreeToDLList(tree->m_pRight);

    DLList *newList = new DLList();
    newList->m_pHead = newList->m_pTail = tree;
    if(left != NULL) {
        newList->m_pHead = left->m_pHead;
        left->m_pTail->m_pRight = tree;
        tree->m_pLeft = left->m_pTail;
    }
    if(right != NULL) {
        newList->m_pTail = right->m_pTail;
        tree->m_pRight = right->m_pHead;
        right->m_pHead->m_pLeft = tree;
    }

    return newList;
}

int main() {
	BSTreeNode *root = new BSTreeNode(10);
    root->m_pLeft = new BSTreeNode(6);
    root->m_pRight = new BSTreeNode(14);
    root->m_pLeft->m_pLeft = new BSTreeNode(4);
    root->m_pLeft->m_pRight = new BSTreeNode(8);
    root->m_pRight->m_pLeft = new BSTreeNode(12);
    root->m_pRight->m_pRight = new BSTreeNode(16);

    printBSTree(root);
    cout << endl;
    DLList *list = tranBSTreeToDLList(root);
    printDLList(list);
    cout << endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值