ホーム » 2011 » 6月 » 29

日別アーカイブ: 2011年6月29日

2011年6月
 1234
567891011
12131415161718
19202122232425
2627282930  

検索・リンク

リストの生成

リスト構造の生成。テスト直しの後に実施した説明が抜けているので、 リストの生成と処理の部分も含めて2週分を記載。

リスト生成の基礎

リスト構造のイメージを分かってもらうために、面倒だけど データ生成を単調に書いた例。

struct List {
int data ;
struct List* next ;
} ;
// 最初は単純に...
// malloc失敗チェックは省略
struct List* top ;
top = (struct List*)malloc( sizeof( struct List ) ) ;
top->data = 1 ;
top->next = (struct List*)malloc( sizeof( struct List ) ) ;
top->next->data = 2 ;
top->next->next = NULL ;

さすがに面倒なので、補助関数を使う。

// 補助関数を使って
struct List* cons( int x , struct List* n ) {
struct List* ans =
(struct List*)malloc( sizeof( struct List ) ) ;
if ( ans != NULL ) {
ans->data = x ;
ans->next = n ;
}
return ans ;
}
struct List* top = cons( 1 , cons( 2 , NULL ) ) ;

リストを使った簡単な処理

リストの末端には、これ以上データが続いていないことを表すNULLが入っている。

void print( struct List* p ) {
for( ; p != NULL ; p = p->next )
printf( "%d¥n" , p->data ) ;
}
int sum( struct List* p ) {
int s = 0 ;
for( ; p != NULL ; p = p->next )
s += p->data ;
return s ;
}
void main() {
struct List* top = cons( 1, cons( 2, cons( 3, NULL ) ) ) ;
print( top ) ;
printf( "%d¥n" , sum( top ) ) ;
}

リスト構造の応用では、2分木なども説明するので、その説明の導入として、 再帰で同じ処理を書いてみる。

void print( struct List* p ) {
if ( p != NULL ) {
printf( "%d¥n" , p->data ) ;
print( p->next ) ;
}
}
int sum( struct List* p ) {
if ( p == NULL ) {
return 0 ;
} else {
return p->data + sum( p->next ) ;
}
}

入力しながらリストを追加

手作業でリストを生成するような処理では、汎用性が無いので、 データを入力しながらリストを生成してみる。

void main() {
struct List* top = NULL ;
int x ;
while( scanf( "%s" , &x ) == 1 ) {
top = cons( x , top ) ;
}
}

しかし、上記の例では、新しい要素をリストの先頭に挿入する方法なので、 データは入力順序と逆順に保存される。 入力順序と同じように、最後のデータが末尾に入るように書くには、 末尾に挿入するデータの場所を覚えるポインタ(tail)を使って、 以下のように書くことができる。

void main() {
struct List* top = NULL ;
struct List** tail = &top ;
int x ;
while( scanf( "%s" , &x ) == 1 ) {
*tail = cons( x , NULL ) ;
tail = &( (*tail)->next ) ;
}
}

システム

最新の投稿(電子情報)

アーカイブ

カテゴリー