好几天没写了,这两天有点忙,身边又没电脑,最好还是坚持吧。
2017-05-25 22:43
267 查看
将二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
定义:
二叉搜索树也叫二叉查找树或二叉排序树,它可以是一颗空树,或者是满足如下性质的二叉树:若该树的左子树不为空,则左子树上所有节点的值均小于根节点的值,若该树的右子树不为空,则右子树上所有节点的值均大于根节点的值。
实现:
二叉搜索树具有二叉树的基本性质,有两个指针分别指向它的左右孩子,在双向链表中每个节点也有两个指针分别指向该节点的前驱和后继,由于这两种数据结构具有相似的性质,题目要求将二叉搜索树转化为有序的双向链表,所以在实现转化的过程中我们可以将原来指向左子树的节点转化为前驱节点,将原来指向右子树的节点转化为指向后继的节点。
代码实现:
[cpp] view
plain copy
#include <iostream>
#include <Windows.h>
#include <assert.h>
using namespace std;
template <class K>
struct SearchBinaryTreeNode
{
K _key;
SearchBinaryTreeNode<K>* _left;
SearchBinaryTreeNode<K>* _right;
SearchBinaryTreeNode(const K& key)
:_key(key)
, _left(NULL)
, _right(NULL)
{}
};
template <class K>
class SearchBinaryTree
{
typedef SearchBinaryTreeNode<K> Node;
public:
SearchBinaryTree()
:_root(NULL)
{}
~SearchBinaryTree()
{}
bool Insert(const K& key) //建树
{
if (_root == NULL)
{
_root = new Node(key);
return true; //递归出口
}
Node* parent = NULL;
Node* cur = _root;
while (cur)
{
if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else
{
return false; //不能有相同的key
}
}
if (parent->_key < key)
{
parent->_right = new Node(key);
return true;
}
if (parent->_key > key)
{
parent->_left = new Node(key);
return true;
}
}
void InOrder() //中序遍历
{
_InOrder(_root);
cout << endl;
}
//将二叉搜索树转换成一个排序的双向链表
Node* ToSortList()
{
Node* prev = NULL;
Node* head = _root;
while (head && head->_left)
{
head = head->_left;
}
_ToSortList(_root,prev);
return head;
}
protected:
void _InOrder(Node* root)
{
if (root == NULL)
{
return;
}
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
void _ToSortList(Node* cur, Node*& prev)
{
if (cur == NULL)
{
return;
}
_ToSortList(cur->_left, prev);
cur->_left = prev;
if (prev)
{
prev->_right = cur;
}
prev = cur;
_ToSortList(cur->_right, prev);
}
protected:
Node* _root; //根节点
};
[cpp] view
plain copy
#include "ToSortList.h"
void TestToSortList()
{
int arr[] = { 10, 23, 1, 4, 5, 7, 8, 10, 9 };
size_t size = sizeof(arr) / sizeof(arr[0]);
SearchBinaryTree<int> qq;
for (size_t i = 0; i < size; ++i)
{
qq.Insert(arr[i]);
}
cout << "搜索二叉树中序遍历:" << "";
qq.InOrder();
SearchBinaryTreeNode<int>* head = qq.ToSortList();
cout << "双向链表序列:" << "";
while (NULL != head)
{
cout << head->_key << " ";
head = head->_right;
}
cout << endl;
}
int main()
{
TestToSortList();
system("pause");
return 0;
}
定义:
二叉搜索树也叫二叉查找树或二叉排序树,它可以是一颗空树,或者是满足如下性质的二叉树:若该树的左子树不为空,则左子树上所有节点的值均小于根节点的值,若该树的右子树不为空,则右子树上所有节点的值均大于根节点的值。
实现:
二叉搜索树具有二叉树的基本性质,有两个指针分别指向它的左右孩子,在双向链表中每个节点也有两个指针分别指向该节点的前驱和后继,由于这两种数据结构具有相似的性质,题目要求将二叉搜索树转化为有序的双向链表,所以在实现转化的过程中我们可以将原来指向左子树的节点转化为前驱节点,将原来指向右子树的节点转化为指向后继的节点。
代码实现:
[cpp] view
plain copy
#include <iostream>
#include <Windows.h>
#include <assert.h>
using namespace std;
template <class K>
struct SearchBinaryTreeNode
{
K _key;
SearchBinaryTreeNode<K>* _left;
SearchBinaryTreeNode<K>* _right;
SearchBinaryTreeNode(const K& key)
:_key(key)
, _left(NULL)
, _right(NULL)
{}
};
template <class K>
class SearchBinaryTree
{
typedef SearchBinaryTreeNode<K> Node;
public:
SearchBinaryTree()
:_root(NULL)
{}
~SearchBinaryTree()
{}
bool Insert(const K& key) //建树
{
if (_root == NULL)
{
_root = new Node(key);
return true; //递归出口
}
Node* parent = NULL;
Node* cur = _root;
while (cur)
{
if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else
{
return false; //不能有相同的key
}
}
if (parent->_key < key)
{
parent->_right = new Node(key);
return true;
}
if (parent->_key > key)
{
parent->_left = new Node(key);
return true;
}
}
void InOrder() //中序遍历
{
_InOrder(_root);
cout << endl;
}
//将二叉搜索树转换成一个排序的双向链表
Node* ToSortList()
{
Node* prev = NULL;
Node* head = _root;
while (head && head->_left)
{
head = head->_left;
}
_ToSortList(_root,prev);
return head;
}
protected:
void _InOrder(Node* root)
{
if (root == NULL)
{
return;
}
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
void _ToSortList(Node* cur, Node*& prev)
{
if (cur == NULL)
{
return;
}
_ToSortList(cur->_left, prev);
cur->_left = prev;
if (prev)
{
prev->_right = cur;
}
prev = cur;
_ToSortList(cur->_right, prev);
}
protected:
Node* _root; //根节点
};
[cpp] view
plain copy
#include "ToSortList.h"
void TestToSortList()
{
int arr[] = { 10, 23, 1, 4, 5, 7, 8, 10, 9 };
size_t size = sizeof(arr) / sizeof(arr[0]);
SearchBinaryTree<int> qq;
for (size_t i = 0; i < size; ++i)
{
qq.Insert(arr[i]);
}
cout << "搜索二叉树中序遍历:" << "";
qq.InOrder();
SearchBinaryTreeNode<int>* head = qq.ToSortList();
cout << "双向链表序列:" << "";
while (NULL != head)
{
cout << head->_key << " ";
head = head->_right;
}
cout << endl;
}
int main()
{
TestToSortList();
system("pause");
return 0;
}
相关文章推荐
- 为什么两次调用同一函数, 输入相同, 输出却不同呢? (解决困扰自己好几天的问题, 还是有点激动哈, 奖励自己一顿丰厚的晚餐)
- 出来找工作,最好还是要有点真实的能力吧
- PHP和JAVASCRIPT判断访客终端是电脑还是手机
- 怎么查看自已WIFI被别人用电脑连接还是用手机?
- 判断Http请求由手机端发起,还是有电脑端发起
- js判断是手机端还是电脑端
- 分享我的学习方法——还是坚持+努力
- 21天战拖记——Day2:有点改变,但还是懒(2014-05-05)
- 坚持是学习的最好方法
- 玩电脑,还是被电脑玩
- 电脑貌似中毒了 学习YII 困扰两天
- php如何判断是手机访问还是电脑访问
- 逃离华强北后 他们去哪儿?採訪身边真实故事——华强北电脑维修 内迁 张家界电脑维修 电子市场电脑维修
- 怎样判断你的电脑是大端字节序存储还是小段字节序存储
- Java web 判断请求是手机还是电脑
- 无线图标不见了?但是还是可以连上网络,原来是电脑节约电源的缘故
- 笔记本电脑配置:选择独立显卡还是集成显卡
- 要走了,还是有点不舍
- 孤单还是对你最好的惩罚
- 服务器判断是手机访问网址还是电脑访问网址