把二元查找树转变成排序的双向链表

树、链表

(二叉查找树、双向链表)


一、题目:(感谢 http://blog.csdn.net/v_JULY_v 提供的题目)

把二元查找树转变成排序的双向链表

输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。

要求不能创建任何新的结点,只调整指针的指向。

            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

};


二、题目分析:

1.通过数组摆放构成二叉查找树的数据

2.通过上述数组构成二叉查找树

3.再通过二叉查找树的根节点中序遍历整棵树构成双向链表


三、代码:

#include<iostream>
using namespace std;

struct BSTreeNode
{
    int m_nValue; // value of node
    BSTreeNode *m_pLeft; // left child of node
    BSTreeNode *m_pRight; // right child of node
};

struct DLListNode
{
    int data; //data of node
    DLListNode * prior; //prior point of node
    DLListNode * next; //next point of node
};

class BSTNDLL //Binary search tree and Doubly linked list
{
public :
    //Binary search tree
    void CreateBST(int intArray[],int size); //create a binary search tree by the data in a char array
    void CoutTAll();//cout all data in BSTree
    void CoutTNode(BSTreeNode *node);//cout a node in BSTree
    BSTreeNode * InsertBST(BSTreeNode *root,BSTreeNode *node);//insert a node in BSTree

    //Doubly linked list
    void InsertDLL(DLListNode *node);//insert a node in DLList
    void CoutLAll();//cout all data in DLList
private :
    BSTreeNode *root;
    DLListNode *head;
    int t_size;
};

void BSTNDLL::CoutLAll()
{
    if(t_size == 10)
    {
        head = head->next;
    }
    if(t_size > 0)
    {
        cout<<head->data<<endl;
        head = head->next;
        t_size--;
        CoutLAll();
    }
}

void BSTNDLL::InsertDLL(DLListNode *node)
{
    if(head == NULL)
    {
        head = node;
        head->next = node;
        head->prior = node;
    }else
    {
        node->prior = head;
        node->next = head->next;
        head->next->prior = node;
        head->next = node;
        head = head->next;
    }
}

void BSTNDLL::CreateBST(int intArray[],int size)
{
    root = NULL;
    head = NULL;
    t_size = size;
    for(int i=0;i<size;i++)
    {
        BSTreeNode *node = new BSTreeNode;
        node->m_nValue = intArray[i];
        node->m_pLeft = node->m_pRight = NULL;
        root = InsertBST(root,node);
    }
}

void BSTNDLL::CoutTAll()
{
    CoutTNode(root);
}

BSTreeNode * BSTNDLL::InsertBST(BSTreeNode *n_root,BSTreeNode *node)
{
    if(n_root == NULL)
    {
        n_root = node;
    }else if(node->m_nValue < n_root->m_nValue)
    {
        n_root->m_pLeft = InsertBST(n_root->m_pLeft,node);
    }else
    {
        n_root->m_pRight = InsertBST(n_root->m_pRight,node);
    }
    return n_root;
}

void BSTNDLL::CoutTNode(BSTreeNode *node)
{
    if(node->m_pLeft != NULL)
    {
        CoutTNode(node->m_pLeft);
    }
    //cout<<node->m_nValue<<endl;

    DLListNode * dll_node = new DLListNode;
    dll_node->data = node->m_nValue;
    dll_node->next = dll_node->prior = NULL;
    InsertDLL(dll_node);

    if(node->m_pRight != NULL)
    {
        CoutTNode(node->m_pRight);
    }
}

void main()
{
    BSTNDLL bstNdll;
    int a[] = {10,6,14,4,8,12,16,23,43,1};
    bstNdll.CreateBST(a,10);
    bstNdll.CoutTAll();
    bstNdll.CoutLAll();
}



四、代码分析:

1.往二叉查找树插入数据

BSTreeNode * BSTNDLL::InsertBST(BSTreeNode *n_root,BSTreeNode *node)
{
	if(n_root == NULL)
	{
		n_root = node;
	}else if(node->m_nValue < n_root->m_nValue)
	{
		n_root->m_pLeft = InsertBST(n_root->m_pLeft,node);
	}else
	{
		n_root->m_pRight = InsertBST(n_root->m_pRight,node);
	}
	return n_root;
}

思路:

(1)如被插节点为空,把节点赋给被插结点

(2)如节点值小于被插节点的左子树值,把节点插入被插节点的左子树

(3)否则把节点插入被插节点的左子树


2.往双向链表插入数据

void BSTNDLL::InsertDLL(DLListNode *node)
{
	if(head == NULL)
	{
		head = node;
		head->next = node;
		head->prior = node;
	}else
	{
		node->prior = head;
		node->next = head->next;
		head->next->prior = node;
		head->next = node;
		head = head->next;
	}
}

思路:

在结点h后插入一个结点n,需要修改四个指针

(1)n->prior = h;

(2)n->next = h->next;

(3)h->next->prior = n;

(4)h->next = n;



五、改进:

看到网上很多资料,发现这个题目并不是要求构建两个结构体(先构建一棵树后再构建一个双向链表)

而是通过调整树的指针令其变为双向链表(由始至终只有一个结构体),OMG~


 5.1.题目分析:

(1) 建立查找二叉树

(2) 设定双向链表的头指针 *head 和尾指针 *last

(3) 中序遍历二叉查找树(顺序输出)时,调用 changeBSTtoDLL() 函数,调整查找二叉树的指针指向


5.2.代码:

//中序遍历
void BSTNDLL::CoutTNode(BSTreeNode *node)
{
	if(node->m_pLeft != NULL)
	{
		CoutTNode(node->m_pLeft);
	}

	//cout<<node->m_nValue<<endl;

	changeBSTtoDLL(node);

	if(node->m_pRight != NULL)
	{
		CoutTNode(node->m_pRight);
	}
}

//调整查找二叉树指针指向
void BSTNDLL::changeBSTtoDLL(BSTreeNode *node)
{
	if(head == NULL && last == NULL)
	{
		head = last = node;
	}
	else{
		node->m_pLeft = last;   //使当前左节点指向双向链表的最后一位
		last->m_pRight = node;  //把双向链表的最后一位右节点指向当前节点
		last = node;            //把当前节点设置为双向链表的最后一位
	}
}



5.3.代码分析:

调整查找二叉树指针指向思路:

使当前左节点指针指向last,last右节点指针指向当前节点,把当前节点赋值给last


即:

1.使当前左节点指向双向链表的最后一位;

node->m_pLeft = last;

2.把双向链表的最后一位右节点指向当前节点;

last->m_pRight = node;

3.把当前节点设置为双向链表的最后一位。

last = node;


六、总结:

    在本题目中,我清楚认识到查找二叉树、双向链表的构造,如何使用代码建立查找二叉树和双向链表,同时认识到二叉查找树和双向链表的结构的相同之处,能通过简单地通过调整指针的指向进行互换。


#include<iostream>
using namespace std;

struct BSTreeNode
{
	int m_nValue; // value of node
	BSTreeNode *m_pLeft; // left child of node
	BSTreeNode *m_pRight; // right child of node
};

struct DLListNode
{
	int data; //data of node
	DLListNode * prior; //prior point of node
	DLListNode * next; //next point of node
};

class BSTNDLL //Binary search tree and Doubly linked list
{
public :
	//Binary search tree
	void CreateBST(int intArray[],int size); //create a binary search tree by the data in a char array
	void CoutTAll();//cout all data in BSTree
	void CoutTNode(BSTreeNode *node);//cout a node in BSTree
	BSTreeNode * InsertBST(BSTreeNode *root,BSTreeNode *node);//insert a node in BSTree

	//Doubly linked list
	void CoutLAll();//cout all data in DLList

	//Change a BSTree to DLList
	void changeBSTtoDLL(BSTreeNode *node);

private :
	BSTreeNode *root;
	BSTreeNode *head;
	BSTreeNode *last;
	int t_size;

};

void BSTNDLL::CoutLAll()
{
	if(t_size > 0)
	{
		cout<<head->m_nValue<<endl;
		head = head->m_pRight;
		t_size--;
		CoutLAll();
	}
}

void BSTNDLL::CreateBST(int intArray[],int size)
{
	root = NULL;
	head = NULL;
	last = NULL;
	t_size = size;
	for(int i=0;i<size;i++)
	{
		BSTreeNode *node = new BSTreeNode;
		node->m_nValue = intArray[i];
		node->m_pLeft = node->m_pRight = NULL;
		root = InsertBST(root,node);
	}
}

void BSTNDLL::CoutTAll()
{
	CoutTNode(root);
	last->m_pRight = head;
}

BSTreeNode * BSTNDLL::InsertBST(BSTreeNode *n_root,BSTreeNode *node)
{
	if(n_root == NULL)
	{
		n_root = node;
	}else if(node->m_nValue < n_root->m_nValue)
	{
		n_root->m_pLeft = InsertBST(n_root->m_pLeft,node);
	}else
	{
		n_root->m_pRight = InsertBST(n_root->m_pRight,node);
	}
	return n_root;
}

void BSTNDLL::CoutTNode(BSTreeNode *node)
{
	if(node->m_pLeft != NULL)
	{
		CoutTNode(node->m_pLeft);
	}

	//cout<<node->m_nValue<<endl;

	changeBSTtoDLL(node);

	if(node->m_pRight != NULL)
	{
		CoutTNode(node->m_pRight);
	}
}

void BSTNDLL::changeBSTtoDLL(BSTreeNode *node)
{
	if(head == NULL && last == NULL)
	{
		head = last = node;
	}
	else{
		node->m_pLeft = last;
		last->m_pRight = node;
		last = node;
	}
}

void main()
{
	BSTNDLL bstNdll;
	int a[] = {10,6,14,4,8,12,16,23,43,1};
	bstNdll.CreateBST(a,10);
	bstNdll.CoutTAll();
	bstNdll.CoutLAll();
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值