双方向リスト
http://www.geocities.jp/ky_webid/algorithm/012.html
逆方向にも参照できる双方向リストですね。
循環リストの拡張でやってみます。
#include <stdio.h> #include <stdlib.h> struct LIST { int data; int last; struct LIST *next; struct LIST *prev; }; typedef struct LIST LIST; LIST *create_list(int data) { LIST *p; p = (LIST *)malloc(sizeof(LIST)); if ( p == NULL ) { // メモリ不足エラー return NULL; } p->next = NULL; p->prev = NULL; p->data = data; p->last = 1; printf("create %p\n",p); return p; } LIST *add_list (LIST *p,int data) { LIST *add,*q; add = create_list(data); while( !p->last ){ p = p->next; } if ( p->next == NULL ) { q = p; } else { q = p->next; } p->last = 0; p->next = add; q->prev = add; add->next = q; add->prev = p; return add; } void free_list (LIST *p) { LIST *s = p; LIST *q; do { q = p; p = p->next; printf("free %p\n",q); free(q); q = NULL; } while ( s!=p ); } void delete_list (LIST *p,int data) { LIST *s = p; LIST *q; do { q = p; p = p->next; if ( p->data == data ) { q->next = p->next; q->next->prev = q; printf("free %p\n",p); free(p); p = NULL; // まだ同じ値の要素があるかもしれないので引き続き検索する p = q->next; } } while ( s!=p ); } void show_list (LIST *p) { LIST *s = p; do{ printf("%d\n",p->data); p = p->next; }while( s!=p ); } void show_prev_list (LIST *p) { LIST *s = p; do{ printf("%d\n",p->data); p = p->prev; }while( s!=p ); } int main (void) { LIST *head; LIST *p; head = create_list(100); p = add_list(head,200); add_list(head,300); add_list(p,200); add_list(p,500); delete_list(head,200); puts("next:"); show_list(head); puts("prev:"); show_prev_list(head); free_list(head); return 0; }
$ main create 00383148 create 00383160 create 00383178 create 00383190 create 003831A8 free 00383160 free 00383190 next: 100 300 500 prev: 100 500 300 free 00383148 free 00383178 free 003831A8
うまくいってますね。
まだまだ実装が汚いので他の実装例を見ながら少しずつ習得していきます。