#include <iostream>
using namespace std;
/**
* 遞迴實現將二叉排序樹BST轉換成排序的雙向連結串列。
* 遞迴左子樹,將左子樹的轉換成的連結串列的尾節點和當前根節點連線,
* 然後當前根節點更新尾轉換好連結串列的尾節點。 遞迴右子樹
*/
typedef struct node{
int value;
struct node *lchild;
struct node *rchild;
}NODE;
NODE *createNode(int v){
NODE *p = (NODE *)malloc(sizeof(NODE));
p->value = v;
p->lchild = NULL;
p->rchild = NULL;
return p;
}
//建立一棵樹作為測試
NODE *buildTree(){
NODE *root,*p,*q;
root = createNode(8);
p = createNode(4);
root->lchild = p;
q = createNode(3);
p->lchild = q;
q = createNode(6);
p->rchild = q;
p = q;
q = createNode(5);
p->lchild = q;
p = createNode(10);
root->rchild = p;
q = createNode(9);
p->lchild = q;
q = createNode(12);
p->rchild = q;
return root;
}
/**
* 將BST遞迴轉換成雙向排序連結串列,隨時維護已轉換好的連結串列的尾節點
*/
void transformToList(NODE *root, NODE **listLastNode){
//空節點,不進行任何轉換
if(root == NULL) return;
//如果左子樹不空,遞迴左子樹
if(root->lchild != NULL){
transformToList(root->lchild, listLastNode);
}
//將自己和左子樹轉換成的連結串列的最後一個節點相互連線
if(*listLastNode != NULL) (*listLastNode)->rchild = root;
root->lchild = *listLastNode;
//把當前節點作為轉換好的連結串列的尾節點,遞迴處理右子樹
//右子樹遞迴到最左孩子的時候,會和listLastNode相互連線的
*listLastNode = root;
if(root->rchild != NULL){
transformToList(root->rchild, listLastNode);
}
}
int main(){
NODE *listLastNode = NULL;
NODE *root = buildTree();
//轉換
transformToList(root, &listLastNode);
//逆序輸出
while(listLastNode != NULL){
cout<<listLastNode->value<<" ";
listLastNode = listLastNode->lchild;
}
cout<<endl;
return 0;
}