<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>저장소</title>
    <link>https://ggashu.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 7 Jun 2026 20:39:37 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>까슈</managingEditor>
    <item>
      <title>오찌는 도찌입니까?</title>
      <link>https://ggashu.tistory.com/9</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;오찌는 도찌인가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 이것에 대해 의문을 가져야 할 필요는 없고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 외우면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오찌는 도찌이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오찌도찌&lt;/p&gt;</description>
      <category>일기장</category>
      <category>오찌도찌</category>
      <author>까슈</author>
      <guid isPermaLink="true">https://ggashu.tistory.com/9</guid>
      <comments>https://ggashu.tistory.com/9#entry9comment</comments>
      <pubDate>Fri, 2 Aug 2024 14:53:00 +0900</pubDate>
    </item>
    <item>
      <title>오찌도찌</title>
      <link>https://ggashu.tistory.com/8</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;오찌기 도찌기 옷도로 돗돗찌&lt;/p&gt;</description>
      <category>일기장</category>
      <category>오찌도찌</category>
      <author>까슈</author>
      <guid isPermaLink="true">https://ggashu.tistory.com/8</guid>
      <comments>https://ggashu.tistory.com/8#entry8comment</comments>
      <pubDate>Thu, 20 Apr 2023 15:43:59 +0900</pubDate>
    </item>
    <item>
      <title>[C]이중연결리스트를 사용한 전화번호부 - 03</title>
      <link>https://ggashu.tistory.com/6</link>
      <description>&lt;p&gt;3. 이어서 함수 설명&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;[ findNode / printNode ]&lt;/p&gt;
&lt;pre class=&quot;brush:java&quot;&gt;void findNode(linkedList *L){
	node *f = L-&amp;gt;head;
	int i, num;

	printf(&quot;찾을 노드 번호를 입력하세요 : &quot;);
	scanf(&quot; %d&quot;, &amp;amp;num);

	if (L-&amp;gt;cnt &amp;lt;= 0) {
		printf(&quot;리스트가 비었음.\n&quot;);
		returnMain(L);
	}
	else if (num &amp;gt; L-&amp;gt;cnt) {
		printf(&quot;검색 위치가 리스트의 길이보다 김.\n&quot;);
		returnMain(L);
	}
	else {
		for (i = 1; i &amp;lt; num; i++)
			f = f-&amp;gt;next;
		printf(&quot;%d 번째 노드의 값 - 이름 : %s 전화번호 : %d\n&quot;, num, f-&amp;gt;name, f-&amp;gt;phone);
		returnMain(L);
	}
}

void printNode(linkedList *L){
	node *f = L-&amp;gt;head;

	printf(&quot;리스트\n&quot;);
	while (f != NULL) {
		printf(&quot;이름 : %s 전화번호 : %d\n&quot;, f-&amp;gt;name, f-&amp;gt;phone);
		f = f-&amp;gt;next;
	}
	printf(&quot;\n노드 수 : %d\n&quot;, L-&amp;gt;cnt);
	returnMain(L);
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;- findNode에서도 삽입과 삭제할 때의 경우와 같이 원하는 위치로 찾아가야 한다.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;더미노드 f 를 만들고 반복문으로 찾아간 후, 그 값을 출력한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;- printNode에서는 모든 노드를 한번씩 찾아가서 값을 출력해야 하기 때문에, 리스트의 테일까지 찾아간다.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;테일까지 찾아가면서 노드의 값들을 출력한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;4. 전체 소스 코드&lt;/p&gt;
&lt;pre class=&quot;brush:java&quot;&gt;/*
	Phone Book (use Doubly Linked List)
	Coder : GGaShu LSW
	Date : 2018.03.30
	Purpose : 이중연결리스트의 활용
*/

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

typedef struct _Node {
	struct _Node *prev;
	struct _Node *next;
	int no;
	char name[20];
	int phone;
}node;

typedef struct _linkedList {
	struct _Node *head;
	struct _Node *tail;
	int cnt;
}linkedList;

void printMain(linkedList *L);	// 메인 메뉴 출력
void returnMain(linkedList *L);	// 메인으로 돌아옴
void inputMenu(linkedList *L);	// 메뉴 선택
void inputData(linkedList *L);	// 데이터 입력

void Init(linkedList *L);	// 리스트 초기화
void createNode(linkedList *L, char *ndata, int pdata, int num);	// 노드 생성
void createLastNode(linkedList *L, char *ndata, int pdata);	// 안씀
void deleteNode(linkedList *L);	// 노드 삭제
void deleteLastNode(linkedList *L);	// 안씀
void findNode(linkedList *L);	// 노드 검색
void printNode(linkedList *L);	// 리스트 출력

void main() {
	linkedList *L = (linkedList *)malloc(sizeof(linkedList));
	Init(L);
	printMain(L);
}

void printMain(linkedList *L) {
	printf(&quot;1. 리스트\n&quot;);
	printf(&quot;2. 검  색\n&quot;);
	printf(&quot;3. 삽  입\n&quot;);
	printf(&quot;4. 삭  제\n&quot;);
	printf(&quot;5. 종  료\n&quot;);
	printf(&quot;메뉴를 골라주세요 : &quot;);
	inputMenu(L);
}

void returnMain(linkedList *L) {
	char c;
	printf(&quot;메인으로(Y/y) 종료(N/n) : &quot;);
	
	// scanf 그냥 통과되는 문제 (버퍼를 비우자)
	// 이상하게 fflush(stdin)이 안먹혀서 한칸을 비우고 스캔하는 방법을 사용.
	scanf(&quot; %c&quot;, &amp;amp;c);

	if (c == 'Y' || c == 'y') {
		system(&quot;cls&quot;);
		printMain(L);
	}
	else if (c == 'N' || c == 'n')
		exit(1);
	else {
		printf(&quot;잘못 누름. 다시 입력 : &quot;);
		returnMain(L);
	}
}

void inputMenu(linkedList *L) {
	int num = 0;

	scanf(&quot;%d&quot;, &amp;amp;num);

	if (num &amp;gt; 5 || num &amp;lt; 1) {
		printf(&quot;1부터 5까지 중에서 고르세요 : &quot;);
		num = 0;
		scanf(&quot; %d&quot;, &amp;amp;num);
	}
	else {
		switch (num) {
		case 1:
			printNode(L);
			break;
		case 2:			
			findNode(L);
			break;
		case 3:
			inputData(L);
			break;
		case 4:
			deleteNode(L);
			break;
		case 5:
			exit(1);
		}
	}
}

void inputData(linkedList *L) {
	char name[20];
	int phone, num;

	printf(&quot;순번 이름 전화번호 순으로 입력하세요 : &quot;);
	scanf(&quot; %d %s %d&quot;, &amp;amp;num, name, &amp;amp;phone);
	
	createNode(L, name, phone, num);
}

void Init(linkedList *L) {
	L-&amp;gt;head = NULL;
	L-&amp;gt;tail = NULL;
	L-&amp;gt;cnt = 0;
}

void createNode(linkedList *L, char *ndata, int pdata, int num) {
	node *f = L-&amp;gt;head;
	node *newNode = (node *)malloc(sizeof(node));
	
	newNode-&amp;gt;no = num;
	strcpy(newNode-&amp;gt;name, ndata);
	newNode-&amp;gt;phone = pdata;
	
	int i;

	if (num &amp;lt;= 0) {
		printf(&quot;삽입 위치가 리스트의 길이보다 짧음.\n&quot;);
		exit(1);
	}
	else if (num == 1) {
		if (L-&amp;gt;head == NULL &amp;amp;&amp;amp; L-&amp;gt;tail == NULL) {
			printf(&quot;헤드\n&quot;);
			L-&amp;gt;head = newNode;
			L-&amp;gt;tail = newNode;
			newNode-&amp;gt;next = NULL;

			printf(&quot;이름 : %s 전화번호 : %d\n&quot;, newNode-&amp;gt;name, newNode-&amp;gt;phone);
			L-&amp;gt;cnt++;

			returnMain(L);
		}
		else {
			printf(&quot;헤드뺏기2\n&quot;);
			newNode-&amp;gt;next = L-&amp;gt;head;
			L-&amp;gt;head = newNode;
			L-&amp;gt;head-&amp;gt;next-&amp;gt;prev = newNode;
			newNode-&amp;gt;prev = L-&amp;gt;head;

			printf(&quot;이름 : %s 전화번호 : %d\n&quot;, newNode-&amp;gt;name, newNode-&amp;gt;phone);
			L-&amp;gt;cnt++;

			returnMain(L);
		}
	}
	else if (num == (L-&amp;gt;cnt) + 1) {
		printf(&quot;테일\n&quot;);
		newNode-&amp;gt;prev = L-&amp;gt;tail;
		L-&amp;gt;tail-&amp;gt;next = newNode;
		L-&amp;gt;tail = newNode;
		newNode-&amp;gt;next = NULL;

		printf(&quot;이름 : %s 전화번호 : %d\n&quot;, newNode-&amp;gt;name, newNode-&amp;gt;phone);
		L-&amp;gt;cnt++;

		returnMain(L);
	}
	else {
		if (num &amp;gt; (L-&amp;gt;cnt) + 2) {
			printf(&quot;삽입 위치가 리스트의 길이보다 길다\n&quot;);
			exit(1);
		}
		else {
			for (i = 1; i &amp;lt; num - 1; i++)
				f = f-&amp;gt;next;
		}

		newNode-&amp;gt;next = f-&amp;gt;next;
		f-&amp;gt;next-&amp;gt;prev = newNode;
		newNode-&amp;gt;prev = f;
		f-&amp;gt;next = newNode;

		printf(&quot;이름 : %s 전화번호 : %d\n&quot;, newNode-&amp;gt;name, newNode-&amp;gt;phone);
		L-&amp;gt;cnt++;

		returnMain(L);
	}
}

void createLastNode(linkedList *L, char *ndata, int pdata){
	// 일단 사용 안함
}

void deleteNode(linkedList *L){
	node *f = L-&amp;gt;head;
	int i, num;

	printf(&quot;삭제할 노드 번호를 입력하세요 : &quot;);
	scanf(&quot; %d&quot;, &amp;amp;num);

	if (num &amp;lt;= 0) {
		printf(&quot;삭제 위치가 리스트의 길이보다 짧다\n&quot;);
		deleteNode(L);
	}
	else if (num == 1) {
		L-&amp;gt;head = L-&amp;gt;head-&amp;gt;next;
		
		printf(&quot;%d 번째 노드 삭제 완료\n&quot;, num);
		L-&amp;gt;cnt--;

		returnMain(L);
	}
	else if (num == L-&amp;gt;cnt) {
		L-&amp;gt;tail = L-&amp;gt;tail-&amp;gt;prev;
		L-&amp;gt;tail-&amp;gt;next = NULL;
		
		printf(&quot;%d 번째 노드 삭제 완료\n&quot;, num);
		L-&amp;gt;cnt--;

		returnMain(L);
	}
	else {
		if (num &amp;gt; (L-&amp;gt;cnt) + 1) {
			printf(&quot;삭제 위치가 리스트의 길이보다 길다\n&quot;);
			deleteNode(L);
		}
		else {
			for (i = 1; i &amp;lt; num; i++)
				f = f-&amp;gt;next;
		}

		f-&amp;gt;prev-&amp;gt;next = f-&amp;gt;next;
		f-&amp;gt;next-&amp;gt;prev = f-&amp;gt;prev;

		printf(&quot;%d 번째 노드 삭제 완료\n&quot;, num);
		L-&amp;gt;cnt--;

		returnMain(L);
	}
}

void deleteLastNode(linkedList *L){
	// 일단 사용 안함.
}

void findNode(linkedList *L){
	node *f = L-&amp;gt;head;
	int i, num;

	printf(&quot;찾을 노드 번호를 입력하세요 : &quot;);
	scanf(&quot; %d&quot;, &amp;amp;num);

	if (L-&amp;gt;cnt &amp;lt;= 0) {
		printf(&quot;리스트가 비었음.\n&quot;);
		returnMain(L);
	}
	else if (num &amp;gt; L-&amp;gt;cnt) {
		printf(&quot;검색 위치가 리스트의 길이보다 김.\n&quot;);
		returnMain(L);
	}
	else {
		for (i = 1; i &amp;lt; num; i++)
			f = f-&amp;gt;next;
		printf(&quot;%d 번째 노드의 값 - 이름 : %s 전화번호 : %d\n&quot;, num, f-&amp;gt;name, f-&amp;gt;phone);
		returnMain(L);
	}
}

void printNode(linkedList *L){
	node *f = L-&amp;gt;head;

	printf(&quot;리스트\n&quot;);
	while (f != NULL) {
		printf(&quot;이름 : %s 전화번호 : %d\n&quot;, f-&amp;gt;name, f-&amp;gt;phone);
		f = f-&amp;gt;next;
	}
	printf(&quot;\n노드 수 : %d\n&quot;, L-&amp;gt;cnt);
	returnMain(L);
}
&lt;/string.h&gt;&lt;/stdlib.h&gt;&lt;/stdio.h&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;5. 마치며&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;블로그에 글을 정말 오랬만에 쓴다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;자료구조나 다시 공부해볼 겸 프로그램을 짜고 나서, 갑자기 블로그가 있다는 사실이 생각나 올리게 되었다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;나도 아직 프로그래밍에 미숙하여 많이 공부중이지만 이 포스트가 다른 사람들에게 도움이 되었으면 좋겠다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;끝!&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;이 아니라 포스팅을 언제 또 다시 할지는 미정...&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;진짜 끝!&lt;/p&gt;</description>
      <category>개발/C</category>
      <author>까슈</author>
      <guid isPermaLink="true">https://ggashu.tistory.com/6</guid>
      <comments>https://ggashu.tistory.com/6#entry6comment</comments>
      <pubDate>Fri, 30 Mar 2018 14:54:59 +0900</pubDate>
    </item>
    <item>
      <title>[C]이중연결리스트를 사용한 전화번호부 - 02</title>
      <link>https://ggashu.tistory.com/5</link>
      <description>&lt;p&gt;3. 이어서 함수 설명&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;[ Init ]&lt;/p&gt;
&lt;pre class=&quot;brush:java&quot;&gt;void Init(linkedList *L) {
	L-&amp;gt;head = NULL;
	L-&amp;gt;tail = NULL;
	L-&amp;gt;cnt = 0;
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;- 리스트를 초기화 한다. 아직 아무런 값이 들어있지 않기 때문에 헤드와 테일을 각각 NULL로 초기화 하고, 카운트 값인 cnt는 0으로 초기화 한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;[ createNode ]&lt;/p&gt;
&lt;pre class=&quot;brush:java&quot;&gt;void createNode(linkedList *L, char *ndata, int pdata, int num) {
	node *f = L-&amp;gt;head;
	node *newNode = (node *)malloc(sizeof(node));
	
	newNode-&amp;gt;no = num;
	strcpy(newNode-&amp;gt;name, ndata);
	newNode-&amp;gt;phone = pdata;
	
	int i;

	if (num &amp;lt;= 0) {
		printf(&quot;삽입 위치가 리스트의 길이보다 짧음.\n&quot;);
		exit(1);
	}
	else if (num == 1) {
		if (L-&amp;gt;head == NULL &amp;amp;&amp;amp; L-&amp;gt;tail == NULL) {
			printf(&quot;헤드\n&quot;);
			L-&amp;gt;head = newNode;
			L-&amp;gt;tail = newNode;
			newNode-&amp;gt;next = NULL;

			printf(&quot;이름 : %s 전화번호 : %d\n&quot;, newNode-&amp;gt;name, newNode-&amp;gt;phone);
			L-&amp;gt;cnt++;

			returnMain(L);
		}
		else {
			printf(&quot;헤드뺏기2\n&quot;);
			newNode-&amp;gt;next = L-&amp;gt;head;
			L-&amp;gt;head = newNode;
			L-&amp;gt;head-&amp;gt;next-&amp;gt;prev = newNode;
			newNode-&amp;gt;prev = L-&amp;gt;head;

			printf(&quot;이름 : %s 전화번호 : %d\n&quot;, newNode-&amp;gt;name, newNode-&amp;gt;phone);
			L-&amp;gt;cnt++;

			returnMain(L);
		}
	}
	else if (num == (L-&amp;gt;cnt) + 1) {
		printf(&quot;테일\n&quot;);
		newNode-&amp;gt;prev = L-&amp;gt;tail;
		L-&amp;gt;tail-&amp;gt;next = newNode;
		L-&amp;gt;tail = newNode;
		newNode-&amp;gt;next = NULL;

		printf(&quot;이름 : %s 전화번호 : %d\n&quot;, newNode-&amp;gt;name, newNode-&amp;gt;phone);
		L-&amp;gt;cnt++;

		returnMain(L);
	}
	else {
		if (num &amp;gt; (L-&amp;gt;cnt) + 2) {
			printf(&quot;삽입 위치가 리스트의 길이보다 길다\n&quot;);
			exit(1);
		}
		else {
			for (i = 1; i &amp;lt; num - 1; i++)
				f = f-&amp;gt;next;
		}

		newNode-&amp;gt;next = f-&amp;gt;next;
		f-&amp;gt;next-&amp;gt;prev = newNode;
		newNode-&amp;gt;prev = f;
		f-&amp;gt;next = newNode;

		printf(&quot;이름 : %s 전화번호 : %d\n&quot;, newNode-&amp;gt;name, newNode-&amp;gt;phone);
		L-&amp;gt;cnt++;

		returnMain(L);
	}
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;- 함수에 사용되는 인자값으로 리스트 L과 이름 데이터 ndata, 핸드폰 번호 데이터 pdata, 노드위치 데이터인 num을 사용한다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;- 이름에 데이터를 넣을 때, strcpy를 사용하는 이유는 name변수가 배열로 선언되어 있기 때문에, 바로 넣을 수 없기 때문.&lt;/p&gt;&lt;p&gt;&amp;nbsp;- 노드를 삽입하고 나면 cnt변수를 하나씩 증가시켜준다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;-&amp;nbsp;else if (num == 1) 부분&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;-- 첫번째 노드로 삽입하고 싶을 때의 조건문이다.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;-- 조건문 두개로 나뉘어져 있는데&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; [[ L-&amp;gt;head == NULL &amp;amp;&amp;amp; L-&amp;gt;tail == NULL ]] 리스트에 아무것도 없고 처음 삽입할 경우이다.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 헤드와 테일을 전부 새로 만든 노드로 지정해주고, 새 노드의 next에 NULL을 넣어준다. 다음 노드가 없기 때문.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;-- 아래 else 부분은 리스트에 노드들이 들어 있는데, 첫 노드로 끼워넣고 싶을 때 사용된다.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 헤드의 앞에 넣어야 되기 때문에, 새 노드의 next에 헤드를 넣고, 헤드를 새 노드로 바꾼다.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; L-&amp;gt;head-&amp;gt;next 즉 원래 있던 헤드의 다음 노드의 prev에 새 노드를 넣는다.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 마지막으로 새 노드의 prev에 헤드를 넣어준다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;-&amp;nbsp;else if (num == (L-&amp;gt;cnt) + 1) 부분&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;-- 마지막 노드로 십입하고 싶을 때의 조건문이다.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;-- 새 노드의 prev에 테일을 넣어주고, 원래 테일의 next에 새 노드를 넣는다.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;그리고 테일을 새 노드로 바꿔준다. 새 노드의 next엔 NULL을 넣는다. 테일이 리스트의 맨 끝이기 때문.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;리스트의 연결 부분을 말로 하나씩 설명하려니 너무 어렵네.. 이후로는 리스트설명 안합니다!!&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 잘 이해가 안가시면 그림을 직접 그려보세요!! 아니면 다른 블로그 구글링 ㄱㄱ!!&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;- else 부분&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;-- 헤드와 테일 이외의 노드를 삽입할 때이다.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;-- 넣을 위치를 먼저 찾아가야 하기 때문에, 더미 역할을 할 노드인 f를 선언하면서 리스트의 첫 위치인 헤드로 초기화 해준다.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;-- for (i = 1; i &amp;lt; num - 1; i++) f = f-&amp;gt;next;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 원하는 위치까지 찾아가는 반복문이다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;[ deleteNode&amp;nbsp;]&lt;/p&gt;
&lt;pre class=&quot;brush:java&quot;&gt;void deleteNode(linkedList *L){
	node *f = L-&amp;gt;head;
	int i, num;

	printf(&quot;삭제할 노드 번호를 입력하세요 : &quot;);
	scanf(&quot; %d&quot;, &amp;amp;num);

	if (num &amp;lt;= 0) {
		printf(&quot;삭제 위치가 리스트의 길이보다 짧다\n&quot;);
		deleteNode(L);
	}
	else if (num == 1) {
		L-&amp;gt;head = L-&amp;gt;head-&amp;gt;next;
		
		printf(&quot;%d 번째 노드 삭제 완료\n&quot;, num);
		L-&amp;gt;cnt--;

		returnMain(L);
	}
	else if (num == L-&amp;gt;cnt) {
		L-&amp;gt;tail = L-&amp;gt;tail-&amp;gt;prev;
		L-&amp;gt;tail-&amp;gt;next = NULL;
		
		printf(&quot;%d 번째 노드 삭제 완료\n&quot;, num);
		L-&amp;gt;cnt--;

		returnMain(L);
	}
	else {
		if (num &amp;gt; (L-&amp;gt;cnt) + 1) {
			printf(&quot;삭제 위치가 리스트의 길이보다 길다\n&quot;);
			deleteNode(L);
		}
		else {
			for (i = 1; i &amp;lt; num; i++)
				f = f-&amp;gt;next;
		}

		f-&amp;gt;prev-&amp;gt;next = f-&amp;gt;next;
		f-&amp;gt;next-&amp;gt;prev = f-&amp;gt;prev;

		printf(&quot;%d 번째 노드 삭제 완료\n&quot;, num);
		L-&amp;gt;cnt--;

		returnMain(L);
	}
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;- 삭제할 노드의 순번을 사용자에게 입력받기 때문에 함수 자체의 인자값은 리스트 L 하나만 들어간다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;- 노드를 삭제할 때 마다 cnt 값을 1씩 감소시킨다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;-&amp;nbsp;else if (num == 1) 부분&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;-- 첫번째 노드를 삭제할 때의 조건문.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;-- 헤드를 날려버리기만 하면 되기 때문에 간단하다. 헤드를 다음노드로 변경해준다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;- else if (num == L-&amp;gt;cnt) 부분&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;-- 마지막 노드를 삭제할 때의 조건문.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;-- 첫 노드와 마찬가지로 테일만 날려버리면 된다. 테일을 이전노드로 변경해주고, 테일의 다음값을 널로 설정한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;-&amp;nbsp;else 부분&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;-- 노드를 삽입할 때와 마찬가지로 더미노드 f를 만들어주고, 삭제할 위치까지 찾아간다.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;-- 찾은 노드의 이전 노드와 다음 노드를 이어준다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;다음 글에서 검색과 출력함수 설명하겠음&lt;/p&gt;</description>
      <category>개발/C</category>
      <author>까슈</author>
      <guid isPermaLink="true">https://ggashu.tistory.com/5</guid>
      <comments>https://ggashu.tistory.com/5#entry5comment</comments>
      <pubDate>Fri, 30 Mar 2018 14:44:36 +0900</pubDate>
    </item>
    <item>
      <title>[C]이중연결리스트를 사용한 전화번호부 - 01</title>
      <link>https://ggashu.tistory.com/4</link>
      <description>&lt;p&gt;자료구조를 다시 공부할 겸 해서 이중연결리스트로 간단한 전화번호부를 만들어 보았다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;대충 만든거라 예상치 못한 에러가 있을 수 있음..&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그래도 나름 웬만한 에러는 다 잡았다고 생각함&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;또한 내가 보려고 올리는거라 설명이 좀 부족할 수 있음&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;전체 코드는 마지막에 한꺼번에 올리도록 하겠음&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;1. 연결리스트를 위한 구조체 생성하기&lt;/p&gt;
&lt;pre class=&quot;brush:java&quot;&gt;typedef struct _Node {
	struct _Node *prev;
	struct _Node *next;
	int no;
	char name[20];
	int phone;
}node;

typedef struct _linkedList {
	struct _Node *head;
	struct _Node *tail;
	int cnt;
}linkedList;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;- 리스트에 들어갈 각 노드를 위한 구조체에는 이중연결리스트를 사용할 것이므로 앞 노드와 뒤 노드의 주소를 저장하는 변수를 생성함.&lt;/p&gt;&lt;p&gt;&amp;nbsp;- 전화번호부에 들어갈 사용자 번호와 이름, 전화번호용 변수를 생성함. 근데 코딩하다보니 딱히 사용자 번호를 쓸 일이 없어서 안씀..&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;- 리스트용 구조체에는 리스트의 헤드와 테일을 저장하는 변수, 리스트의 총 갯수를 파악하기위한 cnt변수를 생성함.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;2. 프로그램에서 사용할 함수 정의&lt;/p&gt;
&lt;pre class=&quot;brush:java&quot;&gt;void printMain(linkedList *L);	// 메인 메뉴 출력
void returnMain(linkedList *L);	// 메인으로 돌아옴
void inputMenu(linkedList *L);	// 메뉴 선택
void inputData(linkedList *L);	// 데이터 입력

void Init(linkedList *L);	// 리스트 초기화
void createNode(linkedList *L, char *ndata, int pdata, int num);	// 노드 생성
void createLastNode(linkedList *L, char *ndata, int pdata);	// 안씀
void deleteNode(linkedList *L);	// 노드 삭제
void deleteLastNode(linkedList *L);	// 안씀
void findNode(linkedList *L);	// 노드 검색
void printNode(linkedList *L);	// 리스트 출력
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;- 프로그램에 사용되는 함수를 미리 정의. 각 내용들은 아래에 설명하겠음.&lt;/p&gt;&lt;p&gt;&amp;nbsp;- LastNode함수는 단일연결리스트 테스트할때 쓰던 코드를 좀 가져오느라 같이 딸려옴..&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;3. 각 함수별 설명&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;[ printMain / returnMain / inputMenu / inputData&amp;nbsp;]&lt;/p&gt;
&lt;pre class=&quot;brush:java&quot;&gt;void printMain(linkedList *L) {
	printf(&quot;1. 리스트\n&quot;);
	printf(&quot;2. 검  색\n&quot;);
	printf(&quot;3. 삽  입\n&quot;);
	printf(&quot;4. 삭  제\n&quot;);
	printf(&quot;5. 종  료\n&quot;);
	printf(&quot;메뉴를 골라주세요 : &quot;);
	inputMenu(L);
}

void returnMain(linkedList *L) {
	char c;
	printf(&quot;메인으로(Y/y) 종료(N/n) : &quot;);
	
	// scanf 그냥 통과되는 문제(버퍼를 비우자)
	// 이상하게 fflush(stdin)이 안먹혀서 한칸을 비우고 스캔하는 방법을 사용.
	scanf(&quot; %c&quot;, &amp;amp;c);

	if (c == 'Y' || c == 'y') {
		system(&quot;cls&quot;);
		printMain(L);
	}
	else if (c == 'N' || c == 'n')
		exit(1);
	else {
		printf(&quot;잘못 누름. 다시 입력 : &quot;);
		returnMain(L);
	}
}

void inputMenu(linkedList *L) {
	int num = 0;

	scanf(&quot;%d&quot;, &amp;amp;num);

	if (num &amp;gt; 5 || num &amp;lt; 1) {
		printf(&quot;1부터 5까지 중에서 고르세요 : &quot;);
		num = 0;
		scanf(&quot; %d&quot;, &amp;amp;num);
	}
	else {
		switch (num) {
		case 1:
			printNode(L);
			break;
		case 2:			
			findNode(L);
			break;
		case 3:
			inputData(L);
			break;
		case 4:
			deleteNode(L);
			break;
		case 5:
			exit(1);
		}
	}
}

void inputData(linkedList *L) {
	char name[20];
	int phone, num;

	printf(&quot;순번 이름 전화번호 순으로 입력하세요 : &quot;);
	scanf(&quot; %d %s %d&quot;, &amp;amp;num, name, &amp;amp;phone);
	
	createNode(L, name, phone, num);
}
&lt;/pre&gt;&lt;p&gt;&amp;nbsp;- 별 거 없다. 간단한 메뉴를 위한 출력문과 데이터 입력을 받는 함수들이다.&lt;/p&gt;&lt;p&gt;&amp;nbsp;- returnMain()에서 scanf()관련 주석을 설명하자면, scanf함수를 한번 이상 사용하게 되면, 입력 할 때 쓰는 엔터값이 버퍼에 저장되게 된다.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;scanf함수는 stdin이라는 버퍼에 있는 값을 읽는데, 이 버퍼에 엔터키 값이 들어가는 것.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;따라서 두번째 scanf함수 부터는 버퍼에 있는 엔터키 값이&amp;nbsp;자동으로 입력되어 그저 슥 지나가게 된다. (인식을 못 하는 것 처럼 보임)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;해결방법으로 fflush(stdin)을 쓰는 방법이 있다. 말 그대로 stdin 버퍼에 있는 값을 다 날려버린다.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;두번째로 scanf(&quot; %c&quot;, c) 와 같이 한칸을 띄고 입력을 받는 방법인데, 한 칸을 띄우게 되면 버퍼의 첫번째 값을 무시하고 두번째 값부터 읽게 되어 엔터값을 무시할 수 있다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;다음 글부터 주요 함수들을 설명하겠음&lt;/p&gt;</description>
      <category>개발/C</category>
      <author>까슈</author>
      <guid isPermaLink="true">https://ggashu.tistory.com/4</guid>
      <comments>https://ggashu.tistory.com/4#entry4comment</comments>
      <pubDate>Fri, 30 Mar 2018 13:20:12 +0900</pubDate>
    </item>
  </channel>
</rss>