二叉树转双向链表
核心:就是中序遍历二叉树,然后将遍历到的节点放入双向链表中
基本框架:首先你得写一个二叉树的中序遍历的程序
// ---- C++ ---------
struct BTNode // 二叉树的节点结构体
{
int val;
BTNode * left;
BTNOde * right;
BTNode(){ // 构造函数,防止在new一个节点时,忘了初始化里面的指针
left = nullptr;
right = nullptr;
};
// 典型的中序遍历是没有第二个list参数的,这里的list是用来接收将转换得到的链表的。
// *&是指针的引用。
void BTree2ListCore(BTNode * root, BTNode *&list)
{
// 中序遍历最典型的递归写法的退出条件
if (root == nullptr)
return;
BTree2ListCore(root->left, list);
// --下面的xxx是对于当前节点的处理,目前只是个中序遍历的框架,故先保留不写
// xxx
BTree2List(root->right, list);
}
修改中序遍历,将二叉树变成双向链表
二叉树之所以可转换为双向链表,是因为二叉树的节点结构和双向链表的节点结构是一样的,将二叉树的节点的left指针看作双向链表的指向前一个的pre指针;将二叉树的节点的right指针看作是双向链表的指向后一个的Next指针。
因此将二叉树转为双向链表,需要两步操作:将当前二叉树节点的左指针指向当前链表节点,同时将当前的链表节点的右指针指向当前二叉树节点。也就是二叉树节点和链表节点互相指向对方,形成了双向链表。感觉我说的好像也不是很清楚,写成代码就是四行,我想应该会比较清楚
// 下面几行代码被是放在上面的中序遍历框架的// xxx部分的
root->left = list; // 当前二叉树节点左指针指向链表节点
if (list != nullptr) //l链表=nullptr,就没有right指针了
{
list->right = root;
}
list = root; // 移动链表指针到当前二叉树节点
完整的程序是这样的
struct BTNode
{
int val;
BTNode * left;
BTNOde * right;
BTNode(){
left = nullptr;
right = nullptr;
};
void BTree2ListCore(BTNode * root, BTNode *&list)
{
if (root == nullptr)
return;
BTree2ListCore(root->left, list);
// --下面的xxx是对于当前节点的处理
root->left = list; // 当前二叉树节点左指针指向链表节点
if (list != nullptr) //l链表=nullptr,就没有right指针了
{
list->right = root;
}
list = root; // 移动链表指针到当前二叉树节点
BTree2List(root->right, list);
}
// 上述代码最后得到的list指针指向了链表的尾部(最右边),一般还会做个处理,将list移到最前面(最左边)
BTNode * BTree2List(BTNode * root)
{
// 异常处理好习惯
if (root == nullptr)
return nullptr;
BTNode * list = nullptr;
BTree2ListCore(root, list);
while (list->left != nullptr)
list = list->left;
return list;
}
// 代码纯手打,有可能有小的拼写错误,望谅解