線性表的順序儲存-順序表,對“突然的自我”的否定,對自我的揚棄

yjhqukq發表於2020-12-18

在上篇部落格中,儘管順序表的功能已經實現了,但是用了好多自己的野路子,程式碼也不是很優雅,很直觀。
於是我的內心便產生了兩種想法:“把部落格刪掉,重新寫”或者“把部落格的程式碼換掉也就能省去很多精力”,思前想後,我決定還是保留下來,儘管程式碼有些許自己的野路子,但這也是我的心血,是我成長的見證。
這一次的順序表,與上次的順序表相比,功能相差無幾,操作也幾乎相同,在操作選單做了些改善,操作的反饋感很直接。
不說廢話了,直接看效果圖
1.順序表的初始化過程
在這裡插入圖片描述

2.遍歷順序表
在這裡插入圖片描述

3.為順序表追加元素
在這裡插入圖片描述

4.刪除順序表的某個元素
在這裡插入圖片描述

5.為順序表插入元素
在這裡插入圖片描述

6.通過下標,修改順序表某個元素的值
在這裡插入圖片描述

7.通過下標獲取順序表對應元素的值
在這裡插入圖片描述

8.通過元素的值獲取順序表對應元素的下標
在這裡插入圖片描述

9.逆轉順序表
在這裡插入圖片描述

10.為順序表排序
在這裡插入圖片描述

11.清空順序表
在這裡插入圖片描述
執行效果圖展示完畢!


關於程式碼的編寫,我在程式碼中都作了相關解釋, 如果有不足的地方,請私信告知我,我一定加以改善!

附程式碼

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>

#define MAXSIZE 6//順序表的最大長度
#define SPAN 35;//選單的水平跨度
#define VerticalGap 1//選單的垂直間距,1就是一個換行,2就是兩個換行
#define OK 1
#define ERROR -1
typedef struct ArrayList {
    int *origin;//資料的來源,在結構體初始化後,與一段連續的記憶體單元建立聯絡,並操作這一塊記憶體單元
    int length;//順序表的最大長度,記錄順序表的最大容量,能存放多少個元素
    int counter;//順序表的計數器,記錄當前元素的個數
} *ListPointer, List;

ListPointer initialize();//初始化順序表
void manifest(ListPointer lp);//遍歷順序表
int sort(ListPointer lp);//為順序表排序
int inverse(ListPointer lp);//將順序表倒置
int append(ListPointer lp, int value);//為順序表追加元素,也就是在順序表末尾新增一個元素
int insert(ListPointer lp, int position, int value);//在順序表指定的位置下插入一個值
int delete(ListPointer lp, int position);//刪除順序表中某一元素的值
int modify(ListPointer lp, int position, int value);//修改表中的某一元素值
int getNode(ListPointer lp, int position, int *value);//通過元素下標獲取元素值,如果成功獲取返回1,否則返回-1
int locateNode(ListPointer lp, int value);//通過元素的值獲取元素下標。若元素不存在或順序表為空,則返回-1;若元素存在,則返回下標。
void clear(ListPointer lp);//清空順序表
int isEmpty(ListPointer lp);//判斷順序表是否為空
int isFull(ListPointer lp);//判斷順序表是否已滿
void inputData(int *data, char *dataExplanation);//錄入資料,因為要反覆使用scanf和printf這兩個函式,乾脆做一個提取
void prompt(char *prompt);//運用了字串和指標的知識,對printf的簡單封裝
void menu(char **menu, int length);//動態地輸出選單
void duplicate(int size, char token);//給出一個整數size和一個字元型符號token,輸出size個token,不換行
int main() {
    char *operatingMenu[] = {"ArrayList",
                             "1.reinitialize list", "2.present list", "3.append element",
                             "4.delete element", "5.insert element", "6.modify element",
                             "7.get element", "8.locate element", "9.sort", "10.inverse",
                             "11.clear list", "12.exit"};
    int length = sizeof(operatingMenu) / sizeof(char *);
    int indicator, position, value, status;
    ListPointer lp = NULL;
    lp = initialize();
    while (1) {
        system("cls");
        menu(operatingMenu, length);
        if (lp == NULL || isEmpty(lp)) {
            printf("The List Is Empty.Data are required!\n");
        } else {
            printf("The MAX LENGTH:\t%d\n", MAXSIZE);
            printf("CURRENT TOTAL:\t%d\n", lp->counter);
            manifest(lp);
        }
        inputData(&indicator, "type in number:\t");
        switch (indicator) {
            case 1:
                free(lp->origin);//銷燬順序表內的所有結點
                free(lp);//銷燬順序表外殼
                lp = initialize();//重新初始化一個順序表
                break;
            case 2:
                manifest(lp);
                system("pause");
                break;
            case 3: {
                inputData(&value, "VALUE:");
                status = append(lp, value);
                (status == OK) ? manifest(lp) : prompt("check out and try again!");
                system("pause");
                break;
            }
            case 4: {
                inputData(&position, "POSITION:");
                status = delete(lp, position);
                (status == OK) ? manifest(lp) : prompt("check out and try again!");
                system("pause");
                break;
            }
            case 5:
                inputData(&position, "POSITION:");
                inputData(&value, "VALUE:");
                status = insert(lp, position, value);
                (status == OK) ? manifest(lp) : prompt("check out and try again!");
                system("pause");
                break;
            case 6:
                inputData(&position, "POSITION:");
                inputData(&value, "VALUE:");
                status = modify(lp, position, value);
                (status == OK) ? manifest(lp) : prompt("check out and try again!");
                system("pause");
                break;
            case 7:
                inputData(&position, "POSITION:");
                status = getNode(lp, position, &value);
                (status == OK) ? printf("VALUE: %d\n", value) : prompt("check out and try again!");
                system("pause");
                break;
            case 8:
                inputData(&value, "VALUE:");
                position = locateNode(lp, value);
                (position == ERROR) ? prompt("check out and try again!") : printf("POSITION:%d\n", position);
                system("pause");
                break;
            case 9:
                status = sort(lp);
                (status == OK) ? manifest(lp) : prompt("check out and try again!");
                system("pause");
                break;
            case 10:
                status = inverse(lp);
                (status == OK) ? manifest(lp) : prompt("check out and try again!");
                system("pause");
                break;
            case 11:
                clear(lp);
                system("pause");
                break;
            case 12:
                free(lp->origin);//銷燬順序表,
                free(lp);
                exit(-1);//退出
        }
    }
}

ListPointer initialize() {
    ListPointer lp = (ListPointer) malloc(sizeof(List));
    lp->length = MAXSIZE;
    lp->origin = (int *) malloc(sizeof(int) * lp->length);
    if (lp == NULL || lp->origin == NULL) {
        prompt("Failed To Allocate Memory!");
        exit(-1);
    }
    lp->counter = 0;
    int length;
    inputData(&length, "The length of List(0<length<6):");
    if (length <= 0 || length > lp->length)
        exit(-1);
    for (int i = 0; i < length; ++i) {
        printf("element %d:", i + 1);
        scanf("%d", lp->origin + i);
        ++lp->counter;
    }
    return lp;
}

void manifest(ListPointer lp) {
    if (isEmpty(lp)) {
        prompt("The List Is Empty");
        return;
    }
    printf("{");
    for (int i = 0; i < lp->counter; ++i) {
        if (i < lp->counter - 1)
            printf("%d\t", lp->origin[i]);
        else
            printf("%d", *(lp->origin + i));
    }
    printf("}\n");
}

int sort(ListPointer lp)//這裡選用插入排序
{
    if (isEmpty(lp)) {
        prompt("The List Is Empty!");
        prompt("Don't allow to sort!");
        return ERROR;
    }
    int retreat, shirley;
    for (int i = 1; i < lp->counter; ++i) {
        shirley = lp->origin[i];
        for (retreat = i - 1; retreat >= 0 && shirley < lp->origin[retreat]; --retreat) {
            lp->origin[retreat + 1] = lp->origin[retreat];
        }
        lp->origin[retreat + 1] = shirley;
    }
    printf("Sorting is completed!\n");
    return OK;
}

int inverse(ListPointer lp) {
    if (isEmpty(lp)) {
        prompt("The List Is Empty!");
        prompt("Don't allow to inverse!");
        return ERROR;
    }
    int exchange, temp;
    int end = lp->counter / 2;
    for (int i = 0; i < end; ++i) {
        exchange = lp->counter - 1 - i;
        temp = lp->origin[i];
        lp->origin[i] = lp->origin[exchange];
        lp->origin[exchange] = temp;
    }
    prompt("Inverse is completed!");
    return OK;
}

int append(ListPointer lp, int value) {
    if (isFull(lp)) {
        prompt("The List Is Full!");
        return ERROR;
    }
    lp->origin[lp->counter] = value;
    ++lp->counter;
    return OK;
}

int insert(ListPointer lp, int position, int value) {
    if (isFull(lp)) {
        prompt("The List Is Full!");
        return ERROR;
    }
    if (isEmpty(lp)) {
        prompt("The List Is Empty!");
        return ERROR;
    }
    if (position <= 0 || position > lp->counter) {
        prompt("INVALID POSITION!");
        return ERROR;
    }
    lp->counter++;
    for (int i = lp->counter; i > position; --i) {
        lp->origin[i - 1] = lp->origin[i - 2];
    }
    lp->origin[position - 1] = value;
    prompt("The element is inserted completely!");
    return OK;
}

int delete(ListPointer lp, int position) {
    if (isEmpty(lp)) {
        prompt("The List Is Empty!");
        return ERROR;
    }
    if (position <= 0 || position > lp->counter) {
        prompt("INVALID POSITION!");
        return ERROR;
    }
    //陣列的下標是從0開始計數的,但在實際生活我們習慣於從1開始計數
    //於是我在未涉及陣列操作時,還是按照生活中的習慣進行思考,在對陣列正式操作時,對其下標進行適當地減1操作
    for (int i = position; i < lp->counter; ++i) {
        lp->origin[i - 1] = lp->origin[i];
    }
    --lp->counter;
    prompt("The element is deleted successfully!");
    return OK;
}

int modify(ListPointer lp, int position, int value) {
    if (isEmpty(lp)) {
        prompt("The List Is Empty!");
        return ERROR;
    }
    if (position <= 0 || position > lp->counter) {
        prompt("INVALID POSITION!");
        return ERROR;
    }
    lp->origin[position - 1] = value;
    prompt("The modification is completed!");
    return OK;
}

int getNode(ListPointer lp, int position, int *value) {
    if (isEmpty(lp)) {
        prompt("The List Is Empty!");
        return ERROR;
    }
    if (position <= 0 || position > lp->counter) {
        prompt("INVALID POSITION!");
        return ERROR;
    }
    *value = lp->origin[position - 1];
    return OK;
}

int locateNode(ListPointer lp, int value) {
    if (isEmpty(lp)) {
        prompt("The List Is Empty!");
        return ERROR;
    }
    for (int i = 0; i < lp->counter; ++i) {
        if (lp->origin[i] == value) {
            return i + 1;
        }
    }
    prompt("The element you are looking for doesn't exist!");
    return ERROR;
}

void clear(ListPointer lp) {
    if (lp->counter == 0) {
        prompt("There is no need to clear!");
        return;
    }
    lp->counter = 0;
    printf("The List Was Cleared.\n");
}

int isEmpty(ListPointer lp) {
    return lp->counter == 0 ? 1 : 0;
}

int isFull(ListPointer lp) {
    return lp->counter == lp->length ? 1 : 0;
}

void inputData(int *data, char *dataExplanation) {
    printf("%s", dataExplanation);
    scanf("%d", data);
}

void prompt(char *prompt) {
    printf("%s\n", prompt);
}

void menu(char **origin, int length) {
    int span = SPAN;
    int gapLength;
    duplicate(span, '*');
    duplicate(1, '\n');
    for (int i = 0; i < length; ++i) {
        duplicate(1, '*');
        gapLength = span - (strlen(*(origin + i))) - 2;
        duplicate(gapLength / 2, ' ');
        printf("%s", origin[i]);
        if (gapLength % 2 == 0) {
            duplicate(gapLength / 2, ' ');
        } else {
            duplicate(gapLength / 2 + 1, ' ');
        }
        duplicate(1, '*');
        duplicate(VerticalGap, '\n');
    }
    duplicate(span, '*');
    duplicate(1, '\n');
}

void duplicate(int size, char token) {
    for (int i = 0; i < size; ++i) {
        printf("%c", token);
    }
}

相關文章