C言語のリスト(格納構造)

一覧(リンクストレージ構造)とを作成

リスト、別名チェーンのストレージ構造または単一リンクリスト、論理的な関係「1」のデータを格納します。順序異なるテーブルは、リンクされたリストは、ランダムである物理的記憶場所に格納されたデータ要素のリストを使用して、換言すれば、物理的なデータの記憶状態を限定するものではありません。

例えば、ストレージリスト用いて{1,2,3}以下に示すように、物理的なデータの記憶状態を:
ここに画像を挿入説明
私たちは、データ間の論理関係を反映していない図を参照。この点で、溶液のリストは、ストア内の各データ要素は彼の直後の後続の要素を指し示すためのポインタを備えています。以下に示すように:
ここに画像を挿入説明
この上に画像、データ要素がランダムに格納され、ポインタデータを介して、論理的な記憶構造との関係であることを示しストレージ構造を連結しました。

ノードのリスト

図2に見られるように、各データがリストに格納され、次の2つの部分で構成さ:

  1. データ要素自体は、その領域で呼ばれるデータフィールド
  2. 面積が呼び出され、後続の要素を指し示す直接ポインタポインタ・フィールド

すなわち、以下に示すようなリスト構造に格納された各データ要素:
ここに画像を挿入説明
上に示した構造は、リストと呼ばれるノード、実際のリストは、実際のデータ要素のノードに格納されているその下に示すように、これらのノードに含まれる:
ここに画像を挿入説明
したがって、特定の実装のリンクされたリスト内の各ノードは、構造は、特に、C言語の使用を必要とします次のように実装コード:

typedef struct Linklist{
	int  elem;//代表数据域
	struct Linklist *next;//代表指针域,指向直接后继元素
}Linklist; //link为节点名,每个节点都是一个 link 结构体

注:ノードポインタのためには、(構造体のリンクは*ここでは、形式で記述する必要があります)ドメインをポイントへのポインタであるため、リンクタイプとして宣言しました。

ヘッドノード、ノード・ヘッド・ポインタと第一要素

実際には、図4に示したリスト構造は完全ではありません。完全なリストは、次のコンポーネントで構成されている必要があります

  1. ヘッド・ポインタ:ポインタ一般的には、最初のリストの場所に常にノードによって点を特徴としています。もちろん、ヘッドポインタは、リストを投稿するには簡単に見つけ、リストの位置を示すために使用し、テーブル内のデータを使用しています。
  2. ノード:ノードのリストは、ヘッドノード、第1のノードと他のノードの元に細分される
    ヘッドノード:実際には、空白ノードは、通常、リストの最初のノードとして、データは存在しません。;リストは、ヘッドノードを必要としない、それだけでいくつかの実用的な問題を解決便宜上役割である
    第一要素ノードためヘッドノード(ある、空のノード)から、リスト内の最初のノードがデータを言います。要素ノードを向かいました。;最初の要素は、単にタイトルリストは、最初のノードのデータが何の本当の意味を持っていない含まれているノード
    の他のノード:他のノードのリストを。

このように、ストレージ{1,2,3}の完全なリスト構造を以下に示します。
ここに画像を挿入説明

メモリストは、ヘッドに対するヘッドノードポインタのヘッドノードを有しており、逆に、リストは、ヘッドノードでない場合、次に、ヘッドノードポインタが指す最初の要素に:。

リストの基本的な構造を理解する、のリンクリストを作成する方法を学びましょう。

リスト(初期化)を作成します。

以下のことを行うには、リストの必要性を作成します。

  1. ヘッドポインタを宣言し(必要に応じて、ヘッドノードを宣言することができます)。
  2. いつでも、その先行ノードへの論理的な関係を確立するために、作成プロセスの間に、データを格納するための複数のノードを作成します。

例えば、ストレージ作成するために{1,2,3,4 }以下のようにヘッドレスノードリストを、C言語コードは次のとおりです。

linklist * initlinklist(){
	linklist * p=NULL;//创建头指针
	linklist * temp = (linklist*)malloc(sizeof(linklist));//创建首元节点
	//首元节点先初始化
	temp->elem = 1;
	temp->next = NULL;
	p = temp;//头指针指向首元节点
	//从第二个节点开始创建
	for (int i=2; i<5; i++) {
	 //创建一个新节点并初始化
		linklist *a=(linklist*)malloc(sizeof(linklist));
		a->elem=i;
		a->next=NULL;
		//将temp节点与新建立的a节点建立逻辑关系
		temp->next=a;
		//指针temp每次都指向新链表的最后一个节点,其实就是 a节点,这里写temp=a也对
		temp=temp->next;
	}
	//返回建立的节点,只返回头指针 p即可,通过头指针即可找到整个链表
	return p;
}

あなたは、メモリを作成したい場合は{1,2,3,4}、リストのヘッドノード、C言語のコードが含まれています。

linklist * initlinklist(){
	linklist * p=(linklist*)malloc(sizeof(linklist));//创建一个头结点
	linklist * temp=p;//声明一个指针指向头结点,
	//生成链表
	for (int i=1; i<5; i++) {
		linklist *a=(linklist*)malloc(sizeof(linklist));
		a->elem=i;
		a->next=NULL;
		temp->next=a;
		temp=temp->next;
	}
	return p;
}

次のように私たちは、主な機能にinitLink機能を単純に呼び出し、あなたは簡単に保存された{1,2,3,4}のリストを作成することができ、C言語の完全なコードは次のとおりです。

#include <stdio.h>
#include <stdlib.h>
//链表中节点的结构
typedef struct Linklist{
	int  elem;
	struct Linklist *next;
}linklist;
//初始化链表的函数
linklist * initlinklist();
//用于输出链表的函数
void display(linklist *p);
int main() {
	//初始化链表(1,2,3,4)
	printf("初始化链表为:\n");
	linklist *p=initlinklist();
	display(p);
	return 0;
}
linklist * initlinklist(){
	linklist * p=NULL;//创建头指针
	linklist * temp = (linklist*)malloc(sizeof(linklist));//创建首元节点
	//首元节点先初始化
	temp->elem = 1;
	temp->next = NULL;
	p = temp;//头指针指向首元节点
	for (int i=2; i<5; i++) {
		linklist *a=(linklist*)malloc(sizeof(linklist));
		a->elem=i;
		a->next=NULL;
		temp->next=a;
		temp=temp->next;
	}
	return p;
}
void display(linklist *p){
	linklist* temp=p;//将temp指针重新指向头结点
	//只要temp指针指向的结点的next不是Null,就执行输出语句。
	while (temp) {
		printf("%d ",temp->elem);
		temp=temp->next;
	}
	printf("\n");
}

プログラムの結果:

リストを初期化することである:
1 2 3 4
:あなたが作成したヘッドノードリストで使用する場合は、ディスプレイリストの出力を修正するために、適切な機能のニーズを作るために:

void display(linklist *p){
	linklist* temp=p;//将temp指针重新指向头结点
	//只要temp指针指向的结点的next不是Null,就执行输出语句。
	while (temp->next) {
		temp=temp->next;
		printf("%d",temp->elem);
	}
	printf("\n");
}

要素のリストを挿入

リストに追加要素として順番テーブルと、追加の位置に応じて、次の3つの場合に分けることができます。

  • (最初のノードの後)最初の要素ノードとして、リストの先頭に挿入されます。
  • リストの途中でどこかに挿入されました。
  • リストの最後のデータ要素として、非常に最後のリストに挿入されました。

新しい要素の挿入位置が固定さが、固定された要素を挿入するリストは考えていませんが、唯一のあなたが指定した場所に新しい要素を挿入することができ、次の2つのステップを実行する必要があります。

  1. 挿入位置の後に次のノードへの新しいノードポインタ。
  2. 次のノードへのノードのポインタの前方挿入位置が挿入されます。

例えば、我々はリストの{1,2,3,4}先頭、中間部分、プロセスは次のように実装される新しいエレメント5を挿入尾に基づいている:
ここに画像を挿入説明
ASが図からわかるように、新規要素の異なる挿入位置が、実装インサートもののこの方法は、最初のステップ1、ステップ2で、同じです。

:要素リスト操作は、ステップ1とステップ2の前に挿入されなければならない、そうでない場合、最初のステップ2は、挿入位置がリストの部分のその後の損失を引き起こす可能性がある場合、ステップ1は、もはや達成できません。

上記の説明を通じて、我々は要素INSERTチェーンを操作達成するためのCコードを書いてみることができます。

//p为原链表,elem表示新数据元素,add表示新元素要插入的位置
linklist * insertElem(linklist * p,int elem,int add){
	linklist * temp=p;//创建临时结点temp
	//首先找到要插入位置的上一个结点
	for (int i=1; i<add; i++) {
		if (temp==NULL) {
			printf("插入位置无效\n");
			return p;
		}
		temp=temp->next;
	}   
	//创建插入结点c
	linklist * c=(linklist*)malloc(sizeof(linklist));
	c->elem=elem;
	//向链表中插入结点
	c->next=temp->next;
	temp->next=c;
	return  p;
}

ヒント:insertElem機能を追加するためのif文、挿入位置を決定するためのユーザ入力が有効です。例えば、{1,2,3}は、リストのリストに新たな要素を挿入するデータ要素は、ユーザ操作が明らかに無効で、その後if文トリガー項100にユーザの位置が記憶されています。

削除リスト要素

あなたは、リストから、指定されたデータ要素を削除すると、実際には、リストから削除されるデータ要素のノードが存在するが、収納スペースを担当する資格のプログラマーとして、収納スペースは、もは​​や使用されているが、速やかに解放されるべきではありません。したがって、リストからのデータ要素の削除は、以下の2段階の操作を必要とします。

  1. ノードは、リストから選びました。
  2. 手動でノードが占有するメモリ空間を回復している、ノードを軽減しました。

このうち、ノードのリストからわずかワンライナーを実行し、ノードの直接の先行ノードの一時を見つけ、非常に単純なを達成するために除去:

temp->次= temp->ネクスト>次;

そこから、例えば、{1,2,3,4}要素3のリストを削除するには、以下に示すように、このコードの効果が行われる。
ここに画像を挿入説明
したがって、次のようにC言語の要素のリストを削除します。

//p为原链表,add为要删除元素的值
linklist * delElem(linklist * p,int add){
	linklist * temp=p;
	//temp指向被删除结点的上一个结点
	for (int i=1; i<add; i++) {
		temp=temp->next;
	}
	linklist * del=temp->next;//单独设置一个指针指向被删除结点,以防丢失
	temp->next=temp->next->next;//删除某个结点的方法就是更改前一个结点的指针域
	free(del);//手动释放该结点,防止内存泄漏
	return p;
}

我々は最終的に自由な手の機能がリリースされましデルオフリストノードから見ることができます。

要素のリストを表示して下さい

最も一般的に使用される方法は、リストで指定されたデータ要素を見つける:比較するため、各ノードのデータフィールドに格納されたデータ要素を持つ要素を見つけ、ヘッダ、ノードテーブルから横断、比較が成功するか、リストまで、最もを横切ります端NULL(故障のマーク率)。

そのため、リストには、特定のデータ要素C言語のコードを検索します:

//p为原链表,elem表示被查找元素、
int selectElem(linklist * p,int elem){
//新建一个指针t,初始化为头指针 p
	linklist * t=p;
	int i=1;
	//由于头节点的存在,因此while中的判断为t->next
	while (t->next) {
		t=t->next;
		if (t->elem==elem) {
			return i;
		}
		i++;
	}
	//程序执行至此处,表示查找失败
	return -1;
}

:ノードのリストの先頭に通し、試験データにヘッドノードの影響を避ける必要がので、直接有効なリンクされたリストのノードのトラバーサルの頭の上に、上記のコードを確立するために使用されるリンク・リスト・トラバーサル方法を横断します。

要素のリストを更新します。

単にこの要素のストレージノード、操作を変更することができ、データフィールド内のノードを見つけるために横断することによって、要素のリストを更新します。

以下のためのリストC言語コード内のデータ要素を更新直接与えられました:

//更新函数,其中,add 表示更改结点在链表中的位置,newElem 为新的数据域的值
linklist *amendElem(linklist * p,int add,int newElem){
	linklist * temp=p;
	temp=temp->next;//在遍历之前,temp指向首元结点
	//遍历到被删除结点
	for (int i=1; i<add; i++) {
		temp=temp->next;
	}
	temp->elem=newElem;
	return p;
}

あなたが良いと感じた場合、データ要素の上記のリストの詳細については、「変更して再検索への追加や削除は、」C言語コードと完全なコードの実現は、GitHubのにプッシュを関連付けられている、小さなパートナーは、独自のクローンを必要とするために、スターを歓迎します!ここではポータルであるチェーンのストレージ構造は、子供用の靴は、などC、C ++、Javaの、Pythonの、より多くの知識を学びたい、加えて、(私のブログへようこそ再会のブログが)、私たちは一緒に議論!次に、私は滞在が調整されたので、他のアルゴリズムを更新していきます!

公開された19元の記事 ウォンの賞賛8 ビュー612

おすすめ

転載: blog.csdn.net/qq_43336390/article/details/103979034