算法面试100题——1、把二元查找树转变成排序的双向链表

本文介绍如何将一棵二叉查找树转换为排序的双向链表,提供了两种实现方式:递归方法和使用栈的非递归方法,并通过示例展示了转换过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。

10
/ \
6 14
/ \ / \
4 8 12 16

转换成双向链表
4=6=8=10=12=14=16。

首先我们定义的二元查找树 节点的数据结构如下:
struct BSTreeNode
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};

/*用途:
**说明:
**算法:
*/

//#define LOCAL
#include <cstdio>
#include <cstdlib>
#include <stack>
using namespace std;

struct BSTreeNode
{
  int m_nValue;
  BSTreeNode *m_pLeft;
  BSTreeNode *m_pRight;
};
typedef BSTreeNode* BST;
BSTreeNode* NewNode();
BSTreeNode* NewNode(int v);
//递归实现
BSTreeNode* ToDLinkList(BST bst);
void Traverse(BST bst, BSTreeNode* &pre);
//显示栈实现 
BSTreeNode* ToDLinkList2(BST bst); 
void TestHead(BSTreeNode* head);
void TestTail(BSTreeNode* tail);
int main()
{
#ifdef LOCAL
    freopen(".in", "r", stdin);
    freopen(".out", "w", stdout);
#endif

    BST bst = NewNode();
    BSTreeNode *n0 = NewNode(10);
    bst->m_pLeft = n0;

    BSTreeNode *n1 = NewNode(6);
    n0->m_pLeft = n1;
    BSTreeNode *n2 = NewNode(14);
    n0->m_pRight = n2;

    BSTreeNode *n3 = NewNode(4);
    n1->m_pLeft = n3;
    BSTreeNode *n4 = NewNode(8);
    n1->m_pRight = n4;

    BSTreeNode *n5 = NewNode(12);
    n2->m_pLeft = n5;
    BSTreeNode *n6 = NewNode(16);
    n2->m_pRight = n6;

    BSTreeNode* tail = bst->m_pLeft;    //测试尾指针 
    while(tail->m_pRight)
        tail = tail->m_pRight;
    BSTreeNode* head;
//  head = ToDLinkList(bst);    //递归实现
    head = ToDLinkList2(bst);   //显示栈实现

    TestHead(head);
    printf("\n");
    TestTail(tail);

    return 0;
}

BSTreeNode* NewNode()
{
    BSTreeNode* pNode = (BSTreeNode*)malloc(sizeof(BSTreeNode));
    pNode->m_pLeft = pNode->m_pRight = NULL;
    return pNode;
}

BSTreeNode* NewNode(int v)
{
    BSTreeNode* pNode = (BSTreeNode*)malloc(sizeof(BSTreeNode));
    pNode->m_nValue = v;
    pNode->m_pLeft = pNode->m_pRight = NULL;
    return pNode;
}

//递归实现
BSTreeNode* ToDLinkList(BST bst)
{
    BSTreeNode* head = bst;
    while(head->m_pLeft)
        head = head->m_pLeft;
    BSTreeNode* pre = NULL;     //当前节点的前一个指针 
    Traverse(bst->m_pLeft, pre);
    return head;
}

void Traverse(BST bst, BSTreeNode* &pre)
{
    if(bst != NULL){
        Traverse(bst->m_pLeft, pre);

        bst->m_pLeft = pre;
        if(pre)
            pre->m_pRight = bst;

        pre = bst;
        Traverse(bst->m_pRight, pre);
    }
}

//显示栈实现
BSTreeNode* ToDLinkList2(BST bst)
{
    stack<BSTreeNode*> s;
    BSTreeNode* head = bst;
    while(head->m_pLeft)
        head = head->m_pLeft;

    BSTreeNode* pre = NULL;
    BSTreeNode* p = bst->m_pLeft;
    while(!s.empty() || p){
        if(p){
            s.push(p);
            p = p->m_pLeft;
        }
        else{
            BSTreeNode* m_pTop = s.top();
            s.pop();
            m_pTop->m_pLeft = pre;
            if(pre)
                pre->m_pRight = m_pTop;

            pre = m_pTop;
            if(m_pTop->m_pRight)
                p = m_pTop->m_pRight;
        }
    }
    return head;
} 

void TestHead(BSTreeNode* head)
{
    while(head){
        printf("%d ", head->m_nValue);
        head = head->m_pRight;
    }
}

void TestTail(BSTreeNode* tail)
{
    while(tail){
        printf("%d ", tail->m_nValue);
        tail = tail->m_pLeft;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值