觉得有必要定期做一些简单算法题,这样做的好处至少有四:
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;
}