下面代码的人工作正常,直到size = 100000.但是它在size = 200000之后给出了堆栈溢出错误。 我该如何解决这个问题? 有没有办法优化它?
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define SIZE 500000
// HELPER ARRAY FUNCTIONS
void check(int *arr)
{
int i = 0;
for (i = 0; i < SIZE - 1; i++)
{
if (arr[i]>arr[i + 1])
{
printf("Not sorted.\n");
return;
}
}
printf("Sorted.\n");
}
void fill_array(int *arr)
{
int i = 0;
for (i = 0; i < SIZE; i++)
arr[i] =rand()%100;
}
void print_array(int *arr)
{
int i;
for (i = 0; i < SIZE; i++)
printf("%d ", arr[i]);
printf("\n");
}
// NODE STRUCT
typedef struct BST_NODE
{
struct BST_NODE *left, *right;
int data;
}node;
// TREE FUNCTIONS
node* generate_node(int *value)
{
node *n = (node*)malloc(sizeof(node));
n->left = NULL;
n->right = NULL;
n->data = *value;
return n;
}
node* insert_node(node *n, int *value)
{
if (n == NULL)
return generate_node(value);
if (*value < n->data)
n->left = insert_node(n->left, value);
else
n->right = insert_node(n->right, value);
return n;
}
node* construct_BST(int *arr, node* n)
{
int i;
n = NULL;
for (i = 0; i < SIZE; i++)
n = insert_node(n, &arr[i]);
return n;
}
int s = 0;
void LVR(int *arr, node* n)
{
if (n != NULL)
{
LVR(arr, n->left);
arr[s] = n->data;
s++;
LVR(arr, n->right);
}
}
void tree_sort(int *arr)
{
node *root = (node*)malloc(sizeof(node));
root = construct_BST(arr, root);
LVR(arr, root);
}
// DRIVER PROGRAM
int main()
{
int *Array = (int*)malloc(sizeof(int)*SIZE);
fill_array(Array);
tree_sort(Array);
print_array(Array);
check(Array);
free(Array);
getchar();
return 0;
}
以下部分给出了错误:
node* generate_node(int *value)
{
node *n = (node*)malloc(sizeof(node));
n->left = NULL;
n->right = NULL;
n->data = *value;
return n;
}
答案 0 :(得分:1)
如果您发现堆栈溢出,则意味着您的函数调用堆栈变得太深。如果树最终不平衡,那么在构建二叉搜索树时就会发生这种情况。
最好的情况是,您的树高为O(log n)
,最差情况为O(n)
。如果您按排序顺序将项目放入树中,您的二叉树将退化为链接列表,并且您将遇到最坏的情况。
对于此特定示例,您将生成0到99之间的随机数。如果增加数字范围,则可能会获得更多随机化结果。因此,请使用rand()%100
之类的内容,而不是使用rand()%10000
。这可能有助于保持树的高度。
在不相关的说明中,您有内存泄漏。首先,为树的根分配的初始节点会被覆盖,因此您不需要它。其次,你从不打扰释放树形结构。
您可以按照以下方式处理这些问题:
void free_tree(node *root)
{
if (root) {
free_tree(root->left);
free_tree(root->right);
free(root);
}
}
void tree_sort(int *arr)
{
node *root = NULL
root = construct_BST(arr, root);
LVR(arr, root);
free_tree(root);
}
答案 1 :(得分:1)
正如其他人已经指出的那样,问题是在最坏的情况下树的深度将为SIZE
。
对于代码,由于要保留的值是小于100的值,因此可以通过不为相同值创建新节点来抑制树的深度。
如果相同的值更改计数如下。
#include <stdio.h>
#include <stdlib.h> //stdlib.h include malloc and free
#define SIZE 500000
typedef struct BST_NODE {
struct BST_NODE *left, *right;
int data;
int count;//Add for count
} node;
node* generate_node(int value){//just use int
node *n = (node*)malloc(sizeof(node));//C does not need to cast from void *.
n->right = n->left = NULL;
n->data = value;
n->count = 1;//set 1 at first time
return n;
}
node* insert_node(node *n, int value){
if(n == NULL)
return generate_node(value);
if(value < n->data)
n->left = insert_node(n->left, value);
else if (value > n->data)
n->right = insert_node(n->right, value);
else
n->count++;//Add count up
return n;
}
node* construct_BST(int *arr){//no need node *n as argument
int i;
node *n = NULL;
for (i = 0; i < SIZE; i++)
n = insert_node(n, arr[i]);
return n;
}
int s = 0;
void LVR(int *arr, node *n){
if (n != NULL){
int i;
LVR(arr, n->left);
for(i = 0; i < n->count; ++i)
arr[s++] = n->data;//Repeat as many times as count
LVR(arr, n->right);
}
}
void tree_free(node *n){
if(n){
tree_free(n->left);
tree_free(n->right);
free(n);
}
}
void tree_sort(int *arr){
node *root = construct_BST(arr);
s = 0;//Necessary for different calls
LVR(arr, root);
tree_free(root);//release tree
}