非递归实现二叉搜索树转化成双链表

Posted zhou753099943

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了非递归实现二叉搜索树转化成双链表相关的知识,希望对你有一定的参考价值。

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

4=6=8=10=12=14=16。

分析:

代码难理解的地方我都已经注释了,为什么要写非递归的实现,是因为我在看剑指offer的时候,上面是递归实现的,而我是一个不安分的人,所以手痒就写了个非递归的,但在看我的实现之前,希望你对二叉树的非递归的中序遍历很清楚,不然我不能保证你能很快看懂我写的;话不多说,看code:

file.h

#include <iostream>
#include <stack>
#include <assert.h>
using namespace std;

template<class Type>
struct TreeNode

	Type _data;
	struct TreeNode<Type> *leftchild;
	struct TreeNode<Type> *rightchild;

	TreeNode(Type data=Type())
		:_data(data),leftchild(NULL),rightchild(NULL)
	
;

template<class Type>
class Tree

	typedef struct TreeNode<Type> TreeNode;
public:
	Tree():_root(NULL)  
public:
	void CreateTree(Type x)
	
		CreateTree(_root,x);
	
	void InOrder()
	
		InOrder(_root);
	
	void TreeToList()
	
		TreeNode *head=TreeToList(_root);
		cout<<"转化成双链表后:";
		show(head);
	
	//显示双链表
	void show(TreeNode *root)
	
		TreeNode *cur=root;
		while(cur !=NULL)
		
			cout<<cur->_data<<" ";
			cur=cur->rightchild;
		
		cout<<endl;
	
public:
	void CreateTree(TreeNode *&root,Type x)
	
		if(root ==NULL)
		
			root=new TreeNode(x);
			return;
		
		TreeNode *cur=root;
		TreeNode *parent=root;
		while(cur !=NULL)
		
			parent=cur;
			if(x < cur->_data)
				cur=cur->leftchild;
			else if(x > cur->_data)
				cur=cur->rightchild;
			else
				return;
		
		TreeNode *tmp=new TreeNode(x);
		if(x < parent->_data)
			parent->leftchild=tmp;
		else
			parent->rightchild=tmp;
	
	void InOrder(TreeNode *root)
	
		if(root==NULL)
			return;
		InOrder(root->leftchild);
		cout<<root->_data<<" ";
		InOrder(root->rightchild);	
	
public:
	//实现将二叉搜索树转化成双链表
	//只要知道二叉搜索树中序遍历,接下来的代码阅读将没有问题
	//如果你对二叉树的中序遍历不熟悉,那建议先把二叉树的中序遍历弄清楚再我的实现,
	//这样不会让你在看的时候感觉心神不定
	TreeNode* TreeToList(TreeNode *root)
	
		assert(root);
		TreeNode *cur=root;
		TreeNode *ptr=NULL;
		TreeNode *head=NULL;//主要保存头节点

		stack<TreeNode*> s;
		s.push(root);
		while(!s.empty())
		
			if(cur !=NULL)//保证将双二叉树左孩子改变指向后不进入
			
				while(cur->leftchild !=NULL)
				
					s.push(cur->leftchild);
					cur=cur->leftchild;
				
			
			//保存上一个被访问后的节点,
			//以此来将此次访问的节点的左孩子链接到上一个节点
			TreeNode *tmp=ptr;

			ptr=s.top();
			s.pop();

			ptr->leftchild=tmp;//将正在被访问的节点左子树链接到上一个节点
			cur=NULL;  //这步很重要,真的很重要,因为当前节点左孩子的指向已经被改变
			if(tmp !=NULL)
				tmp->rightchild=ptr;
			else if(tmp ==NULL)//主要保存头节点
				head=ptr;

			if(ptr->rightchild !=NULL)
			
				s.push(ptr->rightchild);
				cur=ptr->rightchild;  //这步也很重要,改变cur的指向
			
		
		return head;
	
private:
	TreeNode *_root;
;
main.cpp

#include "file.h"





void TestTree()

	Tree<int> t;
	int data;
	while(cin>>data && data !=-1)
	
		t.CreateTree(data);
	
	cout<<"二叉搜索树中序遍历:";
	t.InOrder();
	cout<<endl;
	t.TreeToList();

int main()

	TestTree();
	return 0;






最后想说一下,最近发现很多网站都很喜欢直接爬别人写的文章到自己的服务器里并把专栏的名称也改了,这样才不道德了,这里强调一下我的博客专栏名称只有一个,并附上图




以上是关于非递归实现二叉搜索树转化成双链表的主要内容,如果未能解决你的问题,请参考以下文章

刷题记录-剑指offer36:二叉搜索树与双向链表

刷题记录-剑指offer36:二叉搜索树与双向链表

LeetCode 114| Flatten Binary Tree to Linked List(二叉树转化成链表)

二叉搜索树

数据结构——搜索二叉树的插入,查找和删除(递归&非递归)

剑指offer:二叉搜索树与双向链表