简体   繁体   English

在 C++ 中使用二叉搜索树对数组进行排序

[英]Sorting an array using a Binary Search Tree in C++

I'm trying to write a program that sorts integer elements of an array, using a Binary Search Tree(BST) as support data structure.我正在尝试编写一个程序,使用二叉搜索树(BST)作为支持数据结构,对数组的 integer 元素进行排序。 The idea is that once the array is given, then it is possible to use a BST to sort his element;这个想法是,一旦给定数组,就可以使用 BST 对其元素进行排序; for example:例如:

if my array is: {120, 30, 115, 40, 50, 100, 70}如果我的数组是:{120, 30, 115, 40, 50, 100, 70}

then I build a BST like this:然后我建立一个像这样的BST:

BST

Once I have this BST, I can do an inorder tree traversal to touch every node in order, from the lowest to the highest element and modify the array.一旦有了这个 BST,我就可以进行中序树遍历,从最低到最高元素按顺序触摸每个节点并修改数组。 The result would be a sorted array {30, 40, 50, 70, 100, 115, 120}结果将是一个排序数组 {30, 40, 50, 70, 100, 115, 120}

I wrote this code and I don't understand where is the error I made.我写了这段代码,但我不明白我犯的错误在哪里。 It compiles without any error, but obviously there is something wrong with it:它编译没有任何错误,但显然它有问题:

#include<iostream>
using namespace std;

struct Node
{
    int label;
    Node* left;
    Node* right;
};


void insertSearchNode(Node* &tree, int x)       //insert integer x into the BST
{
    if(!tree){
        tree = new Node;
        tree->label = x;
        tree->right = NULL;
        tree->left = NULL;
        return;
    }
    if(x < tree->label) insertSearchNode(tree->left, x);
    if(x > tree->label) insertSearchNode(tree->right, x);
    return;
}

void insertArrayTree(int arr[], int n, Node* &tree)     //insert the array integer into the nodes label of BST
{
    for(int i=0; i<n; i++){
        insertSearchNode(tree, arr[i]);
    }
    return;
}

int insertIntoArray(int arr[], Node* &tree, int i)      //insert into the array the node label touched during an inorder tree traversal
{
    i=0;
    if(!tree) return 0;
    i += insertIntoArray(arr, tree->left, i) +1;
    arr[i] = tree->label;
    i += insertIntoArray(arr, tree->right, i) +1;
    return i;

}

int main()
{
    Node* maintree;
    maintree = NULL;
    int num;
    cin>>num;
    int arr[num];
    for(int i=0; i<num; i++){    //initialize array with num-elements
     cin>>arr[i];
    }
    insertArrayTree(arr, num, maintree);    //insert elements into BST
    int index;
    insertIntoArray(arr, maintree, index);  //modify array sorting his elements using the BST

    for(int y=0; y<num; y++) cout<< arr[y] << ' ';

    return 0;
}

I hope that my question is clear enough.我希望我的问题足够清楚。 Any help/advice would be appreciated!任何帮助/建议将不胜感激!

Thanks:)谢谢:)

The only thing that seems to be wrong is the insertIntoArray() .唯一似乎错误的是insertIntoArray()

The first issue is that you are passing an unitialized variable as a parameter:第一个问题是您将单元化变量作为参数传递:

int index;
insertIntoArray(arr, maintree, index);

Why.为什么。 You are starting to fill the array at zero so pass zero (and get rid of the index variable).您开始在零处填充数组,因此传递零(并摆脱索引变量)。

insertIntoArray(arr, maintree, 0);

I could not quite decipher your version of insertIntoArray() .我无法完全破译您的insertIntoArray()版本。 But this version seems to work.但这个版本似乎工作。

int insertIntoArray(int arr[], Node* tree, int i)
{
    // If you fall of a leaf then there is nothing to do.
    // So simply return the index as it has not changed.
    if (!tree) {
        return i;
    }


    // Since it is a BST we always go left first.
    // The return value is where we have reached when we
    // have inserted all the left values. 
    i = insertIntoArray(arr, tree->left, i);

    // Now put the current value in and increment the index position.
    arr[i] = tree->label;
    ++i;

    // Now do the right sub-tree.
    i = insertIntoArray(arr, tree->right, i);

    // Return the point index we have reached so far.
    return i;
}

OK.好的。 So it should work.所以它应该工作。 BUT that does not mean this is all good C++ code.但这并不意味着这都是很好的C++代码。 You really should get this code reviewed.你真的应该审查这段代码。

So I modified quite a bit of the code.所以我修改了相当多的代码。 First thing to notice is I'm using Node** instead of Node* & .首先要注意的是我使用的是Node**而不是Node* & This is a pretty common idiom when dealing with trees and traversal algorithms.在处理树和遍历算法时,这是一个非常常见的习惯用法。 Reason being is you need to be able to modify the pointer being passed in (I take it this is why you used Node* & , you could also do it that way).原因是您需要能够修改传入的指针(我认为这就是您使用Node* &的原因,您也可以这样做)。 The big difference with insertIntoArray is that int i becomes int* i , that way each call to insertIntoArray can share the same incrementing index.insertIntoArray的最大区别在于int i变为int* i ,这样每次调用insertIntoArray都可以共享相同的递增索引。 I also added a touch of memory management.我还添加了一点 memory 管理。

I also need to warn you that int arr[num];我还需要警告你int arr[num]; is a variable length array (VLA) and is not standard C++.是可变长度数组 (VLA),不是标准的 C++。 std::vector is the way you should go. std::vector是你应该 go 的方式。 (in fact it makes this problem easier because you can append easily) (事实上它使这个问题更容易,因为你可以很容易地 append)

#include <iostream>

using namespace std;

struct Node
{
    int label;
    Node* left;
    Node* right;

    ~Node() {
      delete left;
      delete right;
    }
};

void insertSearchNode(Node** tree, int x)       //insert integer x into the BST
{
    if (*tree) {
        if (x < (*tree)->label)
            insertSearchNode(&(*tree)->left, x);
        else
            insertSearchNode(&(*tree)->right, x);
    } else {
        *tree = new Node;
        (*tree)->label = x;
        (*tree)->right = NULL;
        (*tree)->left = NULL;
    }
}

void insertArrayTree(int arr[], int n, Node** tree)     //insert the array integer into the nodes label of BST
{
    for (int i = 0; i < n; i++)
        insertSearchNode(tree, arr[i]);
}

void insertIntoArray(int arr[], Node** tree, int* i)      //insert into the array the node label touched during an inorder tree traversal
{
    if (*tree) {
        if ((*tree)->left) insertIntoArray(arr, &(*tree)->left, i);
        arr[(*i)++] = (*tree)->label;
        if ((*tree)->right) insertIntoArray(arr, &(*tree)->right, i);
    }
}

int main()
{
    Node* maintree = NULL;

    int num;
    cin >> num;

    int arr[num];

    for (int i = 0; i < num; i++)    //initialize array with num-elements
        cin >> arr[i];

    insertArrayTree(arr, num, &maintree);    //insert elements into BST
    int index = 0;
    insertIntoArray(arr, &maintree, &index);  //modify array sorting his elements using the BST

    delete maintree;

    for (int y = 0; y < num; y++) 
        cout << arr[y] << ' ';
    cout << '\n';
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM