ホーム » スタッフ » 斉藤徹 » リストの生成

2012年6月
 12
3456789
10111213141516
17181920212223
24252627282930

検索・リンク

リストの生成

テストを返却した後、前回の授業の続き。 リストの生成と挿入削除について説明を行う。

// 前回の授業で説明した時のコード
struct List {
int  data ;
struct List* next ;
} ;
struct List* cons( int x , struct List* n ) {
struct List* ans ;
ans = (struct List*)malloc( sizeof( struct List ) ) ;
if ( ans != NULL ) {
ans->data = x ;
ans->next = n ;
}
return ans ;
}

リストの入力と追加

top = cons(1,cons(2,…)) といった方法では、動作確認の時にしか使えない。 実際にデータを入力しながら、リストに保存するプログラムを考える。 前述の cons() の補助関数を使えば、簡単に記載ができる。

struct List* top = NULL ;
int x ;
while( scanf( "%d" , &x ) == 1 ) {
top = cons( x , top ) ;
}
// 11,22,33の順でデータを与えると、
//   top[◯]→[33|◯]→[22|◯]→[11|×]

しかし、この方法では、データを11,22,33の順序で与えても、 生成されるリストは、逆順となってしまう。

そこで、リストの末尾を覚えるポインタを作っておいて、 下記のように記述すれば良い。

struct List* top = NULL ;
struct List** tail = &top ;
int x ;
while( scanf( "%d" , &x ) == 1 ) {
*tail = cons( x , NULL ) ;
tail = &( (*tail)->next ) ;
}
// 11,22,33の順でデータを与えると、
//   top[◯]→[11|◯]→[22|◯]→[33|×]

リストへの挿入・削除

リスト処理の良い点は、必要に応じてメモリを確保していくため、 配列の容量オーバーといった問題を気にしなくて良い所。 一方、配列で途中にデータを挿入する場合、 挿入場所を作るために後続のデータを1つ後ろにずらす処理が必要となる。 また、配列の途中のデータを抜く場合、 後続データを1つ前にずらす処理が必要となる。 でも、リスト構造であれば、ポインタの繋ぎ変えだけで済む。

// 挿入
// ポインタpには、挿入したい場所の直前のセルの場所。
void insert( struct List* p , int x ) {
p->next = cons( x , p->next ) ;
}
// 削除
void delete( struct List* p ) {
struct List* d = p->next ;
p->next = p->next->next ;
free( d ) ;
}

システム

最新の投稿(電子情報)

アーカイブ

カテゴリー