二叉树转换为双向链表

需求
输入一棵二叉搜索树,将该二叉树转换成一个排序的双向链表,
(要求:不能创建任何新的节点只能调整树中指针的指向)
例如:
这里写图片描述
转换成双向链表后:
这里写图片描述
线索
在二叉搜索树中,左子树的值总是比根节点,右子树的值总是大于根节点,因此我们在将二叉搜索树变换成双向链表时,原先指向左子节点的指针调整为链表中指向前一个节点的指针,原先指向右子节点的指针调整为指向后一个节点的指针。
为了记录已经调整好的链表,需要一个指向链表尾节点的指针。
只有二叉树的中序遍历是有序的,所以解决本题必须要用到二叉树的中序遍历。
实现

void convertTreeCore(BTNode *pNode, BTNode **pLastInList){
    if (!pNode){
        //数据非法,
        return;
    }
    BTNode *pc = pNode;

    if (pNode->left){
        convertTreeCore(pNode->left,pLastInList);
    }
    pc->left = *pLastInList;//将之前的链表挂到当前的二叉树节点
    if (*pLastInList){//说明当前的链表不是空链表,将当前二叉树节点挂到双向链表的后面
        (*pLastInList)->right = pc;
    }
    *pLastInList = pc;//双向链表的尾指针后移,指向当前链表的尾节点
    if (pNode->right){
        convertTreeCore(pNode->right, pLastInList);
    }
}
BTNode* convertTree(BTNode *root){
    BTNode *pLastInList = NULL;
    convertTreeCore(root, &pLastInList);
    //执行完上面函数,pLastInList指向当前链表的尾节点
    BTNode *head = pLastInList;
    while (head != NULL&&head->left){//判断head是否为空的目的是想判断传入的元素第否合法
        head = head->left;
    }
    return head;

}

调试代码:

//定义二叉树的节点
typedef struct node{
    int data;
    struct node *left;
    struct node *right;
}BTNode;

//创建二叉搜索树
BTNode* creatBinSortTree(int data[], int len){
    BTNode *root = NULL, *p = NULL, *pa = NULL, *c = NULL;
    for (int i = 0; i < len; i++){
        //为新的节点分配单元
        p = (BTNode*)malloc(sizeof(BTNode));
        p->data = data[i];
        p->left = p->right = NULL;
        if (!root){
            root = p;
        }
        else{
            c = root;
            while (c){
                pa = c;
                if (c->data < p->data){
                    c = c->right;
                }
                else{
                    c = c->left;
                }
            }
            if (pa->data < p->data){
                pa->right = p;
            }
            else{
                pa->left = p;
            }
        }
    }
    return root;
}
//中序遍历二叉树
void inOrder(BTNode *root){
    if (root){
        inOrder(root->left);
        printf("%d ", root->data);
        inOrder(root->right);
    }
}
//打印双向链表
void printLink(BTNode *head){
    for (BTNode *p = head; p; p = p->right){
        printf("%d ",p->data);
    }
}
//主函数
int main(void){
    int data[8] = { 3, 2, 5, 8, 4, 7, 6, 9 };
    BTNode *root = creatBinSortTree(data, 8);
    //中序遍历二叉树
    inOrder(root);
    printf("\n");
    BTNode *head = convertTree(root);
    //打印双向链表
    printLink(head);
    system("pause");
    return 0;
}

调试结果:
这里写图片描述
思考:
能否将一个双向链表调整成二叉搜索树?
答:我认为不能,因为无法确定该二叉树的根节点是哪个元素。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值