データ構造——手順表の基本操作
6917 ワード
まず問題を見に来ます.
この問題は、順序表要素の増加、削除、検索、および順序表出力の4つの基本的な操作関数を実現することを要求します.Lは順序表で、関数Sttus ListInsert_です.Sq(SqList&L,int pos,ElemType)は、シーケンステーブルのpos位置に要素e(posは1から始まるべき)を挿入し、関数Stuts ListDelete_Sq(SqList&L,int pos,ElemType&e)は、シーケンステーブルのpos位置を削除し、参照型パラメータeで持ち帰って(posは1から)関数int ListLocate_Sq(SqList L,ElemType)は、クエリ要素eがシーケンステーブルの順位で戻ります(複数の最初の位置を取ると、戻りはビットで、1から存在しない場合は0に戻ります)、関数void ListPrint_Sq(SqList L)は、出力順序表要素である.実現にあたっては、表の拡大を考慮する必要がある.
関数インターフェースの定義:
審判試験手順の例:
入力サンプル:
一.Sttus List Insert_Sq(SqList&L,int pos,ElemType)
この関数は、Lのシーケンステーブルのpos位置にデータeを挿入することで実現される.pos位置にデータeを挿入すると、pos位置の後のすべての要素が後ろに移動します.幸い、posというところが空いているので、データeを入れます.そこで私達はまず一つのfor循環を使って、もとのpos位置とその後の元素を後ろに1つ移動させて、その後pos位置にデータeを挿入すればいいという考えを持ち始めました.しかし、私たちも考えたいのですが、シーケンステーブルの要素の個数、つまりL.lengthの数値は最初に設定された上限に達しています.
コード実現とは:
はい、一番難しい関数はもう解決しました.残りは全部簡単です.
この関数が実現したのは、シーケンステーブルの第posビットの要素を削除します.これは私達に思わず第一の増加の効果を思い付かせて、しかし削除するのは増加するよりずっと簡単で、拡張の問題を考慮する必要はありません.だから、pos位置以降の要素を一つずつ前に移動させるだけでいいです.ただし、参照の形でデータeに戻りますので、eに値を付けてから削除操作を行います.同様に、posは>=1であり、配列は0から始まるので、配列中のpos番目の数は【pos-1】としてマークされます.
コードの実装は以下の通りです.
この関数は検索機能であり、このデータがあると戻りがいくつか目になり、複数があると最初のこの数の位置数に戻ります.存在しないなら、NOT FOUNDに戻ります.まず数aを定義して、位置の数を表します.なお、位置数は1から始まり、順序表は0から始まります.2番目の数は、順序表の下に1として表示されます.したがって、戻る時はaを+1操作します.また、見つけられない場合がありますので、先にaを初値にしてもいいです.aの値が初値でない場合、存在を説明します.aがまだ初値であるなら、この数が存在すると説明します.
コードの実装は以下の通りです.
この関数が実装されるのはシーケンステーブルの出力です.最後の数だけ注意してください.後ろにスペースがないだけでいいです.
コードの実装:
この問題は、順序表要素の増加、削除、検索、および順序表出力の4つの基本的な操作関数を実現することを要求します.Lは順序表で、関数Sttus ListInsert_です.Sq(SqList&L,int pos,ElemType)は、シーケンステーブルのpos位置に要素e(posは1から始まるべき)を挿入し、関数Stuts ListDelete_Sq(SqList&L,int pos,ElemType&e)は、シーケンステーブルのpos位置を削除し、参照型パラメータeで持ち帰って(posは1から)関数int ListLocate_Sq(SqList L,ElemType)は、クエリ要素eがシーケンステーブルの順位で戻ります(複数の最初の位置を取ると、戻りはビットで、1から存在しない場合は0に戻ります)、関数void ListPrint_Sq(SqList L)は、出力順序表要素である.実現にあたっては、表の拡大を考慮する必要がある.
関数インターフェースの定義:
Status ListInsert_Sq(SqList &L, int pos, ElemType e);
Status ListDelete_Sq(SqList &L, int pos, ElemType &e);
int ListLocate_Sq(SqList L, ElemType e);
void ListPrint_Sq(SqList L);
ここでLは順番表です.posは位置ですe元素を表します.挿入と削除操作中のposパラメータが不正な場合、関数はERRORに戻ります.そうでなければOKに戻ります.審判試験手順の例:
//
#include
#include
#include
//
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
//
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
typedef int ElemType; //
typedef struct{
ElemType* elem; //
int length; //
int listsize; //
}SqList; //
Status ListInsert_Sq(SqList &L, int pos, ElemType e);
Status ListDelete_Sq(SqList &L, int pos, ElemType &e);
int ListLocate_Sq(SqList L, ElemType e);
void ListPrint_Sq(SqList L);
//
Status InitList_Sq(SqList &L){
// L
L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L.elem)exit(OVERFLOW);
L.listsize=LIST_INIT_SIZE;
L.length=0;
return OK;
}
int main() {
SqList L;
if(InitList_Sq(L)!= OK) {
printf("InitList_Sq: !!!
");
return -1;
}
for(int i = 1; i <= 10; ++ i)
ListInsert_Sq(L, i, i);
int operationNumber; //
scanf("%d", &operationNumber);
while(operationNumber != 0) {
int operationType; //
scanf("%d", & operationType);
if(operationType == 1) { //
int pos, elem;
scanf("%d%d", &pos, &elem);
ListInsert_Sq(L, pos, elem);
} else if(operationType == 2) { //
int pos; ElemType elem;
scanf("%d", &pos);
ListDelete_Sq(L, pos, elem);
printf("%d
", elem);
} else if(operationType == 3) { //
ElemType elem;
scanf("%d", &elem);
int pos = ListLocate_Sq(L, elem);
if(pos >= 1 && pos <= L.length)
printf("%d
", pos);
else
printf("NOT FIND!
");
} else if(operationType == 4) { //
ListPrint_Sq(L);
}
operationNumber--;
}
return 0;
}
/* */
入力フォーマット:1行目は整数のoperationNumberを入力して、操作数を表します.次にoperation Number行で、1行に1つの操作情報(「操作種類番号操作内容」を含みます.)を表します.番号は1で挿入操作を示し、後の2つのパラメータは挿入の位置と挿入の要素値番号は2で削除操作を示し、後の一つのパラメータは削除の位置番号は3で検索動作を表し、後の一つのパラメータは検索の値番号は4で順序表出力操作を表します. 出力フォーマット:操作2に対して、削除された要素の値を出力します.操作3に対して、その要素の位置を出力します.この要素が存在しない場合は、「NOT FOUND」を出力します.4を操作する場合、順序表全体の要素を順次出力します.二つの要素の間はスペースで区切られています.最後の要素の後ろにはスペースがありません.入力サンプル:
4
1 1 11
2 2
3 3
4
出力例:1
3
11 2 3 4 5 6 7 8 9 10
テーマの内容によって、このプログラムの主関数と必要な声明が出されました.私達が自分で充填するのがSttus ListInsert_です.Sq(SqList&L,int pos,ElemType)、Sttus ListDelete_Sq(SqList&L,int pos,ElemType&e)、int ListLocate_Sq(SqList L,ElemType)とvoid ListPrint_Sq(SqList L)の4つの関数の具体的な内容.私たちは一人ずつ見に来ます.一.Sttus List Insert_Sq(SqList&L,int pos,ElemType)
この関数は、Lのシーケンステーブルのpos位置にデータeを挿入することで実現される.pos位置にデータeを挿入すると、pos位置の後のすべての要素が後ろに移動します.幸い、posというところが空いているので、データeを入れます.そこで私達はまず一つのfor循環を使って、もとのpos位置とその後の元素を後ろに1つ移動させて、その後pos位置にデータeを挿入すればいいという考えを持ち始めました.しかし、私たちも考えたいのですが、シーケンステーブルの要素の個数、つまりL.lengthの数値は最初に設定された上限に達しています.
#define LIST_INIT_SIZE 100
この行で定義されているLIST_INIT_SIZEの個数については、まず拡大してから各データを後ろに移動させる作業が必要です.さもないと境界を超えます.ですから、拡大が必要かどうかを判断します.また、与えられたposが本来L.engthの制限を超えていたら、エラーに戻ります.第pos位がないからです.また、注意しなければならない点は、posは>=1であり、配列は0から始まるので、pos番目の数は配列中の下に「pos-1」と表示されます.コード実現とは:
Status ListInsert_Sq(SqList &L, int pos, ElemType e) { ElemType *newbase;// if(pos >= 1&&pos <= L.length + 1)// pos L.length { if(L.length >= L.listsize)// L.length , { newbase = (ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT) * sizeof(ElemType));// newbase LISTINCREMENT if(!newbase)// return ERROR; L.elem = newbase;// L.listsize += LISTINCREMENT;// } ElemType *p,*q; p = &(L.elem[pos - 1]);// pos p for(q = &(L.elem[L.length - 1]);q >= p;--q) { *(q + 1) = *q; }// q, *p = e;// e pos ++L.length;// return OK; } else return OVERFLOW; }
二.Sttus ListDelete_Sq(SqList&L,int pos,ElemType&e)はい、一番難しい関数はもう解決しました.残りは全部簡単です.
この関数が実現したのは、シーケンステーブルの第posビットの要素を削除します.これは私達に思わず第一の増加の効果を思い付かせて、しかし削除するのは増加するよりずっと簡単で、拡張の問題を考慮する必要はありません.だから、pos位置以降の要素を一つずつ前に移動させるだけでいいです.ただし、参照の形でデータeに戻りますので、eに値を付けてから削除操作を行います.同様に、posは>=1であり、配列は0から始まるので、配列中のpos番目の数は【pos-1】としてマークされます.
コードの実装は以下の通りです.
Status ListDelete_Sq(SqList &L, int pos, ElemType &e) { if(pos >= 1&&pos <= L.length)// pos { ElemType *q; e = L.elem[pos - 1];// e , for(q = &(L.elem[pos - 1]);q <=&(L.elem[L.length - 1]);++q) { *q = *(q + 1); }// pos L.length = L.length - 1;//L } else return OVERFLOW; }
三.int ListLocate_Sq(SqList L,ElemType)この関数は検索機能であり、このデータがあると戻りがいくつか目になり、複数があると最初のこの数の位置数に戻ります.存在しないなら、NOT FOUNDに戻ります.まず数aを定義して、位置の数を表します.なお、位置数は1から始まり、順序表は0から始まります.2番目の数は、順序表の下に1として表示されます.したがって、戻る時はaを+1操作します.また、見つけられない場合がありますので、先にaを初値にしてもいいです.aの値が初値でない場合、存在を説明します.aがまだ初値であるなら、この数が存在すると説明します.
コードの実装は以下の通りです.
int ListLocate_Sq(SqList L, ElemType e) { int a = -1;// a , , -1 , -1 for(int i = 0;i <= L.length -1;i++) { if(L.elem[i] == e) { a = i; break; } }//for if(a >= 0&&a <= L.length -1) return a + 1;// a , a else return ERROR;// a , 。 }
四.void ListPrint_Sq(SqList L)この関数が実装されるのはシーケンステーブルの出力です.最後の数だけ注意してください.後ろにスペースがないだけでいいです.
コードの実装:
void ListPrint_Sq(SqList L) { for(int i = 0;i <= L.length - 2;i++) { printf("%d ",L.elem[i]); } printf("%d",L.elem[L.length -1]); }