[c] 単方向リスト

単方向リスト作成例


<stdio.h> //fgets, printf
<malloc.h> //malloc
<string.h> //strcmp, strcpy
<stdlib.h> //atoi

typedef struct list {
char name[20];
struct list *next;
}LIST;

LIST* inputData();
void viewList(LIST *);
void deleteList(LIST *);
void memoryFree(LIST *);

int main(void)
{
LIST *headList = NULL;	//先頭アドレス保持用

/* リストのデータ入力 */
headList = inputData();
/* 一覧表示 */
viewList(headList);

/* 削除 */
deleteList(headList);
/* 一覧表示 */
viewList(headList);

/* メモリの解放 */
memoryFree(headList);

return 0;
}

/* データを入力し、リスト構造で保持する。 */
/* 先頭アドレスを戻す。 */
LIST* inputData()
{
LIST *headList = NULL;	//先頭アドレス保持用
LIST *nextList = NULL;	//データ入力用
LIST *tempList = NULL;	//次のアドレス変更のための一つ前のアドレス保持用
LIST *freeList = NULL;	//freeするためのLIST
char inputStr[80];		//文字入力用

//メモリの確保
nextList = (LIST *)malloc(sizeof(LIST));

/* データ入力 */
while(1)
{
	//nextListの次のアドレスを教えるためにnextListのアドレスを覚えておく
	tempList = nextList;
	//入力
	fgets(inputStr, 80, stdin);
	//ループの終了条件(Eが入力されたら終了)
	if(strcmp(inputStr, "E\n") == 0)
	{
		break;
	}
	//メモリ確保
	nextList = (LIST *)malloc(sizeof(LIST));
	//入力値設定
	strcpy(tempList->name, inputStr);
	//確保先のアドレスを設定
	tempList->next = nextList;
	//確保先のアドレスの次のアドレスはまだ未定
	nextList->next = NULL;
	
	//リストの先頭には個別に教えてあげる必要がある。
	//headListがNULLつまり1順目の場合
	if(headList == NULL)
	{
		headList = tempList;
	}
	//上記でなくて、headListの次のアドレスがNULLつまり2順目の場合
	else if(headList->next == NULL)
	{
		headList->next = nextList;
	}
}	
return headList;
}

/* リストの中身を表示する。 */
void viewList(LIST *_headList)
{
LIST *tempList = _headList;
//headList->nextがNULLの場合numにデータを入れていない
while(tempList->next != NULL)
{
	//現在のアドレスが保持するnameを表示
	printf("%s", tempList->name);
	//現在のアドレスを次のアドレスに変更
	tempList = tempList->next;
}
}

/* リストの中から、選択された番号の要素を削除する。 */
void deleteList(LIST *_headList)
{
LIST *freeList;		//解放アドレスを記憶するためのLIST
LIST *tempList;		//要素を確認するための一時退避LIST
char inputStr[80];	//文字入力のためのchar配列
int deleteNum;		//削除したい順番
int loopCnt;		//ループ用カウンタ

printf("削除したい番号を入力してください -> ");
fgets(inputStr, 80, stdin);
//番号は1番目からだが、配列上は0番目から始まるため1を引いている
deleteNum = atoi(inputStr) - 1;

//先頭の場合のみ処理が異なる
if(deleteNum == 0)
{
	//先頭のアドレスを変える必要がある
	freeList = _headList;
	_headList = _headList->next;
	free(freeList);
}
else
{
	tempList = _headList;
	//消したい番号の一つ前のアドレスを取得
	for(loopCnt = 0; loopCnt < deleteNum-1; loopCnt++)
	{
		tempList = tempList->next;
	}
	freeList = tempList->next;
	//次のアドレスをリストから排除し、さらに次のアドレスが次のアドレスとなる
	tempList->next = tempList->next->next;
	//削除したアドレスを解放する
	free(freeList);
}
}

/* 動的に確保したメモリを解放する */
void memoryFree(LIST *_headList)
{
LIST *freeList = NULL;
LIST *tempList = NULL;

freeList = _headList;
//先頭から順に解放していく
while(freeList->next != NULL)
{
	tempList = freeList->next;
	free(freeList);
	freeList = tempList;
}
}
最終更新:2010年07月01日 14:57
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。