Cohe

연결 리스트 본문

자료구조론

연결 리스트

코헤0121 2023. 3. 1. 10:21
728x90
  • 리스트 자료구조

데이터 연산 설명

 

스택 int stact[100];    
(10,30,40,20) push(35);    
y=pop();      
삽입과 삭제가 한쪽 끝    
int queue[100];    
(10,30,40,20) insert(35);    
y=delete();      
삽입과 삭제가 양쪽 끝    
리스트 int mylist[100];    
(10,30,40,20) intsert(45);    
y=delete(); 삽입과 삭제가 아무 곳에서나 일어난다.    
(문제점)→ 데이터가 많으면 순서를 유지하기 위하여 데이터 이동이 많아진다.      

 

동적 데이터의 관리

프로그램 실행 중 데이터가 이동을 많이 한다면?

  • 데이터가 움직이지 않으면 검색을 빨리할 수 있다.
    • ex) 공룡에 대한 데이터 타입
  • 데이터는 삽입 삭제 연산에 의하여 위치와 개수가 변한다
  • 데이터가 변경되어 위치가 바뀌면 검색을 빨리 하기 위한 재배치를 해야한다

포인터 타입

💡 연결리스트는 기억장소의 임의의 구조체로 구현된 노드를 서로 연결하여 리스트를 만든다. 따라서 다음 데이터가 저장된 노드의 기억장소를 저장하는 값이 필요하다. 기억장소의 주소값을 저장하는 데이터 타입을 포인터 타입이라고 한다.

  • 사용 예시
int x;
int *y;
int z;

x=10;
y=&x;
z=*y;   /*y가 가리키는 곳의 내용을 저장, z=x*/

int a[10]; /* 배열 변수 a는 주소값으로 처리*/ 
#include <stdio.h>

int main(){
int i, *pi;
float f. *pf;
pi=&i; // i의 주소값
pf=%f; //j의 주소값
*pi=1024;
*pf=(float)3.14;
printf("an integet =%d, a float=%f\\n", *pi,*pf);

의자 4개가 있고 사람이 4명을 앉음

#include <stdio.h>
#include <malloc.h>

int main(){
int *pi;
float  *pf;
pi=(int *)malloc(sizeof(int));
pf=(float * )**malloc**(sizeof(float)); /*메모리에서 주소값을 가져오고 정수형 포인터를 갖고 오고 싶다.
주소값이 1000이다 그러면 pi에 1000을 저장한다.
기억장소를 배정받는다.*/

*pi=1024;
*pf=(float)3.14;
printf("an integet =%d, a float=%f\\n", *pi,*pf);
**free(pi);**
free(pf); //기억장소를 반납함

의자가 2개가 있고 의자 2개를 빌려와서 4명이 앉음

의자가 작을 때도 작업을 시작할 수 있으며 무한정 의자를 빌릴 수 있다.

 

출력 : a float=3.14

 

연결리스트를 만들기 위한 구조체 선언

  • 자기참조구조체
  • 동적인 자료의 할당과 해지를 위한 자료구조
struct node{
int data; //data
struct node *link;}; //another node 주소
typedef struct node list_node; //타입으로 선언하면 편리

typedef list_node * list_ptr;

리스트 자료의 예

list_node item1, item2, item3;
ltem1.data=10;
ltem2.data=20;
ltem3.data=30;
	ltem1.link=item2.link=item3.link=NULL;//포인터 초기값
  • 접지 형식으로 표현하여 연결 주소값 자체를 초기화한다.

리스트 연결 예

item1.link=&item2;
item2.link=&item3;
  • 다음 리스트를 연결함

program example

  • 정적 기억장소에 데이터 저장
**프로그램1(p19)

// 연결리스트 프로그램1(p19)

#include <stdio.h>

#include <malloc.h>

struct node {

	int data; // 데이터

	struct node *link; // 다른 데이터 주소(포인터)

};

typedef struct node list_node;

typedef list_node * list_ptr;

 

int main(void)

{

	list_node item1, item2, item3;

	item1.data = 10;

	item2.data = 20;

	item3.data = 30;

	item1.link = item2.link = item3.link = NULL; // 포인터 초기값

	item1.link = &item2; item2.link = &item3; // 노드 연결

	printf("%d %d %d\\n", item1.data, item2.data, item3.data);

}
  • 동적 기억장소에 데이터 저장
#include <stdio.h>
#include <malloc.h>

struct node{
int data; //data
struct node *link;}; //another node 주소
typedef struct node list_node; //타입으로 선언하면 편리
typedef list_node * list_ptr;

int main(void){
list_prt first, second, third;
first=(list_prt)malloc(sizeof(list_node)); //합 영역에 할당
second=(list_prt)malloc(sizeof(list_node));
third=(list_prt)malloc(sizeof(list_node));

third->link=NULL;
first -> data=19; second-> data =20; third-> data =30;
first->link=second;
second->link=third;//노드 연결

printf(%d %d %d \\n", first->data, second->data, third->data);
}

단순 연결리스트

  • 연결리스트의 가장 간단한 형태로 그냥 연결리스트라고 부른다
  • 노드들을 연결한 형태이며 노드는 데이터부분과 링크 부분으로 구성된다
  • 데이터 부분은 한 개 혹은 여러개의 속성을 저장할 수 있다
  • 링크 부분은 다음노드의 주소값을 가리킨다
  • 동적 기억 할당과 해제가 가능하다.

단순 연결리스트

<그림 참조 - 21페이지>

예제

  • 단순 연결리스트 노드의 선언과 생성
struct node{ int data;struct node *link;};
typedef struct node list_node;
typedef list_node * list_ptr;
  • 빈리스트에 노드를 한 개 생성하여 50을 저장
<23페이지에 있음>
  • 수정
  • 삭제
  • 생성함수

리스트 생성 시험 프로그램

리스트 생성 실험 프로그램 : 4개의 노드를 반복문으로 생성 (6-2)

#include <stdio.h>

#include <malloc.h>

struct node {

	int data;

	struct node * link;

};

typedef struct node list_node;

typedef list_node * list_ptr;

 

int main()

{

	list_ptr ptr = NULL, before = NULL; int i;

	for (i = 1; i <= 4; i++) {

		ptr = (list_ptr)malloc(sizeof(list_node));

		ptr->data = i * 10;

		ptr->link = before;

		before = ptr;

	}

	printf(" %d\\n", ptr->data);

	printf(" %d\\n", ptr->link->data);

 

	printf(" %d\\n", ptr->link->link->data);

	printf(" %d\\n", ptr->link->link->link->data);

}

연결리스트를 이용한 스택과 큐 구현

연결리스트를 이용한 스택의 구현

왜 스택으로 하는가? → 배열의 개수를 100개로 선언을 했으나 실질적으로 3~4 등과 같이 적은 공간만 쓰거나 공간보다 더 많이 사용할 경우 error가 된다.

연결리스트의 경우 동적할당이 가능하기 때문에 기억장소의 절약과 활용이 편리하다는 장점이 있다.

번거롭다는 단점이 있다.

스택의 상태

  • 비어있는 상태 : top ==NULL
  • 꽉 찬 상태
    • malloc() 함수 호출 시 기억 장소 공간이 부족할 때
  •  

스택 test의 main 함수

/* 프로그램 6-3, 6-4 연결리스트를 이용한 스택 : linkedlist-stack.c */
#include <stdio.h>
#include <malloc.h>
#define MAX_STACK_SIZE 100

struct node {
    int item;
    struct node *link;
};
typedef struct node stacknode;
typedef stacknode *stacknode_ptr;

stacknode_ptr top=NULL;

void push(int data) {
   stacknode_ptr temp =
   (stacknode_ptr)malloc(sizeof (stacknode));
   if( !temp) {
	fprintf(stderr,"The memory is full\\n");
	exit(1);
   }
   temp->item=data;
   temp->link=top;
   top = temp;
}

int pop() {
   stacknode_ptr temp = top;
   int item;
   if( !temp ) {
	fprintf(stderr,"The stack is empty\\n");
	exit(1);
   }
   item=temp->item;
   top=temp->link;
   free(temp);
   return item;
}

int isempty()
{ if( top == NULL ) return(1); else return(0); }

int main()
{
	int e;
	push(20);
	push(40);
	push(60);

	printf(" Begin Stack Test ...\\n");

	while(!isempty())
	{
		e = pop();
		printf("value = %d\\n", e);
	}
}

연결리스트를 이용한 큐의 구현

  • 앞은 삽입 삭제가 쉬우나 뒤는 삭제가 어렵고 삽입은 쉽다.
  • ⇒ rear가 마지막 노드. front가 첫 번째 노드로 만들자!

큐의 상태

  • 비어있는 큐 : front==null
  • 꽉 찬 상태 : malloc()함수 호출 시 기억 장소 확보가 어려울 때
/* DBLAB linkedlist-queue.c */
#include <stdio.h>
#include <malloc.h>
#define MAX_QUEUES 10 /* m=MAX_QUEUES=10 */
typedef struct {
	int key;/* other fields */
} element;

struct node {
	element item;
	struct node* link;
};
typedef struct node queuenode;
typedef queuenode* queuenode_ptr;

void insertq(queuenode_ptr *front, queuenode_ptr *rear, element x) {
	queuenode_ptr temp = (queuenode_ptr)malloc(sizeof(queuenode));
	if( !temp ) {
		fprintf(stderr,"The memory is full\\n");
	exit(1);
	}
	temp->item=x;
	temp->link=NULL;
	if(*front) (*rear)->link=temp;
	else *front = temp;
	*rear = temp;
}

element deleteq(queuenode_ptr *front) {
	queuenode_ptr temp=*front;
	element x;
	if(!(*front)) {
		fprintf(stderr,"The queue is empty\\n");
		exit(1);
	}
	x=temp->item;
	*front=temp->link;
	free(temp);
	return x;
}

int main()
{
	queuenode_ptr front=NULL, rear=NULL;
	element x; x.key=50;
	insertq(&front, &rear, x);
	insertq(&front, &rear, x);
	insertq(&front, &rear, x);

	printf(" Begin Queue Test ...\\n");

	while(! front==NULL)
	{
		x = deleteq(&front);
		printf("value = %d\\n", x.key);
	}
}

6.2

#include <stdio.h>
#include <malloc.h>

struct node {
	int data;
	struct node * link;
};

typedef struct node list_node;
typedef list_node * list_ptr;

void print_list(list_ptr p);

int main() {
	list_ptr p;

	int n = 10;

	list_ptr temp = NULL;
	list_ptr before = NULL;
	for (int i = 1; i <= n; i++) {
		temp = (list_ptr)malloc(sizeof(list_node));
		temp->data = (n - i + 1) * 10;
		temp->link = before;
		before = temp;
	}
	p = temp;

	print_list(p);

	//find(p, 2);

	list_ptr head = p;
	int i = 0;
	int k = 1;
	for (int i = 0; i <k-1; i++) {
		head = head->link;
	}
	printf("ok %d\\n", head->data);

}

list_ptr creat(int n) {
	list_ptr first;
	list_ptr temp = NULL;
	list_ptr before = NULL;
	for (int i = 1; i <= n; i++){
		temp=(list_ptr)malloc(sizeof(list_node));
		temp->data = (n - i + 1) * 10;
		temp->link = before;
		before = temp;
	}
	first = temp; return first;
}

void print_list(list_ptr p) {
	list_ptr temp;
	for (temp = p; temp; temp = temp->link) {
		printf("%d\\n", temp->data);

	}
}
  •  

6.4

  • 실험 1
  • 실험 2
int elementcount(queuenode_ptr front, queuenode_ptr rear){
if(!front){return -1;}

/*여기 작성*/

return 0;
}

void main(){

printf(queue length = "%d", elementcount(front, rear));
}
/* DBLAB linkedlist-queue.c */
#include <stdio.h>
#include <malloc.h>
#define MAX_QUEUES 10 /* m=MAX_QUEUES=10 */
typedef struct {
	int key;/* other fields */
} element;

struct node {
	element item;
	struct node* link;
};
typedef struct node queuenode;
typedef queuenode* queuenode_ptr;

int elementcount(queuenode_ptr front, queuenode_ptr rear) {
	if (!front) { return -1; }

	else {
		return front-rear;

		//queue에 있는 원소의 수 세기 프로그램
		int count = 0, i=0;
		//while(!i) {
		//	i = front->link;
		//	count++;
		//}
		//return count;
	}

	return 0;
}

void insertq(queuenode_ptr* front, queuenode_ptr* rear, element x) {
	queuenode_ptr temp = (queuenode_ptr)malloc(sizeof(queuenode));
	if (!temp) {
		fprintf(stderr, "The memory is full\\n");
		exit(1);
	}
	temp->item = x;
	temp->link = NULL;
	if (*front) (*rear)->link = temp;
	else *front = temp;
	*rear = temp;
}

element deleteq(queuenode_ptr* front) {
	queuenode_ptr temp = *front;
	element x;
	if (!(*front)) {
		fprintf(stderr, "The queue is empty\\n");
		exit(1);
	}
	x = temp->item;
	*front = temp->link;
	free(temp);
	return x;
}

int main()
{
	queuenode_ptr front = NULL, rear = NULL;
	element x; x.key = 50;
	insertq(&front, &rear, x);
	insertq(&front, &rear, x);
	insertq(&front, &rear, x);

	printf(" Begin Queue Test ...\\n");

	printf("queue length = %d\\n", elementcount(front, rear));

	while (!front == NULL)
	{
		x = deleteq(&front);
		printf("value = %d\\n", x.key);
	}
}

'자료구조론' 카테고리의 다른 글

트리 자료구조  (0) 2023.03.01
고급 연결 리스트  (0) 2023.03.01
5장 스택 응용  (1) 2023.03.01
스택과 큐  (0) 2022.10.02
array  (0) 2022.10.02