91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

二叉搜索樹與雙向鏈表——27

發布時間:2020-05-21 09:59:35 來源:網絡 閱讀:513 作者:給我個bit位 欄目:編程語言

    輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表,要求不能創建任何新的結點,只能調整樹中結點指針的指向。

二叉搜索樹與雙向鏈表——27

如上所示的二叉搜索樹,轉換成排序的雙向鏈表就是5-><-6-><-7-><-8-><-9-><-10-><-11。


    因為要求轉換成雙向鏈表,而恰好二叉樹的每個結點都有兩個指針,因此可以直接調整指針的指向;對于搜索二叉樹,每個結點的左子樹的值都比根結點的值要小,而每個右子樹的值都比當前結點的值要大,而要求轉換成排序的雙向鏈表,因此,對于每個結點的訪問順序應當是先左再中后右,也就是用中序遍歷的思路,這樣才能保證是有序的;

    對于指針的指向,可以將每個結點指向左結點的指針看做雙向鏈表中指向前一個結點的prev指針,而每個結點指向右結點的指針看做雙向鏈表中指向下一個結點的next指針;因此,對于搜索二叉樹的最左結點,其實也就是樹中的最小值,也就是雙向鏈表的頭結點,而樹的最右結點就是鏈表的尾結點也就是最大值;

    觀察可發現,對于根結點來說,其prev應該指向的是左子樹的最右結點,而next應該指向的是右子樹的最左結點,因此對于整棵樹來說,可以劃分成左右子樹來進行遞歸;


程序設計如下:

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

struct BinaryTreeNode//二叉樹結點結構體
{
    int _val;
    BinaryTreeNode *_Lnode;
    BinaryTreeNode *_Rnode;

    BinaryTreeNode(int val)//構造函數
        :_val(val)
         ,_Lnode(NULL)
         ,_Rnode(NULL)
    {}  
};

//創建二叉搜索樹,這里簡便直接使用前序遍歷的方式結構造出了二叉搜索樹
BinaryTreeNode* _Create(const int *arr, size_t& index, size_t size)
{
    if((index < size) && (arr[index] != '#'))
    {   
        BinaryTreeNode* root = new BinaryTreeNode(arr[index]);
        root->_Lnode = _Create(arr, ++index, size);
        root->_Rnode = _Create(arr, ++index, size);
        return root;
    }   
    else
        return NULL;
}

BinaryTreeNode* CreateBinaryTree(const int *arr, size_t size)
{
    assert(arr && size);

    size_t index = 0;
    return _Create(arr, index, size);
}

//銷毀轉變之后的雙向鏈表
void DestoryBinaryTree(BinaryTreeNode* ListNode)
{
    BinaryTreeNode* tmp = ListNode;
    while(ListNode != NULL)
    {
        tmp = ListNode;
        ListNode = ListNode->_Lnode;
        delete tmp;
    }
}

//前序遍歷檢驗二叉樹
void PrevOrder(BinaryTreeNode *root)
{
    if(root != NULL)
    {
        cout<<root->_val<<" ";
        PrevOrder(root->_Lnode);
        PrevOrder(root->_Rnode);
    }
}

//二叉搜索樹轉換為雙向鏈表
void BSTToList(BinaryTreeNode* root, BinaryTreeNode** lastnode)
{
    if(root != NULL)
    {
        BSTToList(root->_Lnode, lastnode);
        root->_Lnode = *lastnode;//如果左結點為空,則當前結點的前指針指向當前鏈表的最后一個結點

        if(*lastnode != NULL)
            (*lastnode)->_Rnode = root;//將當前鏈表的最后一個結點的next指針設置為當前結點

        *lastnode = root;//將鏈表的最后一個結點更新為當前結點
        BSTToList(root->_Rnode, lastnode);//繼續遍歷右子樹直至為空
    }
}

void PrintList(BinaryTreeNode* ListNode)
{
    assert(ListNode);

    BinaryTreeNode* tmp = ListNode;
    cout<<"ListHead:"<<tmp->_val<<endl;
    cout<<"正向打印鏈表:";
    while(tmp->_Rnode != NULL)//每個結點的右指針指向下一個結點
    {
        cout<<tmp->_val<<"->";
        tmp = tmp->_Rnode;
    }
    cout<<tmp->_val<<"->NULL"<<endl;

    cout<<"ListTail:"<<tmp->_val<<endl;
    cout<<"逆向打印鏈表:";
    while(tmp->_Lnode != NULL)//每個結點的左指針指向前一個結點
    {
        cout<<tmp->_val<<"->";
        tmp = tmp->_Lnode;
    }
    cout<<tmp->_val<<"->NULL"<<endl;
}

int main()
{
    int arr[] = {8,6,5,'#','#',7,'#','#',10,9,'#','#',11,'#','#'};

    BinaryTreeNode* root = CreateBinaryTree(arr, sizeof(arr)/sizeof(arr[0]));
    cout<<"PrevOrder: ";
    PrevOrder(root);
    cout<<endl;

    BinaryTreeNode* lastnode = NULL;
    BSTToList(root, &lastnode);

    BinaryTreeNode* ListNode = root;
    while(ListNode->_Lnode != NULL)//獲取鏈表的頭結點
        ListNode = ListNode->_Lnode;

    PrintList(ListNode);

    DestoryBinaryTree(ListNode);
    return 0;
}


運行程序:

二叉搜索樹與雙向鏈表——27



《完》

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

松溪县| 鹿泉市| 石景山区| 丽江市| 辉南县| 澄城县| 盖州市| 丰镇市| 科尔| 彰化县| 千阳县| 亚东县| 富顺县| 阳信县| 蛟河市| 南江县| 临泉县| 临潭县| 渝北区| 鄂尔多斯市| 綦江县| 额敏县| 门头沟区| 正阳县| 和平县| 富宁县| 玉屏| 收藏| 杨浦区| 海林市| 应城市| 荆州市| 辽源市| 离岛区| 沐川县| 秭归县| 明水县| 榆林市| 昌邑市| 获嘉县| 龙胜|