您的位置:首页 > 其它

将二叉搜索树转换成一个排序双向链表

2017-05-25 22:46 495 查看
将二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

定义:

   二叉搜索树也叫二叉查找树或二叉排序树,它可以是一颗空树,或者是满足如下性质的二叉树:若该树的左子树不为空,则左子树上所有节点的值均小于根节点的值,若该树的右子树不为空,则右子树上所有节点的值均大于根节点的值。

实现:

   二叉搜索树具有二叉树的基本性质,有两个指针分别指向它的左右孩子,在双向链表中每个节点也有两个指针分别指向该节点的前驱和后继,由于这两种数据结构具有相似的性质,题目要求将二叉搜索树转化为有序的双向链表,所以在实现转化的过程中我们可以将原来指向左子树的节点转化为前驱节点,将原来指向右子树的节点转化为指向后继的节点。

代码实现:

[cpp]
view plain
copy

print?

#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;    //根节点  
};  



#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

print?





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



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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐