자료구조 세미나 포인터
포인터는 추상적이다 ? 포인터는 추상적으로 가질 수 없는 개념이다. 포인터에 대한 개념을 추상적으로 가질 경우 포인터를 100% 활용할 수 없다. 그렇다면 포인터를 어떻게 바라봐야 할까
포인터의 정체 포인터는  int  변수 int  변수가 하드웨어 및 운영체제에 따라 그 크기가 달라지는 것처럼 포인터 변수의 크기도 같이 달라짐 sizeof(  포인터 변수  ) == sizeof( int ) sizeof( char * ) > sizeof( char )  그렇다면 왜 따로 포인터 변수라는 것을 사용하는가 ?
어셈블러에서 포인터 어셈블러에서  OFFSET  이나  ADDR  의 값을 저장할 때 모드에 따라  DWORD  나  WORD  를 사용했다 . 즉 ,  어셈블러에서도 포인터 변수는  int 였다 . 하지만 어셈블러에서는 포인터 변수가 따로 없어서 주소에 있는 값을 참조할 때 여러 가지 처리를 해줘야 했다 .  크기를 모르기 때문에  PTR  을 사용해야 했고 크기에 따라 다르게 주소 값을 증가시켰다 .
어셈블러에서 포인터 어셈블러에서 포인터 사용 mov esi, myaddress mov ax, WORD PTR [esi] add esi, TYPE myaddress mov ax, WORD PTR [esi]
C 언어에서 포인터 포인터는 가리키는 메모리가 어떤 메모리인지 알 수 있게 한다. char * 형의 포인터 변수는 1바이트 변수를 가리키고 있다. FILE * 형의 포인터 변수는 FILE 구조체를 가리키고 있으며 FILE 구조체의 멤버변수에 접근할 수 있게 한다.
C 언어에서 포인터 C 언어에서 포인터 사용 int a, b, c, k[10], *addr; addr = &k[0]; // &k[0] == k a = *addr; addr++; b = *addr; c = *(addr + 4)
자료구조 세미나 링크드 리스트
정의 메모리상에서 인접하지 않은 데이터들을 인접한 것처럼 포인터로 연결한 자료구조 동적으로 생성되는 메모리에 기반 삽입 삭제가 빠르고 메모리의 낭비가 적음
개념도 head tail 데이터 데이터 데이터 데이터
구조체 구조체의 정의 typedef struct _link {    int data;    _link *prev;    _link *next; } LINK;
초기화 초기화 코드 LINK *head, *tail;   void init() {    head = new LINK;    tail = new LINK;      head->next = tail;    head->prev = head;    tail->next = tail;    tail->prev = head; }
초기화 구조 [ data ][ prev ][ next ] 앞에서부터  data, previous, next 진행과정 head [        ][        ][        ] tail [        ][        ][        ] 초기화 후 head(10680 번지 ) [        ][ 10680 ][ 10692 ] tail(10692 번지 ) [        ][ 10680 ][ 10692 ]
삽입 삽입 코드 void put( int a ) {    LINK *t;    t = new LINK;    t->data = a;    t->next = head->next;    t->prev = head;    head->next->prev = t;    head->next = t; }
삽입 진행과정 put( 5 )  를 실행 head(10680 번지 ) [        ][ 10680 ][ 10692 ] tail(10692 번지 ) [        ][ 10680 ][ 10692 ] t(10704 번지 ) [        ][        ][        ] head(10680 번지 ) [        ][ 10680 ][ 10692 ] tail(10692 번지 ) [        ][ 10680 ][ 10692 ] t(10704 번지 ) [  5  ][        ][        ]
삽입 진행과정 head(10680 번지 ) [        ][ 10680 ][ 10692 ] tail(10692 번지 ) [        ][ 10680 ][ 10692 ] t(10704 번지 ) [ 5 ][  10680  ][  10692  ] head(10680 번지 ) [        ][ 10680 ][  10704  ] tail(10692 번지 ) [        ][  10704  ][ 10692 ] t(10704 번지 ) [ 5 ][ 10680 ][ 10692 ]
삭제 삭제 코드 void pop(LINK *k) {    k->next->prev = k->prev;    k->prev->next = k->next; }
삭제 진행과정 pop( head->next )  을 실행 head(10680 번지 ) [        ][ 10680 ][ 10704 ] tail(10692 번지 ) [        ][  10680  ][ 10692 ] k(10704 번지 ) [ 5 ][ 10680 ][ 10692 ] head(10680 번지 ) [        ][ 10680 ][  10692  ] tail(10692 번지 ) [        ][ 10680 ][ 10692 ] k(10704 번지 ) [ 5 ][ 10680 ][ 10692 ]
탐색 탐색 코드 LINK *t; for( t=head->next ; t!=tail ; t=t->next ) {   .. 처리 .. }
트리 구현 트리 또한 링크드 리스트로 구현이 가능 구조체 typedef struct _node { int data; _node *child[ MAX ], *parent; } NODE; 자식노드 또한 링크드 리스트로 만들 수 있다 .

Data Structure 3

  • 1.
  • 2.
    포인터는 추상적이다 ?포인터는 추상적으로 가질 수 없는 개념이다. 포인터에 대한 개념을 추상적으로 가질 경우 포인터를 100% 활용할 수 없다. 그렇다면 포인터를 어떻게 바라봐야 할까
  • 3.
    포인터의 정체 포인터는 int 변수 int 변수가 하드웨어 및 운영체제에 따라 그 크기가 달라지는 것처럼 포인터 변수의 크기도 같이 달라짐 sizeof( 포인터 변수 ) == sizeof( int ) sizeof( char * ) > sizeof( char ) 그렇다면 왜 따로 포인터 변수라는 것을 사용하는가 ?
  • 4.
    어셈블러에서 포인터 어셈블러에서 OFFSET 이나 ADDR 의 값을 저장할 때 모드에 따라 DWORD 나 WORD 를 사용했다 . 즉 , 어셈블러에서도 포인터 변수는 int 였다 . 하지만 어셈블러에서는 포인터 변수가 따로 없어서 주소에 있는 값을 참조할 때 여러 가지 처리를 해줘야 했다 . 크기를 모르기 때문에 PTR 을 사용해야 했고 크기에 따라 다르게 주소 값을 증가시켰다 .
  • 5.
    어셈블러에서 포인터 어셈블러에서포인터 사용 mov esi, myaddress mov ax, WORD PTR [esi] add esi, TYPE myaddress mov ax, WORD PTR [esi]
  • 6.
    C 언어에서 포인터포인터는 가리키는 메모리가 어떤 메모리인지 알 수 있게 한다. char * 형의 포인터 변수는 1바이트 변수를 가리키고 있다. FILE * 형의 포인터 변수는 FILE 구조체를 가리키고 있으며 FILE 구조체의 멤버변수에 접근할 수 있게 한다.
  • 7.
    C 언어에서 포인터C 언어에서 포인터 사용 int a, b, c, k[10], *addr; addr = &k[0]; // &k[0] == k a = *addr; addr++; b = *addr; c = *(addr + 4)
  • 8.
  • 9.
    정의 메모리상에서 인접하지않은 데이터들을 인접한 것처럼 포인터로 연결한 자료구조 동적으로 생성되는 메모리에 기반 삽입 삭제가 빠르고 메모리의 낭비가 적음
  • 10.
    개념도 head tail데이터 데이터 데이터 데이터
  • 11.
    구조체 구조체의 정의typedef struct _link {   int data;   _link *prev;   _link *next; } LINK;
  • 12.
    초기화 초기화 코드LINK *head, *tail;   void init() {   head = new LINK;   tail = new LINK;     head->next = tail;   head->prev = head;   tail->next = tail;   tail->prev = head; }
  • 13.
    초기화 구조 [data ][ prev ][ next ] 앞에서부터 data, previous, next 진행과정 head [        ][        ][        ] tail [        ][        ][        ] 초기화 후 head(10680 번지 ) [        ][ 10680 ][ 10692 ] tail(10692 번지 ) [        ][ 10680 ][ 10692 ]
  • 14.
    삽입 삽입 코드void put( int a ) {   LINK *t;   t = new LINK;   t->data = a;   t->next = head->next;   t->prev = head;   head->next->prev = t;   head->next = t; }
  • 15.
    삽입 진행과정 put(5 ) 를 실행 head(10680 번지 ) [        ][ 10680 ][ 10692 ] tail(10692 번지 ) [        ][ 10680 ][ 10692 ] t(10704 번지 ) [        ][        ][        ] head(10680 번지 ) [        ][ 10680 ][ 10692 ] tail(10692 번지 ) [        ][ 10680 ][ 10692 ] t(10704 번지 ) [ 5  ][        ][        ]
  • 16.
    삽입 진행과정 head(10680번지 ) [        ][ 10680 ][ 10692 ] tail(10692 번지 ) [        ][ 10680 ][ 10692 ] t(10704 번지 ) [ 5 ][  10680 ][  10692 ] head(10680 번지 ) [        ][ 10680 ][  10704 ] tail(10692 번지 ) [        ][  10704 ][ 10692 ] t(10704 번지 ) [ 5 ][ 10680 ][ 10692 ]
  • 17.
    삭제 삭제 코드void pop(LINK *k) {   k->next->prev = k->prev;   k->prev->next = k->next; }
  • 18.
    삭제 진행과정 pop(head->next ) 을 실행 head(10680 번지 ) [        ][ 10680 ][ 10704 ] tail(10692 번지 ) [        ][  10680 ][ 10692 ] k(10704 번지 ) [ 5 ][ 10680 ][ 10692 ] head(10680 번지 ) [        ][ 10680 ][  10692 ] tail(10692 번지 ) [        ][ 10680 ][ 10692 ] k(10704 번지 ) [ 5 ][ 10680 ][ 10692 ]
  • 19.
    탐색 탐색 코드LINK *t; for( t=head->next ; t!=tail ; t=t->next ) {   .. 처리 .. }
  • 20.
    트리 구현 트리또한 링크드 리스트로 구현이 가능 구조체 typedef struct _node { int data; _node *child[ MAX ], *parent; } NODE; 자식노드 또한 링크드 리스트로 만들 수 있다 .