數據結構與算法 —— 線性表之順序存儲(C語言)

本文首發於我的個人博客:https://staunchkai.com

線性結構是較簡單、常用的一種數據結構,其特點爲:除第一個元素無直接前驅、最後一個元素無直接後繼外,集合中其餘元素均有唯一的直接前驅和直接後繼。而線性結構的存儲方式有兩種:順序存儲和鏈式存儲。

順序存儲結構

用一組地址連續的存儲單元一次存儲表中的各個元素,表在邏輯結構上相鄰的元素在物理結構上也是相鄰的,例如:

{a1, a2, a3, ..., an}

實現代碼

定義

使用結構體來定義順序表。

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

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 20

typedef int ElemType;
typedef int Status;
typedef struct
{
    ElemType data[MAXSIZE]; // 線性表最大長度
    int length; // 線性表實際內容最後一個的位置
}SqList;

創建順序表

/* 創建表 */
Status CreateList(SqList *L)
{
    int L_length;

    printf("輸入表的長度:");
    scanf("%d", &L_length);
    printf("輸入 %d 個元素:\n", L_length);

    int i = 0;
    while(i < L_length)
    {
        scanf("%d", &L->data[i]);
        i++;
    }
    L->length = L_length - 1;
    return OK;
}

打印順序表

/* 打印表 */
Status Print(SqList L)
{
    if(L.length >= 0)
    {
        printf("\n表中的元素爲:");
        for(int i = 0; i <= L.length; i++)
        {
            printf("%d ", L.data[i]);
        }
        return OK;
    }
    else
    {
        printf("表爲空!!!");
        return ERROR;
    }
}

元素的插入

要做到插入運算,要弄清楚兩個關鍵問題:

  1. 插入不成功的情況該怎麼辦?
  2. 插入成功後,表發生了什麼變化?
/* 插入元素 */
Status ListInsert(SqList *L, int i, ElemType e)
{
    /* 判斷表是否滿了 */
    if(L->length == MAXSIZE -1)    // L->length 爲最後一個元素的下標,而 MAXSIZE 非從 0 開始,所以 -1
    {
        printf("表內元判斷表是否滿了素已達到最大數量,無法插入...");
        return ERROR;
    }

    /* 判斷插入的位置是否合法 */
    if(i < 1 || i > L->length + 2)  // i 位置從 1 開始算,小於 1 爲非法,L->length 應 +1,考慮到在表最後一位追加,所以 +2
    {
        printf("插入的位置不合法...");
        return ERROR;
    }

    /* 把要插入元素的位置騰空,其他元素往後挪,應該先挪最後一個 */
    for(int k = L->length; k >= i - 1; k--)
    {
        L->data[k + 1] = L->data[k];
    }
    L->data[i - 1] = e;
    L->length++;    // 插入了一個元素,自然長度需要 +1
    return OK;
}

刪除元素

/* 刪除元素 */
Status DeleteElem(SqList *L, int i, ElemType *e)
{
    if(L->length < 0)
    {
        printf("表內爲空...");
        return ERROR;
    }

    if(i < 1 || i > L->length + 1)
    {
        printf("刪除的位置不合法!!!");
        return ERROR;
    }

    *e = L->data[i - 1];    // 將要刪除的元素返回

    /* 位移 */
    for(int k = i; k <= L->length; k++)
    {
        L->data[k - 1] = L->data[k];    // 從後往前覆蓋實現刪除
    }
    L->length--;
    return OK;
}

查找元素

/* 查找元素 */
Status GetElem(SqList L, ElemType e)
{
    for(int k = 0; k <= L.length; k++)
    {
        if(e == L.data[k])
            return k + 1;
        else
        {
            printf("該元素不存在...");
            return ERROR;
        }
    }
    return OK;
}

測試代碼

int main()
{
    SqList L;   // 定義一個順序表
    CreateList(&L);     // 創建表
    ElemType e;

    while(1)
    {
        printf("\n1. 瀏覽表中的數據\n");
        printf("2. 插入元素\n");
        printf("3. 刪除元素\n");
        printf("4. 查找元素\n");
        printf("5. 退出\n");
        printf("\n輸入序號:");

        int select;
        scanf("%d", &select);

        if(select == 5)
            return 0;

        switch(select)
        {
            case 1:
                Print(L);
                break;
            case 2:
                printf("\n輸入要插入的位置:");
                int insPosition, insElem;
                scanf("%d",&insPosition);
                printf("\n輸入要插入的元素:");
                scanf("%d",&insElem);
                if(ListInsert(&L, insPosition, insElem) == OK)
                    printf("插入成功!");
                break;
            case 3:
                printf("\n輸入要刪除元素的位置:");
                int deletePosition;
                scanf("%d", &deletePosition);
                if(DeleteElem(&L, deletePosition, &e) == OK)
                    printf("刪除成功,刪除的元素爲 %d", e);
                break;
            case 4:
                printf("輸入要查找的元素:");
                int FindElem, FindElemPosition;
                scanf("%d", &FindElem);
                FindElemPosition = GetElem(L, FindElem);
                if(FindElemPosition == OK)
                    printf("查找成功,位置爲:%d", FindElemPosition);
                break;
            default:
                printf("選擇失敗...");
                break;
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章