二叉树转双向链表|数据结构和算法

二叉树转双向链表

核心:就是中序遍历二叉树,然后将遍历到的节点放入双向链表中

基本框架:首先你得写一个二叉树的中序遍历的程序

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

// 代码纯手打,有可能有小的拼写错误,望谅解
发布了12 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/void_xinyue/article/details/93139242