Sorting an array using a Binary Search Tree in C++

空扰寡人 提交于 2021-02-11 14:11:07

问题


I'm trying to write a program that sorts integer elements of an array, using a Binary Search Tree(BST) as support data structure. The idea is that once the array is given, then it is possible to use a BST to sort his element; for example:

if my array is: {120, 30, 115, 40, 50, 100, 70}

then I build a BST like this:

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. The result would be a sorted array {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 :)


回答1:


The only thing that seems to be wrong is the 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(). 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. You really should get this code reviewed.




回答2:


So I modified quite a bit of the code. First thing to notice is I'm using Node** instead of 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). The big difference with insertIntoArray is that int i becomes int* i, that way each call to insertIntoArray can share the same incrementing index. I also added a touch of memory management.

I also need to warn you that int arr[num]; is a variable length array (VLA) and is not standard C++. std::vector is the way you should go. (in fact it makes this problem easier because you can append easily)

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


来源:https://stackoverflow.com/questions/61071783/sorting-an-array-using-a-binary-search-tree-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!