靜態順序表增刪查詢操作
阿新 • • 發佈:2018-11-30
#pragma once #include <stdio.h> #include <assert.h> #include <string.h> #include <windows.h> //#ifndef __SeqList_H__ //#define __SeqList_H__ // //#endif //__SeqList_H__ //資料結構是抽象型別 //資料本身不僅僅是數字 typedef int DataType; #define MAX_SIZE 100 typedef struct SeqList{ DataType array[MAX_SIZE]; int size;//儲存的是順序表裡已經存了的資料個數 //當前可用下標 }SeqList; //介面函式 //初始化、銷燬 //增、刪、查、改 //初始化(函式設計) void SeqListInit(SeqList *pSeq) { //1 初始化 size //2 可能需要去把容器空間清理一下(一般沒有必要) /*memset(pSeq->array, 0, MAX_SIZE * sizeof(DataType));*/ assert(pSeq != NULL); pSeq->size = 0; } //銷燬 void SeqListDestroy(SeqList *pSeq) { assert(pSeq != NULL); pSeq->size = 0; } //增 //尾插(儘量和c++的STL統一) void SeqListPushBack(SeqList *pSeq, DataType data) { assert(pSeq != NULL); //特殊情況(滿了) if (pSeq->size >= MAX_SIZE) { printf("滿了\n"); assert(0);//直接崩掉 return; } //通常情況 pSeq->array[pSeq->size] = data; pSeq->size++; } //頭插 void SeqListPushFront(SeqList *pSeq, DataType data) { assert(pSeq != NULL); //特殊情況(滿了) if (pSeq->size >= MAX_SIZE) { printf("滿了\n"); assert(0);//直接崩掉 return; } //通常情況 //i代表位置 for (int i = pSeq->size; i > 0; i--) { pSeq->array[i] = pSeq->array[i - 1]; } pSeq->array[0] = data; pSeq->size++;//這裡是重點,不要忘記!!! } //插入(任意位置) void SeqListInsert(SeqList *pSeq, int pos, DataType data) { assert(pSeq); assert(pos >= 0 && pos <= pSeq->size); //特殊情況(滿了) if (pSeq->size >= MAX_SIZE) { printf("滿了\n"); assert(0);//直接崩掉 return; } //一般情況 //資料搬移 for (int i = pSeq->size; i > pos; i--) { pSeq->array[i] = pSeq->array[i - 1]; } pSeq->array[pos] = data; pSeq->size++; } //刪 //尾刪 void SeqListPopBack(SeqList *pSeq) { assert(pSeq != NULL); //特殊情況(空了) if (pSeq->size <= 0) { printf("空了\n"); assert(0);//直接崩掉 return; } //通常情況 pSeq->size--; } //頭刪 void SeqListPopFront(SeqList *pSeq) { assert(pSeq != NULL); //特殊情況(空了) if (pSeq->size <= 0) { printf("空了\n"); assert(0);//直接崩掉 return; } //通常情況 for (int i = 0; i < pSeq->size - 1; i++) { pSeq->array[i] = pSeq->array[i + 1]; } pSeq->size--; } //刪除 void SeqListErase(SeqList *pSeq, int pos) { assert(pSeq); assert(pos >= 0 && pos < pSeq->size); //特殊情況 if (pSeq->size <= 0) { printf("空了\n"); assert(0); return; } //一般情況 //資料搬移 for (int i = pos; i < pSeq->size - 1; i++) { pSeq->array[i] = pSeq->array[i + 1]; } pSeq->size--; } //查詢 //找到第一個遇到的數的下標,沒找到返回-1 int SeqListFind(SeqList *pSeq, DataType data) { //二分查詢(有序) //順序遍歷 for (int i = 0; i < pSeq->size; i++) { if (data == pSeq->array[i]) { return i; } } return -1; } //查詢帶出來的第二種形態刪除 //1 刪除遇到的第一個資料 void SeqListRemove(SeqList *pSeq, DataType data) { int pos = SeqListFind(pSeq, data);//返回的是資料的下標 if (-1 == pos) { return;//沒找到資料 } SeqListErase(pSeq, pos); } //2 刪除遇到的所有資料 void SeqListRemoveAll(SeqList *pSeq, DataType data) { /*int pos = 0; while (-1 != (pos = SeqListFind(pSeq, data))) { SeqListErase(pSeq, pos);//這種演算法速度太慢了 }*/ #if 0 //最好是一次遍歷刪除 //好處:一次遍歷,時間比較快 //壞處:開了新空間,空間大小和size有關係 //開新陣列 DataType *newArray = (DataType *)malloc(pSeq->size * sizeof(DataType)); int i, j; for (i = 0, j = 0; i < pSeq->size; i++) { if (data != pSeq->array[i]) { newArray[j] = pSeq->array[i]; j++; } } for (i = 0; i < j; i++) { pSeq->array[i] = newArray[i]; } pSeq->size = j; //釋放空間 free(newArray); #endif //第三種刪除方式 int i, j; for (i = 0, j = 0; i < pSeq->size; i++) { if (data != pSeq->array[i]) { pSeq->array[j] = pSeq->array[i]; j++; } } pSeq->size = j; } void SeqListPrint(SeqList *pSeq) { assert(pSeq); for (int i = 0; i < pSeq->size; i++) { printf("%d ", pSeq->array[i]); } printf("\n"); } //使用場景 void Test() { SeqList seqList; SeqListInit(&seqList); SeqListPushFront(&seqList, 1); SeqListPushFront(&seqList, 1); SeqListPushFront(&seqList, 1); SeqListPushFront(&seqList, 1); SeqListPushFront(&seqList, 1);//頭插 //SeqListPushBack(&seqList, 6);//尾插 //SeqListInsert(&seqList, 3, 7);//插入 //SeqListPopFront(&seqList);//頭刪 //SeqListPopBack(&seqList);//尾刪 //SeqListErase(&seqList, 3);//刪除 SeqListRemoveAll(&seqList, 1); SeqListPrint(&seqList); }