この記事では主に、線形テーブルの追加と削除操作、順次ストレージ構造、およびこの記事のコードなど、線形テーブルに関連する理論と例を紹介します。
目次
リニアテーブル
線形テーブル、完全な名前は線形ストレージ構造です。これは非常に重要なタイプのデータ構造であり、最も一般的に使用され、最も単純です。
線形テーブルの定義
0 個以上のデータ要素の有限シーケンス
線形テーブル内のデータ要素間の関係は 1 対 1 の関係です。つまり、最初と最後のデータ要素を除いて、他のデータ要素はエンド ツー エンドで接続されています。
注 1: この文は、すべてではなく、ほとんどの線形テーブルにのみ適用されます。たとえば、循環リスト (後述) も論理レベルでは線形リストです (ストレージ レベルではチェーン ストレージに属しますが、最後のデータ要素のテール ポインターは最初のノードを指します)。
注 2: 前述のことを振り返ると、データ要素は必ずしも最小単位ではなく、データ要素は複数のデータ項目で構成される場合があります。
注 3: 線形テーブルの要素数 n は線形テーブルの長さと定義され、n=0 の場合は空テーブルと呼ばれます。
線形テーブルの抽象データ型
リニアテーブルの定義を知って、リニアテーブル薬局はどのような業務を行っていますか? まず、一般的な基本操作に慣れることができます: (一般的な理解を得て、記事をブックマークして、使用するときにそれらを読んでください)
- MakeEmpty(L) Lを空リストにするメソッドです
- Length(L) は、テーブル L の長さ、つまり、テーブル内の要素の数を返します。
- Get(L,i) L の i 番目の要素を値とする関数 (1≤i≤n)
- Prior(L, i) は i の先行要素を取ります
- Next(L, i) は i の後続要素を取ります
- Locate(L, x) これは、値が L 内の要素 x の位置である関数です。
- Insert(L, i, x) 要素 x をテーブル L の i 番目の位置に挿入し、最初に i 番目の位置を占めていた要素と次の要素を 1 桁分戻します。
- Delete(L,p) はリスト L から位置 p の要素を削除します
- IsEmpty(L) は、テーブル L が空のテーブル (長さが 0) の場合に true を返し、それ以外の場合は false を返します。
- Clear(L) すべての要素をクリアします
- 初期化 (L) は最初のものと同じで、初期化線形テーブルは空です
- Traverse(L) すべての要素をトラバースして出力します
- Find(L, x) 要素を見つけて返します
- Update(L, x) は要素を変更します
- Sort(L) は、指定された条件に従ってすべての要素を並べ替えます
- strstr(string1, string2) は、文字配列内の string1 内の string2 の最初のアドレスを見つけるために使用されます
線形テーブル順次ストレージ構造
線形テーブルには 2 つの物理構造がありますが、ここではまず単純な順次ストレージについて説明します。
意味
線形テーブルのデータ要素は、連続したアドレスを持つ記憶装置に順次格納されます。
1対1の 論理関係でデータを物理空間全体に順次格納する格納構造が順次格納構造である。
順次ストレージ
順次ストレージ構造コードを見てください。
#define MAXSIZE 20 /* 存储空间初始分配量 */
typedef int ElemType; /* ElemType类型根据实际情况而定,这里假设为int */
typedef struct
{
ElemType data[MAXSIZE]; /* 数组,存储数据元素 */
int length; /* 线性表当前长度 */
}SqList;
したがって、配列の長さは必ずしも線形テーブルの長さと同じではありません。線形テーブルの長さは、配列の長さ以下にする必要があります。
/* 初始化顺序线性表 */
Status InitList(SqList *L)
{
L->length=0;
return OK;
}
/* 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
Status ListEmpty(SqList L)
{
if(L.length==0)
return TRUE;
else
return FALSE;
}
/* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */
Status ClearList(SqList *L)
{
L->length=0;
return OK;
}
/* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
int ListLength(SqList L)
{
return L.length;
}
順次ストレージ構造操作
要素を取得
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:用e返回L中第i个数据元素的值,注意i是指位置,第1个位置的数组是从0开始 */
Status GetElem(SqList L,int i,ElemType *e)
{
if(L.length==0 || i<1 || i>L.length)
return ERROR;
*e=L.data[i-1];
return OK;
}
表示要素
/* 初始条件:顺序线性表L已存在 */
/* 操作结果:依次对L的每个数据元素输出 */
Status ListTraverse(SqList L)
{
int i;
for(i=0;i<L.length;i++)
visit(L.data[i]);
printf("\n");
return OK;
}
挿入操作
一緒に考えてみましょう:
- 線形テーブルの長さは配列の長さより大きくすることはできません
- 処理できるように不合理な例外を挿入する
- 挿入位置以降のすべての要素が後方に移動されます
- 要素を挿入
- テーブルの長さ +1
C 言語コードは次のとおりです。
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert(SqList *L,int i,ElemType e)
{
int k;
if (L->length==MAXSIZE) /* 顺序线性表已经满 */
return ERROR;
if (i<1 || i>L->length+1)/* 当i比第一位置小或者比最后一位置后一位置还要大时 */
return ERROR;
if (i<=L->length) /* 若插入数据位置不在表尾 */
{
for(k=L->length-1;k>=i-1;k--) /* 将要插入位置之后的数据元素向后移动一位 */
L->data[k+1]=L->data[k];
}
L->data[i-1]=e; /* 将新元素插入 */
L->length++;
return OK;
}
削除操作
アイデア:
- 理不尽な例外を処理できる
- 要素を削除
- 削除された要素の次の要素が 1 つ前に移動します
- テーブルの長さ-1
C 言語コードは次のとおりです。
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
Status ListDelete(SqList *L,int i,ElemType *e)
{
int k;
if (L->length==0) /* 线性表为空 */
return ERROR;
if (i<1 || i>L->length) /* 删除位置不正确 */
return ERROR;
*e=L->data[i-1];
if (i<L->length) /* 如果删除不是最后位置 */
{
for(k=i;k<L->length;k++)/* 将删除位置后继元素前移 */
L->data[k-1]=L->data[k];
}
L->length--;
return OK;
}
高度な操作
線形リスト Lb にあるが La にはないすべてのデータ要素を La に挿入します
上記の操作を組み合わせて考えてみましょう。コードは次のようになります。
void unionL(SqList *La,SqList Lb)
{
int La_len,Lb_len,i;
ElemType e; /*声明与La和Lb相同的数据元素e*/
La_len=ListLength(*La); /*求线性表的长度 */
Lb_len=ListLength(Lb);
for (i=1;i<=Lb_len;i++)
{
GetElem(Lb,i,&e); /*取Lb中第i个数据元素赋给e*/
if (!LocateElem(*La,e)) /*La中不存在和e相同数据元素*/
ListInsert(La,++La_len,e); /*插入*/
}
}
いいね、収集、コメント欄へのコメントを歓迎し、ソースを示すために転載してください。
------------------------------
上記のリンク:
以下のリンク:
アルゴリズムとデータ構造 - 線形テーブルとその連鎖ストレージ構造。https://blog.csdn.net/qq_52213943/article/details/125824927