C++将一颗有序二叉树(二叉搜素树)转换成一个双向链表#include<iostream> #include <queue> using namespace std; struct BianrySe

#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;
    
}



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值