#include<iostream>
#include <queue>
using namespace std;
struct BianrySearchThree{
int data;
BianrySearchThree* lChild;
BianrySearchThree* rChild;
BianrySearchThree(int value){
data = value;
lChild = NULL;
rChild = NULL;
}
};
/*建立一个二叉搜索树(也就是一颗排序好了的树)
注意这里是“ BianrySearchThree* &root不是BianrySearchThree* root ” */
void Insert(BianrySearchThree* &root, int value){
if(NULL == root){
root = new BianrySearchThree(value);
}else if(value > root->data){
Insert(root->rChild, value);
}else if(value < root->data){
Insert(root->lChild, value);
}else{
;
}
}
void ShowMiddleTree(BianrySearchThree* root){
if(NULL == root){
return;
}
ShowMiddleTree(root->lChild);
cout<<root->data<<" ";
ShowMiddleTree(root->rChild);
}
void ShowPreTree(BianrySearchThree* root){
if(NULL == root){
return;
}
cout<<root->data<<" ";
ShowMiddleTree(root->lChild);
ShowMiddleTree(root->rChild);
}
void ShowPostTree(BianrySearchThree* root){
if(NULL == root){
return;
}
ShowMiddleTree(root->lChild);
ShowMiddleTree(root->rChild);
cout<<root->data<<" ";
}
void BreathSearch(BianrySearchThree* root){
if(NULL == root){
return;
}
std::queue<BianrySearchThree*> q;
q.push(root);
while(!q.empty()){
BianrySearchThree* node = q.front();
q.pop();
cout<<node->data<<" ";
if(node->lChild){
q.push(node->lChild);
}
if(node->rChild){
q.push(node->rChild);
}
}
}
void ShowList(BianrySearchThree* root){
if(NULL==root)
return ;
while(root){
cout<<root->data<<" ";
root = root->rChild;
}
cout<<endl;
}
/*返回链表的头节点
主要思路:通过递归的方式,以及中序遍历的原理,将树分为左边子树,root,右子树
然后:
1、通过递归遍历到左边子树的叶子结点,也就是最左最下以及最小的那个节点。
2、定义一个临时的链表指针,将这个指针的next指向当前叶子结点,叶子结点的pre指向这个临时的tail,
3、然后将这个临时头指针向后移动到当前叶子结点。
4、此时继续遍历这个叶子结点的右结点,但是右结点为空,所以本节点递归回退到上一级结点,
5、此时上一级结点,此时递归代码将会执行到左结点递归完成的下一条语句,此时的又把cur结点的pre执行tail结点(此时指向的是开始那个左叶子结点)
6、然后再把tail->next指向cur这个节点,然后再递归k扫描右边节点(其实就是直接扫描到当前结点最右边的叶子结点)
7、此时右进入这个函数,此时这个节点没有左孩子,就直接执行这个叶子结点指向开始的tail,tail指向这个节点,这样这个递归完成后,函数又回到了
8、此时就回到再上一级的节点了。z
9、这样一级一级的往上走。。。
注意这里递归的返回其实就是回退到上一级,因为递归其实就是栈的原理,下面的处理完了当回退回去的时候就是弹出处理了的 处理栈剩下了的
*/
void TransferBstToList(BianrySearchThree *head, BianrySearchThree **list_tail){
if(head == NULL){
return;
}
BianrySearchThree *cur = head;
TransferBstToList(cur->lChild, list_tail);
cur->lChild = *list_tail;/*当前节点指向tail节点*/
if(*list_tail != NULL){
(*list_tail)->rChild = cur;/*tail节点指向当前节点*/
}
(*list_tail) = cur;/*移动tail指针指向当前节点*/
TransferBstToList(cur->rChild, list_tail);
}
BianrySearchThree * TransferBstToSortList(BianrySearchThree *head){
if(NULL == head){
return head;
}
BianrySearchThree *listTail = NULL;
TransferBstToList(head, &listTail);/*但是这里得到指针是指向的链表的tail位置,所以需要移动到前面去*/
/*往前遍历*/
/*这里不能把listTail指向了没有的位置了,因此需要增加一个限制listTail->lChild不为空,这里就限制了这个lastNode做多能走到链表头,而不是指向链表头的lChild(一个空位置)。*/
while(listTail && listTail->lChild){
listTail = listTail->lChild;
}
return listTail;
}
int main(){
int treeData[9]={12,5,18,2,9,15,19,17,16};
BianrySearchThree *tree = NULL;
for(int i = 0; i < 9 ;i++ ){
Insert(tree,treeData[i]);
}
ShowMiddleTree(tree);
cout<<endl;
BianrySearchThree *list=TransferBstToSortList(tree);
ShowList(list);
cout<<endl;
}