ストレージ構造線状 - レッスン8
最大の問題は、多くのことを移動する必要がある要素のテーブルの挿入や削除のためです!どのように解決するには?
生徒A:線形位置空いたテーブルのデータ要素との間、次の使用の挿入のために。
学生B:それをしないでください!どんなに多くの中間スペースが不足する可能性がありません!
学生A:まあ、それは何の解決策ではないではありません!
学生B:各要素が行、どのように空のプラグ上の彼の次の要素を知っているように私は思います。
1.ストレージ構造
その直後の後続データ要素と各要素間の論理関係を表す情報自体に加えて、各記憶素子だけでなく、その直接の後継者を示す情報を格納する必要があるためです。
L鎖ストアロジック構造
直鎖構造にnノードリンクチェーンは、各ノードが唯一のポインタフィールドを含むテーブルと呼ばれ、単一のリンク・リストと呼ばれています。
Lヘッダノード
リストの最初のノードは、データ要素及び情報自体のいくつかの最初のリストへのポインタを含みます。
データノードL
ノードデータ要素のリストを表す、およびデータ要素の次のデータ要素に情報ポインタポイントを含みます。
エンド・ノードリットル
次の要素ポインタは何ら後継者がないことを示す、NULLであるデータのリンクされたリスト内の最後のノード。
2. C言語記述
C言語でリンクされたリスト構造ポインタフィールドを定義するために使用されてもよいです。
リスト・ヘッダ・ノード構造を用いて実装されてもよいです。
typedefは構造体_tag_LinkList
{
LinkListNodeヘッダ。
int型の長さ。
} TLinkList; //ヘッドノードが定義されています
typedefは構造体_tag_LinkListNode LinkListNode
構造体_tag_LinkListNode
{
LinkListNode *次の;
int型の長さ。
} TLinkList; //ノード・ポインタ・フィールドが定義され
構造体の値
{
LinkListNodeヘッダ。
テレビで;
}; //インスタンスデータ要素定義
3.第1の要素の動作POSを取得
(1)線形テーブルを決定することは正当です。
(2)法的位置か否かを決定します。
(3)次のポインタによってヘッダの開始後、すなわち、次のポインタを取得する要素を指し、現在の要素をPOSパスを移動させます。
LinkListNode *現在=(LinklistNode *)のリスト。
用(i = 0; iはPOSを<; iは++)
{
現在= crrrent->次。
}
RET =の電流>次。
4.位置posアルゴリズムに要素を挿入します
(1)線形テーブルを決定することは正当です。
(2)挿入位置を決定することは正当です。
(3)次のポインタによってヘッダの開始後、すなわち、次のポインタが挿入される位置を指し、現在の要素をPOSパスを移動させます。
(4)新たな要素を挿入します。
(5)プラス直線状の長さ。
LinkListNode *現在=(LinklistNode *)のリスト。
(I = 0;(私は<POSを)&&(電流 - >次= NULL);!私は++)のために
{
現在=の電流>次。
}
ノード - >次=の電流>次。
電流 - >次=ノード。
sList->長++;
前記第1のアルゴリズムのPOS要素を削除
(1)線形テーブルを決定することは正当です。
(2)挿入位置を決定することは正当です。
(3)最初のPOS要素を取得します。
リストから削除(4)第一のPOS要素。
(5)線状長さから1を引きました。
TLinkList * SLIST =(TLinkList *)リスト。
リンクリストノード*右= NULL;
int型私= 0;
もし((SLIST!= NULL)&&(0 <= POS)&&(POS <sList->長))
{
LinkListNode *現在=(LinkListNode *)リスト。
用(i = 0; iはPOSを<; iは++)
{
現在=の電流>次。
}
RET =の電流>次。
電流>次= ret->次。
sList-> length--。
}
6.ハンズプログラム
LinkList.h
#ifndefの_LINKLIST_H_
#define _LINKLIST_H_
空LINKLISTのtypedef。
typedefは構造体_tag_LinkListNode LinkListNode。
構造体_tag_LinkListNode
{
LinkListNode *次の;
}。
LINKLIST * LinkList_Create();
空LinkList_Destroy(LINKLISTの*リスト)。
LinkList_Clear(LINKLIST *リスト)を無効に。
int型LinkList_Length(LINKLIST *リスト)。
int型LinkList_Insert(LINKLIST *リスト、LinkListNode *ノード、int型のPOS);
LinkListNode * LinkList_Get(LINKLIST *リスト、int型のPOS);
LinkListNode * LinkList_Delete(LINKLIST *リスト、int型のPOS);
#endifの
LinkList.c
書式#include <stdio.hに>
書式#include <malloc.hを>
#include "LinkList.h"
typedefは構造体_tag_LinkList
{
LinkListNodeヘッダ。
int型の長さ。
} TLinkList。
LINKLIST * LinkList_Create()// O(1)
{
TLinkList * RET =(TLinkList *)はmalloc(はsizeof(TLinkList))。
(RET!= NULL)の場合
{
ret->長さ= 0。
ret-> header.next = NULL;
}
右を返します。
}
空LinkList_Destroy(LINKLIST *リスト)// O(1)
{
無料(リスト);
}
空LinkList_Clear(LINKLIST *リスト)// O(1)
{
TLinkList * SLIST =(TLinkList *)リスト。
(SLIST!= NULL)の場合
{
sList->長さ= 0。
sList-> header.next = NULL;
}
}
int型LinkList_Length(LINKLIST *リスト)// O(1)
{
TLinkList * SLIST =(TLinkList *)リスト。
int型RET = -1;
(SLIST!= NULL)の場合
{
RET = sList->長さ。
}
右を返します。
}
int型LinkList_Insert(LINKLIST *リスト、LinkListNode *ノード、int型のPOS)// O(n)は、
{
TLinkList * SLIST =(TLinkList *)リスト。
int型RET =(!SLIST = NULL)&&(POS> = 0)&&(ノード= NULL!)。
int型私= 0;
(RET)の場合
{
LinkListNode *電流=(LinkListNode *)SLIST。
(I = 0;(私は<POSを)&&(電流 - >次= NULL);!私は++)のために
{
現在=の電流>次。
}
ノード - >次=の電流>次。
電流 - >次=ノード。
sList->長++;
}
右を返します。
}
LinkListNode * LinkList_Get(LINKLIST *リスト、int型のPOS)// O(n)は、
{
TLinkList * SLIST =(TLinkList *)リスト。
リンクリストノード*右= NULL;
int型私= 0;
もし((SLIST!= NULL)&&(0 <= POS)&&(POS <sList->長))
{
LinkListNode *電流=(LinkListNode *)SLIST。
用(i = 0; iはPOSを<; iは++)
{
現在=の電流>次。
}
RET =の電流>次。
}
右を返します。
}
LinkListNode * LinkList_Delete(LINKLIST *リスト、int型のPOS)// O(n)は、
{
TLinkList * SLIST =(TLinkList *)リスト。
リンクリストノード*右= NULL;
int型私= 0;
もし((SLIST!= NULL)&&(0 <= POS)&&(POS <sList->長))
{
LinkListNode *電流=(LinkListNode *)SLIST。
用(i = 0; iはPOSを<; iは++)
{
現在=の電流>次。
}
RET =の電流>次。
電流>次= ret->次。
sList-> length--。
}
右を返します。
}
main.cの
書式#include <stdio.hに>
書式#include <stdlib.h>に含ま
#include "LinkList.h"
/ * / *コンソールpauserを使用してこのプログラムを実行したり、独自のgetchは、システム(「一時停止」)、または入力ループを追加
構造体の値
{
LinkListNodeヘッダ。
テレビで;
}。
(int型ARGC、チャー*のARGV [])INT主
{
int型私= 0;
LINKLIST *リスト= LinkList_Create();
構造体の値V1、
構造体の値V2。
構造体の値V3。
構造体の値V4。
構造体の値V5;
v1.v = 1。
v2.v = 2。
v3.v = 3。
v4.v = 4。
v5.v = 5;
LinkList_Insert(リスト、(LinkListNode *)&V1、LinkList_Length(リスト));
LinkList_Insert(リスト、(LinkListNode *)&V2、LinkList_Length(リスト));
LinkList_Insert(リスト、(LinkListNode *)&V3、LinkList_Length(リスト));
LinkList_Insert(リスト、(LinkListNode *)&V4、LinkList_Length(リスト));
LinkList_Insert(リスト、(LinkListNode *)&V5、LinkList_Length(リスト));
以下のための(I = 0; i)がLinkList_Length(リスト<;私は++します)
{
構造体の値* PV =(構造体バリュー*)LinkList_Get(リスト、I);
printf( "%d個の\ n" は、PV-> V);
}
しばらく(LinkList_Length(リスト)> 0)
{
構造体の値* PV =(構造体の値*)LinkList_Delete(リスト0)。
printf( "%d個の\ n" は、PV-> V);
}
LinkList_Destroy(リスト);
0を返します。
}
利点:
(1)ワンタイム能力のリストをカスタマイズする必要はありません。
(2)データ要素を移動させることなく挿入および欠失。
短所:
(3)データ要素は、後続の要素の位置情報を格納しなければなりません。
素子動作がシーケンシャルアクセスを要求する前に、(4)指定されたデータ要素を取得します。
放課後の練習
1.なぜ保存されたアドレスの特定のデータ要素を実現するためには、テーブルに?保存されたアドレスがunsigned int型ではなく、特定のポインタ型に格納されて?ボイド*なぜそうではありませんか?
2.チェーンのストレージ構造に関する次の文は正しいです
A.ストレージ構造ではないシーケンシャルアクセス構造。
隣接ノードBの物理ロジックに隣接しなければなりません。
C. III族元素は、計算によって直接I番目の要素で決定されてもよいです。
他のノードを移動することなくD.容易な挿入および削除操作、。
単一リンクリストの実装および応用3.非単ヘッダノードリストがあります。私たちがリストされている動作によれば、プログラミング
単一のリンクされたリストは、このヘッダ・ノード、およびヘッダなく達成良好と比較ヘッダの実装である方法を達成しないこと。
私たちは、単一のリストと注文テーブルを達成するため4.反転動作を追加します。動作は、リストの順序を、即ち、第1、逆転すなわち、最初の要素は最後の要素となり、第2の要素は、ダウンされるように
第二の要素の数。以下のような:ABCDは、結果の結果が逆転するリバース
DCBA。
時間計算量O(n)を達成するために必要。
SeqList_Reverse(SeqList *リスト)。
LinkList_Reverse(LINKLIST *リスト)。