目次
序文
線形テーブルは 2 つの部分に分かれており、この記事の内容では、まずシーケンス テーブルの種類と定義、概念構造、線形テーブルの分類と関数宣言、アルゴリズムの実装について説明します。リンクリストの分類と関数宣言はスペースに起因します。この問題については、次の記事で詳しく反映します。
以下の内容は参考用です。批判や修正は大歓迎です~
提示:以下是本篇文章正文内容,下面案例可供参考
1. 線形テーブルの種類と定義
線形リストは、同じプロパティを持つ n データ要素の有限シーケンスです。
一般的な線形テーブルには、シーケンス リスト、リンク リスト、スタック、キュー、文字列などがあります。線形テーブルは論理的には線形構造、つまり連続した直線です。ただし、物理的な構造は必ずしも連続しているわけではなく、線形テーブルを物理的に保存する場合、通常は配列や連鎖構造の形で保存されます。
第二に、線形テーブルの数列テーブル
1. コンセプトと構造
順序テーブルは、連続した物理アドレスを持つ記憶装置にデータ要素を順番に格納する線形構造であり、通常は配列に格納されます。アレイ上のデータを追加、削除、確認、変更します。
2. アルゴリズムの実装
1) 静的シーケンステーブル:
要素を格納するには固定長配列を使用します。
//顺序表的静态存储 #define N 7 typedef int SLDataType; typedef struct SeqList { SLDataType array[N]; //定长数组,只能开辟宏定义中N大小的空间 size_t size; //有效数据的个数 }SeqList;
2) 動的シーケンステーブル:
動的に割り当てられた配列ストレージを使用します。(スペースが足りない場合は拡張可能)
//顺序表的动态存储 typedef struct SeqList { SLDataType* array; //指向动态开辟的数组 size_t size; //有效数据的个数 size_t capacity; //空间容量的大小 }SeqList;
静的シーケンス テーブルは、保存する必要があるデータ量がわかっているシナリオにのみ適しています。静的シーケンス テーブルの固定長配列では、N の固定サイズになり、スペースが多すぎると無駄になり、スペースが少なすぎると十分ではありません。したがって、実際には、基本的には動的シーケンス テーブルが使用され、必要に応じて領域が動的に割り当てられます。
3) インターフェースの実装
typedef int SLDataType; // 顺序表的动态存储 typedef struct SeqList { SLDataType* array; // 指向动态开辟的数组 size_t size ; // 有效数据个数 size_t capicity ; // 容量空间的大小 }SeqList; // 基本增删查改接口 // 顺序表初始化 void SeqListInit(SeqList* ps); // 检查空间,如果满了,进行增容 void CheckCapacity(SeqList* ps); // 顺序表尾插 void SeqListPushBack(SeqList* ps, SLDataType x); // 顺序表尾删 void SeqListPopBack(SeqList* ps); // 顺序表头插 void SeqListPushFront(SeqList* ps, SLDataType x); // 顺序表头删 void SeqListPopFront(SeqList* ps); // 顺序表查找 int SeqListFind(SeqList* ps, SLDataType x); // 顺序表在pos位置插入x void SeqListInsert(SeqList* ps, size_t pos, SLDataType x); // 顺序表删除pos位置的值 void SeqListErase(SeqList* ps, size_t pos); // 顺序表销毁 void SeqListDestory(SeqList* ps); // 顺序表打印 void SeqListPrint(SeqList* ps);
void SeqListInit(SL* ps);
void SeqListInit(SeqList* ps) { assert(ps); ps->a = NULL; ps->size = 0; ps->capacity = 0; }
void CheckCapacity(SeqList* ps)
void CheckCapacity(SL* ps) { assert(ps); if (ps->size == ps->capacity) { int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; SLDataType* tmp = (SLDataType*)realloc(ps->a, newCapacity*sizeof(SLDataType)); if (tmp == NULL) { perror("realloc fail"); exit(-1); } ps->a = tmp; ps->capacity = newCapacity; } }
void SeqListPushBack(SeqList* ps,SLDataType x);
void SeqListPushBack(SeqList* ps, SLDataType x) { assert(ps); // 扩容 : 21:20 if (ps->size == ps->capacity) { int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; SLDataType* tmp = (SLDataType*)realloc(ps->a, newCapacity*sizeof(SLDataType)); if (tmp == NULL) { perror("realloc fail"); exit(-1); } ps->a = tmp; ps->capacity = newCapacity; } ps->a[ps->size] = x; ps->size++; }
void SeqListPopBack(SeqList* ps)
void SeqListPopBack(SeqList* ps) { assert(ps); // 温柔的检查 /*if (ps->size == 0) { return; }*/ // 暴力的检查 assert(ps->size > 0); //ps->a[ps->size - 1] = 0; ps->size--; }
void SeqListPushFront(SeqList* ps)
void SeqListPushFront(SeqList* ps, SLDataType x) { //assert(ps); //SLCheckCapacity(ps); 挪动数据 //int end = ps->size - 1; //while (end >= 0) //{ // ps->a[end + 1] = ps->a[end]; // end--; //} //ps->a[0] = x; //ps->size++; SeqListInsert(ps, 0, x); }
void SeqListPopFront(SeqList* ps)
void SeqListPopFront(SeqList* ps) { /*assert(ps); assert(ps->size > 0); int begin = 1; while (begin < ps->size) { ps->a[begin - 1] = ps->a[begin]; begin++; } ps->size--;*/ SeqListErase(ps, 0); }
int SeqListFind(SeqList* ps, SLDataType x, int begin)
int SeqListFind(SeqList* ps, SLDataType x, int begin) { assert(ps); for (int i = begin; i < ps->size; ++i) { if (ps->a[i] == x) { return i; } } return -1; }
void SLInsert(SL* ps, int pos, SLDataType x)
void SeqListInsert(SeqList* ps, int pos, SLDataType x) { assert(ps); assert(pos >= 0); assert(pos <= ps->size); CheckCapacity(ps); int end = ps->size - 1; while (end >= pos) { ps->a[end + 1] = ps->a[end]; end--; } ps->a[pos] = x; ps->size++; }
void SeqListErase(SeqList* ps, int pos)
void SeqListErase(SeqList* ps, int pos) { assert(ps); assert(pos >= 0); assert(pos < ps->size); //assert(ps->size > 0); // 挪动数据覆盖 int begin = pos + 1; while (begin < ps->size) { ps->a[begin - 1] = ps->a[begin]; begin++; } ps->size--; }
void SeqListDestroy(SeqList* ps)
void SeqListDestroy(SeqList* ps) { assert(ps); //if (ps->a != NULL) if (ps->a) { free(ps->a); ps->a = NULL; ps->size = ps->capacity = 0; } }
void SeqListPrint(SeqList* ps)
void SeqListPrint(SeqList* ps) { assert(ps); for (int i = 0; i < ps->size; ++i) { printf("%d ", ps->a[i]); } printf("\n"); }
やっと
幸せな時間はいつも短いです。今日私が話したいのは以上です。この記事では引き続き、シャオ・ジャオ同志のアルゴリズムとデータ構造(C 言語)および線形テーブルに関する予備的な理解を簡単に紹介します。家族は批判や修正を歓迎します。Xiao Zhao同志は更新を続けています。継続的な学習の動機は、1つのボタンと3つの連続リンクによるBaoziのサポートです〜