AVL木の実装で困っています

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
RIKU13

AVL木の実装で困っています

#1

投稿記事 by RIKU13 » 8年前

以下のようなAVL木のコードを書いてみたのですがセグメンテーション違反が出てしまい原因が分からず困っています。
内容としては、ある数列をAVL木として挿入を行い、数列の数が50個までの場合は可視化を行っています。初心者であるため、かなり煩雑なコードになっていますが、アドバイスお願いいたします。なるべく早く返信を頂けると幸いです。
私の予想としてはinsert_nodeとrebalanceの中身でミスをしているのではないかという検討を立てています。
code=C
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#define VISION 50
#define AVL_BALANCED 0
#define AVL_LEFT 1
#define AVL_RIGHT 2

typedef struct node{
struct node *left;
struct node *right;
struct node *parent;
int element;
int balance;
}Node;

typedef struct{
Node *root;
}Tree;

static void destroy_node(Node *node)
{
if (node != NULL){
destroy_node(node->left);
destroy_node(node->right);
free(node);
}
}

void rebalance(Node *node, int direct)
{
Node *prev,*next;

if (node == NULL) return;
if ((node->balance == AVL_LEFT && direct == AVL_RIGHT)
|| (node->balance == AVL_RIGHT && direct == AVL_LEFT))
{
node->balance = AVL_BALANCED;
} else if (node->balance == AVL_BALANCED) {
node->balance = direct;
if ((prev = node->parent) != NULL)
rebalance(prev, node->element < prev->element ? AVL_LEFT : AVL_RIGHT);
} else if (node->balance == direct){
prev = node->parent;
if (node->left->balance == direct) {
next = (direct == AVL_LEFT) ? node->left : node->right;
node->parent = next;
next->parent = prev;
if (direct == AVL_LEFT) {
node->left = next->right;
next->right = node;
} else {
node->right = next->left;
next->left = node;
}
node->balance = AVL_BALANCED;
next->balance = AVL_BALANCED;
} else {
Node *dene;
if (direct == AVL_LEFT) {
dene = node->left;
next = dene->right;
} else {
dene = node->right;
next = dene->left;
}

node->parent = next;
dene->parent = next;
next->parent = prev;
if (direct == AVL_LEFT) {
node->left = next->right;
next->right = node;
dene->right = next->left;
next->left = dene;
dene->balance = (next->balance == AVL_RIGHT) ?
AVL_LEFT : AVL_BALANCED;
node->balance = (next->balance == AVL_LEFT) ?
AVL_RIGHT : AVL_BALANCED;
} else {
node->right = next->left;
next->left = node;
dene->left = next->right;
next->right = dene;
dene->balance = (next->balance == AVL_LEFT) ?
AVL_RIGHT : AVL_BALANCED;
node->balance = (next->balance == AVL_RIGHT) ?
AVL_LEFT : AVL_BALANCED;
}
next->balance = AVL_BALANCED;
}
if (prev->parent == NULL)
prev->left = prev->right = next;
else if (node->element < prev->element) prev->left = next;
else prev->right = next;
}
}
static Node *make_node(int element,Node *prev)
{
Node *node = malloc(sizeof(Node));
if (node != NULL){
node->element=element;
node->left=NULL;
node->right=NULL;
node->balance = 0;
node->parent = prev;
}
return node;
}
static Node *insert_node(int element,Node *node)
{
Node *prev = NULL;

while (node != NULL) {
if (element == node->element) return NULL;
prev = node;
if (element < node->element)
node->left = insert_node(element,node->left);
else
node->right = insert_node(element,node->right);
}
make_node(element,prev);
if (prev != NULL)
rebalance(prev, element < prev->element ? AVL_LEFT : AVL_RIGHT);
return node;

}

int depth_node(int element,Node *node)
{
int depth = 0;
while(node->element != element){
if(element < node->element){
node = node->left;
}else{
node = node->right;
}
depth++;
}
return depth;
}

int depth_tree(int element,Tree *tree)
{
return depth_node(element,tree->root);
}

Tree *make_tree(void)
{
Tree *tree = malloc(sizeof(Tree));
if (tree != NULL){
tree->root = NULL;
}
return tree;
}

void insert_tree(int elememt,Tree *tree)
{
tree->root = insert_node(elememt,tree->root);
}

void destroy_tree(Tree *tree)
{
destroy_node(tree->root);
free(tree);

}

int GetRandom(int min,int max)
{
return min + (int)(rand()*(max-min+1.0)/(1.0+RAND_MAX));
}

void shuffle(int *num,int n)
{
int s,m,tmp;
for(s = n - 1;s > 0;s--){
m = rand() % (s + 1);
tmp = num;
num = num[m];
num[m] = tmp;
}
}
int main(void)
{
int i,n,x,y,z,tree_number,*num,(*vision)[VISION],
depth,height,error,*height_tree;
double sum_height=0,sum2_height=0,real_number=0,average1,average2;

srand((unsigned int)time(NULL));

printf("!!");
fflush(0);
scanf("%d",&n);

int (*check_tree)[n];

tree_number = (int)((double)n/log2((double)n));
num = calloc(n,sizeof(int));
check_tree = calloc(tree_number * n,sizeof(int));
height_tree = calloc(n,sizeof(int));

for (i = 0;i < n;i++)
num=i+1;
for(x = 0;x < tree_number;x++){
Tree *tree =make_tree();
if(n <= VISION)
vision = calloc(VISION * VISION,sizeof(int));
height = 0;
error = 0;
shuffle(num,n);
for (i = 0;i < n;i++){
insert_tree(num,tree);
if(n <= VISION)
printf("%d ",num);
}
for(i = 0;i < n;i++){
depth=depth_tree(num,tree);
if(n <= VISION)
vision[depth][num-1]=num;
if(depth >= height)
height = depth;
check_tree[x][num-1]=depth;
}

for(y = 0;y < x;y++){
for(z = 0;z < n;z++){
if(check_tree[y][z]!=check_tree[x][z])
break;
}
if((z == n)&&(check_tree[y][z-1]==check_tree[x][z-1])){
error++;
break;
}
}
if(x != 0&&error == 1){
printf("this tree has been already created\n");
if(n <= VISION)
free(vision);
destroy_tree(tree);
continue;
}
if(n <= VISION){
printf("\n");
for(y = 0;y <= height;y++){
for(z = 0;z < n;z++){
if(vision[y][z] != 0)
printf("%2d",vision[y][z]);
else
printf(" ");
}
printf("\n");
}
printf("%d\n",height);
}
if(n <= VISION)
free(vision);
destroy_tree(tree);
height_tree[height]++;
}
for(i = 0;i < n;i++){
sum_height += (i * height_tree);
sum2_height += (i * i * height_tree);
real_number += height_tree;
}
average1 = sum_height / tree_number;
average2 = sum2_height /tree_number;

printf("%f\n%f\n",average1,average2 - average1 * average1);
free(check_tree);
free(height_tree);
return 0;
}
/code

BBB

Re: AVL木の実装で困っています

#2

投稿記事 by BBB » 8年前

困ってるのかぁ・・・
それは大変だね・・・

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: AVL木の実装で困っています

#3

投稿記事 by みけCAT » 8年前

複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

“C言語何でも質問掲示板” へ戻る