把二元查找树转变成排序的双向链表
2012-07-27 20:47
429 查看
树、链表
(二叉查找树、双向链表)
一、题目:(感谢 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();
}
相关文章推荐
- 二元查找树转变成排序的双向链表
- 把二元查找树转变成排序的双向链表
- 算法与数据结构面试题(1)-把二元查找树转变成排序的双向链表
- 把二元查找树转变成排序的双向链表
- 把二元查找树转变成排序的双向链表
- 把二元查找树转变成排序的双向链表
- 把二元查找树转变成排序的双向链表
- 微软100题(1) 二元查找树转变成排序的双向链表
- 把二元查找树转变成排序的双向链表[数据结构]
- 把二元查找树转变成排序的双向链表
- 算法1-把二元查找树转变成排序的双向链表
- 【转载】把二元查找树转变成排序的双向链表
- 二元查找树转变成排序的双向链表
- 每天一算法(把二元查找树转变成排序的双向链表 )
- 【老鸟学算法】二元查找树转变成排序的双向链表——算法思想及java实现
- 把二元查找树转变成排序的双向链表
- 1.把二元查找树转变成排序的双向链表[BST2DoubleLinkedList]
- 把二元查找树转变成排序的双向链表
- 把二元查找树转变成排序的双向链表
- 程序员面试题精选---01 把二元查找树转变成排序的双向链表