老郭帶你學數據結構(C語言系列)2-線性表之動態順序表

一、基本概念:

線性表:由n個類型相同的數據元素組成的有限序列,記爲(a1,a2,……an)。

線性表的特徵:其中的元素存在這序偶關係,元素之間存在着嚴格的次序關係。

順序存儲表:線性表中的元素依次存放在一組地址連續的存儲單元(數組)中。

存儲特點:若已知首元素的起始地址a0和每個元素佔用的空間m,則計算第i個元素的存儲位置:ai = a0 + (i - 1)m。

順序表的特徵:(1)在邏輯上相鄰的元素,在物理上也是相鄰
(2)知道表中起始元素的地址,線性表中的任一個元素地址都可以確定,因此很容易實現對線性表中的元素的隨機訪問。

動態順序表:動態存儲分配方式實現

二、代碼實現:

1)結構實現(行號是爲了閱讀和說明代碼方便,請複製代碼是忽略行號)

typedef int ElemType;           //定義一種數據類型
#define INITSIZE 60             //定義一個動態表的初始化大小的值

typedef struct{                 //封裝了數據類型
    ElemType *data;
    int len;
    int listSiz;
} SqList;

2)抽象數據類型(主要是爲了說明定義的結構(本例中是順序表)支持的運算操作,爲了使用上的方便,建議使用頭文件加實現的方式來運用,引入了bool變量,包含頭文件stdbool.h)

void listInit(SqList *L);                       //表的初始化
bool listEmpty(SqList L);                       //判斷表是否爲空  
bool listFull(SqList L);                        //判斷表是否已滿   
void listCreate(SqList *L);                     //創建表 
void listPrint(SqList L);                       //輸出表的內容
void listDestroy(SqList *L);                    //表的銷燬,涉及內存分配,因此必須free   
void listInsert(SqList *L, int i, ElemType e);  //在表中i的位置插入元素e                   
int listLength(SqList L);                       //獲取表的長度
int listSerch(SqList L, ElemType e);            //在表中查找元素e,返回其在表中的位置   
ElemType listDelete(SqList *L, int i);          //刪除表中位置爲i的元素,並返回刪除元素的值  
ElemType listVisit(SqList L, int i);            //訪問表中第i個元素,並返回元素的值

3)頭文件實現
將1)和2)中的代碼整合後,在第4行加上#ifndef SqList_H,在第42行加上#endif,實際項目中這樣作是爲了避免重複定義和引用頭文件,文件名爲SqList.h,完整代碼如下:

#include <stdbool.h>

typedef int ElemType;
#ifndef SqList_H
#define SqList_H
#define INITSIZE 60

typedef struct{
    ElemType *data;
    int len;
    int listSiz;
} SqList;

void listInit(SqList *L);                       //表的初始化
bool listEmpty(SqList L);                       //判斷表是否爲空  
bool listFull(SqList L);                        //判斷表是否已滿   
void listCreate(SqList *L);                     //創建表 
void listPrint(SqList L);                       //輸出表的內容
void listDestroy(SqList *L);                    //表的銷燬,涉及內存分配,因此必須free   
void listInsert(SqList *L, int i, ElemType e);  //在表中i的位置插入元素e                   
int listLength(SqList L);                       //獲取表的長度
int listSerch(SqList L, ElemType e);            //在表中查找元素e,返回其在表中的位置   
ElemType listDelete(SqList *L, int i);          //刪除表中位置爲i的元素,並返回刪除元素的值  
ElemType listVisit(SqList L, int i);            //訪問表中第i個元素,並返回元素的值

#endif

4)操作算法實現,實現頭文件定義的順序表的操作,文件名爲SqList.c(注意頭文件和和實現文件名字一模一樣,只有後綴名由區別),具體代碼如下:

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

void listInit(SqList *L){
    (*L).data = (ElemType *)malloc(sizeof(ElemType) * INITSIZE);
    if(0 == (*L).data){
        return;
    }
    (*L).len = 0;
    (*L).listSize = INITSIZE;
}

bool listEmpty(SqList L){
    return (0 == L.len);
}

bool listFull(SqList L){
    return (listSize == L.len);
}

void listCreate(SqList *L){
    printf("please input the lenth of list:");
    scanf("%d", &((*L).len));
    if((*L).len > (*L).listSize){
        (*L).listSize = (*L).len + INITSIZE / 2;
        free((*L).data);
        (*L).data = (ElemType *)malloc(sizeof(ElemType) * (*L).listSize);
        if(0 == (*L).data){
            return;
        }
    }
    for(int i = 0; i <= (*L).len; i++){
        printf("please input NO%d element: ", i);
        scanf("%d", &((*L).data[i]));
    }

    return;
}

void listPrint(SqList L){
    for(int i = 0; i < L.len; i++){
        printf("%d\t", L.data[i]);
    }
    printf("\n");

    return;
}

void listDestroy(SqList *L){
    free((*L).data);
    (*L).data = NULL;
    (*L).len = 0;
    (*L).listSize = 0;

    return;
}

void listInsert(SqList *L, int i, ElemType e){
    if(i < 0 || i > (*L).len){
        return;
    }
    if(listFull(*L)){
        (*L).listSize = (*L).listSize + INITSIZE / 2;
        (*L).data = (ElemType *)realloc(sizeof(ElemType) * (*L).listSize);
        if(0 == (*L).data){
            return;
        }
    }
    for(int j = (*L).len - 1; j >= i - 1; j--){
        (*L).data[j + 1] = (*L).data[j];
    }
    (*L).data[i - 1] = e;
    (*L).len++;

    return;
}

int listLength(SqList L){
    return L.len;
}

int listSerch(SqList L, ElemType e){
    for(int i = 0; i < L.len; i++){
        if(e == L.data[i]){
            return i;
        }
    }

    return -1;
}

int listDelete(SqList *L, int i){
    if(i < 0 || i > (*L).len){
        return -1;
    }
    if(listEmpty(*L)){
        return -2;
    }
    ElemType e = (*L).data[i - 1];
    for(int j = i; j < (*L).len; j++){
        (*L).data[j - 1] = (*L).data[j]
    }
    (*L).len--;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章