ホームページ:
探索を待っている未知の領域がまだある_小規模プロジェクト、羅谷クイズ、データ構造 - CSDN ブログ
トピック列---データ構造:
目次
最初のステップは、シーケンス テーブル タイプを作成することです。
2 番目のステップは、シーケンス テーブルを定義して初期化することです。
1. 知識の蓄え
私たちが以前に学んだC言語やJAVA言語などの高級言語では、文法、逐次構造、選択構造、ループ構造、そしてそれらの3つの構造と文法を通して問題を解決するためのコードの書き方について話していました。
現在、データ構造では、データの論理構造とデータの物理構造、およびそれらの間の関係を研究し、この構造に適切な操作を定義し、対応するアルゴリズムを設計し、これらの操作後に結果として得られる新しい構造が元の構造タイプを維持していることを確認します。 。
データ構造は、線形テーブル、ツリー、グラフの 3 つのカテゴリに大別できます。これら 3 つのカテゴリには、基本的にシーケンシャル ストレージ構造とチェーン ストレージ構造があります。この記事は主に、線形テーブルのシーケンシャル テーブルのシーケンシャル ストレージ構造について説明します。
二、引例
逐次表の逐次記憶構造とは、線形表のすべてのデータ要素が論理的な順序で連続した記憶単位群に記憶されることを意味し、この記憶形式で記憶された線形表が逐次表となる。その特徴は、論理的に隣接する 2 つのデータ要素が物理的にも隣接していることです。
学生情報シート
学籍番号 名前 得点 1 2022123 張三 90 2 2022124 李思 95 3 2022125 王呉 85上の学生情報テーブルと同様に、このテーブルをどのように保存しますか? この情報を人物を記述する構造体に直接保存してから、保存用の構造体配列を定義する必要があるでしょうか?
struct student { int num;//学号 char name[20];//姓名 int score;//成绩 };
#define MAX 3 struct student s[MAX]; for(int i=0;i<MAX;i++) { scanf("%d",&s[i].num); char name[20]; scanf("%s",name); strcpy(s[i].name,name); scanf("%d",&s[i].score); }
上記のように保存されるのでしょうか?
3. シーケンステーブル
最初のステップは、シーケンス テーブル タイプを作成することです。
#define MAX 100 typedef struct { int num; char name[20]; int score; }elemtype; typedef struct LNode { elemtype data[MAX]; int last; }List;
誰もが、define が定数 MAX を定義し、その値を 100 に設定することを知っているはずです。次に、次のセクションで出現する 100 はすべて MAX に置き換えられます。このようにして、数値を変更する (配列を拡張する) 場合は、define で変更を直接定義することができ、データを変更するという面倒な手順を回避できます。
typedef は、データ型の名前を変更できる名前変更キーワードです。
シーケンス リスト構造を定義する場合、内部の配列も構造型として定義され、必要なデータ型がすべてその中に配置されます。
2 番目のステップは、シーケンス テーブルを定義して初期化することです。
List* ListInit() { List* L; L = (List*)malloc(sizeof(List)); L->last = -1; return L; }
L->lastに-1を代入し、データ入力時にL->last++を設定しますが、このL->lastには実際には配列の最後の要素の添字が格納されます。テーブル長が 0 の場合、その値は -1 になります。
第三段階 シーケンステーブルの基本操作
1.挿入(増加)
初期化された空のシーケンステーブルにデータを順次追加していく操作。
シーケンス テーブルに記入されたデータは、1 つおきではなく、連続して保存する必要があることに注意してください。
List* ListInsert(List* L) { int P;//插入的位置,从0开始 //插入的元素 int num, score; char name[20]; scanf("%d%d", &P, &num); scanf("%s", name); scanf("%d", &score); if (P<0 || P>L->last+1)//大于L->last+1是因为,数据可以插在顺序表的最后一个元素的后面 { printf("坐标非法\n"); } else { for (int i = L->last; i >= P; i--) { L->data[i + 1].num = L->data[i].num; L->data[i + 1].score = L->data[i].score; strcpy(L->data[i + 1].name, L->data[i].name); } L->data[P].num = num; L->data[P].score = score; strcpy(L->data[P].name, name); L->last++; } }
if (P<0 || P>L->last+1)//大于L->last+1是因为,数据可以插在顺序表的最后一个元素的后面
この声明は、データを継続的に保存できるようにするためのものです。P<0 の場合、座標は不正です。P>L->last+1 は、挿入されたデータを元のシーケンス テーブルに接続します。
2.削除
削除とは、指定した場所のデータを削除することです。
List* Listdelete(List* L) { int P;//删除位置,从0开始 scanf("%d", &P); if (L->last == -1) { printf("顺序表为空,无法删除\n"); } else { if (P<0 || P>L->last) printf("坐标非法\n"); else { for (int i = P; i < L->last; i++) { L->data[i].num = L->data[i + 1].num; L->data[i].score = L->data[i + 1].score; strcpy(L->data[i].name, L->data[i + 1].name); } L->last--; } } return L; }
3.取る
指定した位置の要素を取得する
int ListGet(List* L) { int P;//取指定位置,从0开始 scanf("%d", &P); if (P<0 || P>L->last) { printf("坐标非法\n"); return -1; } else { return P; } }
4.チェック
シーケンステーブルに要素があるかどうかを調べ、見つかった場合は添え字を返し、そうでない場合は-1を返します。
int ListSearch(List* L) { int X;//查找的数据 scanf("%d", &X); for (int i = 0; i <= L->last; i++) { if (X == L->data[i].num) return i; } return -1; }
5. リンクリストの長さを計算する
最後の要素の添字を格納する L->last によって計算されます。
int ListLength(List* L) { return L->last + 1; }
4. 完全な配列リスト
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 5
typedef struct
{
int num;
char name[20];
int score;
}elemtype;
typedef struct LNode
{
elemtype data[MAX];
int last;
}List;
List* ListInit();
List* ListInsert(List* L);
List* Listdelete(List* L);
int ListGet(List* L);
int ListSearch(List* L);
int ListLength(List* L);
int main()
{
List* L;
L = ListInit();
int n;//插入数据的个数
scanf("%d", &n);
while (n--)
{
L = ListInsert(L);
if (L->last == MAX - 1)
{
printf("顺序表已满,无法插入数据\n");
break;
}
}
L = Listdelete(L);
int s=ListGet(L);
if (s != -1)
{
printf("%d %s %d\n", L->data[s].num, L->data[s].name, L->data[s].score);
}
int s=ListSearch(L);
if (s != -1)
{
printf("找到了,下标为%d\n", s);
}
else
{
printf("未找到\n");
}
int len=ListLength(L);
printf("%d", len);
return 0;
}
List* ListInit()
{
List* L;
L = (List*)malloc(sizeof(List));
L->last = -1;
return L;
}
List* ListInsert(List* L)
{
int P;//插入的位置
//插入的元素
int num, score;
char name[20];
scanf("%d%d", &P, &num);
scanf("%s", name);
scanf("%d", &score);
if (P<0 || P>L->last+1)//大于L->last+1是因为,数据可以插在顺序表的最后一个元素的后面
{
printf("坐标非法\n");
}
else
{
for (int i = L->last; i >= P; i--)
{
L->data[i + 1].num = L->data[i].num;
L->data[i + 1].score = L->data[i].score;
strcpy(L->data[i + 1].name, L->data[i].name);
}
L->data[P].num = num;
L->data[P].score = score;
strcpy(L->data[P].name, name);
L->last++;
}
return L;
}
List* Listdelete(List* L)
{
int P;//删除位置
scanf("%d", &P);
if (L->last == -1)
{
printf("顺序表为空,无法删除\n");
}
else
{
if (P<0 || P>L->last)
printf("坐标非法\n");
else
{
for (int i = P; i < L->last; i++)
{
L->data[i].num = L->data[i + 1].num;
L->data[i].score = L->data[i + 1].score;
strcpy(L->data[i].name, L->data[i + 1].name);
}
L->last--;
}
}
return L;
}
int ListGet(List* L)
{
int P;//取指定位置
scanf("%d", &P);
if (P<0 || P>L->last)
{
printf("坐标非法\n");
return -1;
}
else
{
return P;
}
}
int ListSearch(List* L)
{
int X;//查找的数据
scanf("%d", &X);
for (int i = 0; i <= L->last; i++)
{
if (X == L->data[i].num)
return i;
}
return -1;
}
int ListLength(List* L)
{
return L->last + 1;
}
ご協力ありがとうございます!!相互励まし合います!