공부/C & C++

[C언어/자료구조] 원형 리스트

미친사람 2021. 12. 21. 12:22
반응형

http://orentec.co.kr/q_a/list.php?rowid=6495&page=237 

 

====== 오렌지 미디어 ======

      6495. 원형리스트를 작성했는데.. 작동이 않되네요. 아이디 san7309 등록일 2012-06-30 조회수 544 안녕하세요 제가 원형리스트에 더미를 추가한후 사용자로부터 데이터를 입력받는 식의 

orentec.co.kr

 

해당 게시글에 있는 문제를 수정해서 올림

 

Main.c

#include <stdio.h>
#include "RingList.h"

void Menue(void);
int WhoIsPrecede(LData d1, LData d2);

enum {insert = 1, setsortrule, print, delect, exit};

int main(void) {
	List list;
	int data;
	int choice;
	int eliminate;
	ListInit(&list);
	
	while(1) {
		Menue();
		puts("-= 선택해주세요 =-");
		scanf("%d",&choice);
	
		switch(choice) {
		case insert:
			LInsert(&list);
			break;
		case setsortrule:
			SetSortRule(&list,WhoIsPrecede);
			break;
		case delect:
			fputs("삭제 데이터 : ", stdout);
			scanf("%d", &eliminate);
			if(LFirst(&list,&data)) {
				if(data == eliminate) LRemove(&list);
				while(LNext(&list,&data)) if(data == eliminate) LRemove(&list);
			}
			break;
		case print:
			if(LFirst(&list, &data)) {
				printf("%d ", data);
				
				while(LNext(&list, &data)) {
					printf("%d ", data);
				}
			}
			break;
		case exit:
			puts("프로그램을 종료합니다.");
			return 0;
		default:
			puts("다시 선택해주세요.");
		};
	}
}

void Menue(void) {
	puts("===  Menue  ===");
	puts("1. 리스트 삽입");
	puts("2. 정렬 규칙");
	puts("3. 리스트 출력");
	puts("4. 리스트 삭제");
	puts("5. 나가기");
	puts("===============");
}

int WhoIsPrecede(LData d1, LData d2) {
	if(d1<d2) return 0;
	else return 1;
}

 

RingList.h

#ifndef __RING_LIST_H__
#define __RING_LIST_H__

#define TRUE 1
#define FALSE 0

typedef int LData;

typedef struct _node {
	LData data;
	struct _node * next;
} Node;

typedef struct _ringList {
	Node * tail;
	Node * cur;
	Node * before;
	int numOfData;
	int (*comp)(LData d1, LData d2);
} RingList;

typedef RingList List;

// 초기화 
void ListInit(List * plist);

// 삽입 
void LInsert(List * plist);

// 처음, 다음 이후 
int LFirst(List * plist, LData * pdata);
int LNext(List * plist, LData * pdata);

// 삭제 
void LRemove(List * plist);

// 정렬 
void SetSortRule(List * plist, int (*comp)(LData d1, LData d2));

// 카운트 
int LCount(List * plist); 

#endif

 

RingList.c

#include <stdio.h>
#include <stdlib.h>
#include "RingList.h"

void ListInit(List * plist) {
	// 더미 생성 
	plist->tail = (Node*)malloc(sizeof(Node));
	// 원형 리스트라 꼬리 물기 
	plist->tail->next = plist->tail;
	// 초기화 
	plist->cur = NULL;
	plist->before = NULL;
	plist->comp = NULL;
	plist->numOfData = 0;
}

void LInsert(List * plist) {
	LData data;
	fputs("데이터 입력 : ", stdout);
	scanf("%d", &data);
	
	if(plist->comp == NULL) {
		FInsert(plist, data);
	} else {
		SInsert(plist, data);
	}
}

void FInsert(List * plist, LData data) {
	Node * newNode = (Node*)malloc(sizeof(Node));
	newNode->data = data;
	
	newNode->next = plist->tail->next;
	plist->tail->next = newNode;
	
	plist->numOfData++;
}

void SInsert(List * plist, LData data) {
	Node * newNode = (Node*)malloc(sizeof(Node));
	Node * pred = plist->tail->next;
	newNode->data = data;
	
	while(pred->next != plist->tail && plist->comp(data, pred->next->data) != 0) {
		pred = pred->next;
	}
	newNode->next = pred->next;
	pred->next = newNode;
	
	plist->numOfData++;
}

int LFirst(List * plist, LData * pdata) {
	if(plist->tail == plist->tail->next) return FALSE;

	plist->before = plist->tail;
	plist->cur = plist->tail->next;
	
	*pdata = plist->cur->data;
	return TRUE;
}

int LNext(List * plist, LData * pdata) {
	if(plist->cur->next == plist->tail) return FALSE;

	plist->before = plist->cur;
	plist->cur = plist->cur->next;
	
	*pdata = plist->cur->data;
	return TRUE;
}

void LRemove(List * plist) {
	Node * rpos = plist->cur;
	
	if(rpos == plist->tail) {
		if(plist->tail == plist->tail->next) {
			plist->tail = NULL;
		} else {
			plist->tail = plist->before;
		}
	}

	plist->before->next = plist->cur->next;
	plist->cur = plist->before;
	
	printf("%d 가 삭제되었습니다. \n", rpos->data);
	free(rpos);
}

void SetSortRule(List * plist, int (*comp)(LData d1, LData d2)) {
	plist->comp = comp;
}

 

 

12년도 게시글이라 그런지

독일어를 사용해서 만들었는데, 처음에는 뭔 영어가 이래 하다가 번역하니 독일어더라

그때 그 감성 다시금 기억하며 코드를 읽으며 수정해보았다.

 

enum 라는 열거형에 작성된 remove가 stdio.h 에 있는 remove 랑 겹쳐서 난 문제였으며 delect 로 수정해주니 정상적으로 작동한다.

 

그 외에 코드가 보기 불편해서 보기편하게 변경했으며 누락된 부분을 추가했다.

물론 귀찮아서 몇몇개만 추가하고 가독성도 신경을 안썻다.

 

보고 수정하는건 익숙한데, 직접 만들기엔 아직 역부족인듯하다.

노력하자

반응형