이진트리의 높이를 출력하는 프로그램을 만들어 보았는데 질문이 있어 글을 올립니다!

gol f@Google의 이미지

pool을 init하고 rand 함수를 이용해 데이터를 넣는 부분의 for문에서 반복획수가 10000을 넘어가니 굉장히 느려지고 거의 값을 출력 못하고 있는데 저의 경우 백만까지 for문을 돌리고 싶은데 어떻게 하면 좋을까요 ??

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#include <time.h>
#define M 1000000 // 백만
 
struct record {
	int num;
	struct record * left;
	struct record * right;
};
 
static struct record pool[N];
struct record * top = pool; 
 
struct record * data = NULL;
 
 
struct record * new_node()
{
	struct record *r;
 
	if (top == NULL)
		return NULL;
 
	r = top;
	top = r->right;
	return r;
}
 
void free_node(struct record *r)
{
	r->right = top;  
	top = r;
}
 
void add(int addnum)
{
	struct record* p = data;
	struct record** g = &data;
 
 
	while (p != NULL) {
		if (addnum < p->num) {
			g = &(p->left);
			p = p->left;
		}
		else {
			g = &(p->right);
			p = p->right;
		}
	}
 
	struct record* newNode = new_node();
	if (newNode == NULL) {
		printf("Can not add\n");
		return;
	}
	newNode->num = addnum;
 
 
	newNode->left = NULL;
	newNode->right = NULL;
 
	*g = newNode;
}
int height(struct record *t)
{
	if (t == NULL)
		return -1;
	else
		return (((height(t->left)>height(t->right)) ? height(t->left) : height(t->right)) + 1);
 
}
void print_height()
{
	printf("BST's height is %d.\n", height(data));
}
int main()
{
	time_t t;
	int i, j;
	srand((unsigned)time(&t)); 
 
	struct record *r = pool;
	struct record *s;
	pool[M - 1].right = NULL;
 
	for (j = 0; j < 100; j++) {
		for (i = 0; i < M; i++) {
			s = r++;
			s->right = r;
		}
 
		for (i = 0; i < M; i++) {
			add(rand());
		}
		print_height();
		free_node(data);
	}
 
}
jachin의 이미지

새로운 노드에 대한 메모리 공간을 4KB 안에서 만드느라 느립니다. malloc 함수로 메모리 저장공간을 미리 할당해주세요.

gol f@Google의 이미지

제가 잘 이해를 못해서 여기에 답글을 달아요!! 이미 pool을 선언해서 그곳에서 node의 메모리 공간을 가져와서 쓰는건데 malloc으로 어디부분의 저장공간을 마련해야되나요 ?

jachin의 이미지

밑에 분들이 답글 달아두신 거 보고 이제서야 제대로... 죄송...

익명 사용자의 이미지

height() 에서 전체 트리를 모든 노드를 탐색합니다. 이게 느려지는 원인인거 같습니다.
add() 하는 과정에서 height를 구해 따로 max height를 저장해 두는 게 좋을 거 같습니다.

jick의 이미지

(((height(t->left)>height(t->right)) ? height(t->left) : height(t->right)) + 1);

이 부분에 어마어마한 성능 문제가 숨어 있습니다.

잘 이해가 안되면 대략 높이 5 정도 되는 트리를 만든 다음에, height 함수 시작할 때 printf를 집어넣어서 각 노드를 몇 번씩 방문하나 확인해 보세요.

코드가 제대로 되어 있으면 한번씩만 방문해야 하는데 아마 안 그럴 겁니다.

gol f@Google의 이미지

정말 감사합니다!!!

익명 사용자의 이미지

height()에서 height(t->left) 또는 height(t->right)를 두번 계산하네요. 이게 가장 큰 이유입니다. 아래와 같이 변수에 값을 저장해서 사용해보세요.

int left = height(t->left);
int right = height(t->right);
return (left > right ? left : right) + 1;
gol f@Google의 이미지

정말 감사합니다 정말 큰도움이 되었어요!!

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.