1. 程式人生 > >資料結構-不定長順序表

資料結構-不定長順序表

        不定長順序表,顧名思義,就是順序表的長度不定,可以存放任意多個數據。與定長順序表相比,它可以在順序表長度不夠用時自己進行擴容。那麼在設計不定長的順序表時,存放資料的陣列就不能是固定長度的了,這時我們可以考慮用動態陣列elem來代替,進行擴容時就可以動態申請記憶體,將資料存放到動態陣列中。同時加入一個變數size來存放總的格子數(總容量)。

接下來是程式碼:

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<memory.h>
#include"DSeqList.h"
//初始化
void Init(PDSeqList pl)
{
    if (pl == NULL)
    {
        return;
    }
    pl->parr = (ELEM_TYPE*)malloc(sizeof(ELEM_TYPE)*INITSIZE);                     //動態開闢空間
    assert(pl->parr != NULL);
    pl->cursize = 0;                                                                                 //陣列長度為0
    pl->totalsize = INITSIZE;                                                                 //陣列總長度為巨集定義資料5
}

//第一種擴容方式 利用realloc函式
static void resize1(PDSeqList pl)
{
    pl->parr = (ELEM_TYPE*)realloc(pl->parr,sizeof(ELEM_TYPE)*(pl->totalsize + INITSIZE));     //realloc函式
    assert(pl->parr != NULL);
    pl->totalsize += INITSIZE;                                               //總長度變長
}

//第二種擴容方式 直接開闢更大的陣列
static void resize(PDSeqList pl)
{
    ELEM_TYPE* newarr = (ELEM_TYPE*)malloc(sizeof(ELEM_TYPE)*(pl->totalsize + INITSIZE));  //開闢更大的空間
    assert(newarr != NULL);
    memcpy(newarr,pl->parr, sizeof(ELEM_TYPE)*pl->totalsize);     //利用memcpy將原先資料複製進去
    free(pl->parr);                                                                             //將原先開闢的動態空間釋放掉
    pl->parr = newarr;
    pl->totalsize += INITSIZE;
}

//插入資料
int InsertPos(PDSeqList pl, int pos, ELEM_TYPE val)
{
    if (pl == NULL)
    {
        return 0;
    }
    if (pos < 0 || pos > pl->cursize)
    {
        return -1;
    }
    if (IsFull(pl))
    {
        resize(pl);
    }
    for (int i = pl->cursize; i > pos; --i)                       //先將資料往後移
    {
        pl->parr[i] = pl->parr[i - 1];
    }
    pl->parr[pos] = val;                                              //將資料插入進去
    pl->cursize++;
    return 1;
}

//按位置刪除
int DeletePos(PDSeqList pl, int pos)
{
    if (pl == NULL)
    {
        return 0;
    }
    if (pos < 0 || pos > pl->cursize - 1)
    {
        return -1;
    }
    for (int i = pos; i < pl->cursize - 1; ++i)              //資料往前挪,直接覆蓋
    {
        pl->parr[i] = pl->parr[i + 1];
    }
    pl->cursize--;
    return 1;
}

//按元素刪除
int DeleteKey(PDSeqList pl, ELEM_TYPE key)
{
    int index = Search(pl, key);
    if (index < 0)
    {
        return -1;
    }
    for (int j = index; j < pl->cursize; ++j)
    {
        if (pl->parr[j] == key)
        {
            for (int k = j; k < pl->cursize - 1; ++k)
            {
                pl->parr[k] = pl->parr[k + 1];
            }
            pl->cursize--;
            j--;
        }
    }
    return 1;
}

int Search(PDSeqList pl, ELEM_TYPE key)
{
    int rt = -1;
    if (pl != NULL)
    {
        for (int i = 0; i < pl->cursize; ++i)
        {
            if (key == pl->parr[i])
            {
                rt = i;
                break;
            }
        }
    }
    return rt;
}

bool IsFull(PDSeqList pl)
{
    return pl->cursize == pl->totalsize;
}
void Show(PDSeqList pl)
{
    for (int i = 0; i < pl->cursize; ++i)
    {
        printf("%d ", pl->parr[i]);
    }
    printf("\n");
}

void Clear(PDSeqList pl)//清空資料
{
    pl->cursize = 0;
}

void Destroy(PDSeqList pl)//銷燬順序表
{
    Clear(pl);
    free(pl->parr);
}

標頭檔案DSeqList:

#define INITSIZE 5
typedef int ELEM_TYPE;
typedef struct DSeqList
{
    ELEM_TYPE *parr;
    int cursize;
    int totalsize;
}DSeqList,*PDSeqList;

void Init(PDSeqList pl);
static void resize2(PDSeqList pl);
static void resize(PDSeqList pl);
int InsertPos(PDSeqList pl, int pos, ELEM_TYPE val);
int DeletePos(PDSeqList pl, int pos);
int DeleteKey(PDSeqList pl, ELEM_TYPE key);
int Search(PDSeqList pl, ELEM_TYPE key);
bool IsFull(PDSeqList pl);
void Show(PDSeqList pl);
void Clear(PDSeqList pl);
void Destroy(PDSeqList pl);
 

主函式main():(基本操作)

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

int main()
{
    DSeqList sl;
    Init(&sl);
    for (int i = 0; i < 10; ++i)
    {
        int rt = InsertPos(&sl, i, i + 1);
        printf("rt %d:%d\n", i + 1, rt);
    }
    Show(&sl);
    DeletePos(&sl, 2);
    Show(&sl);
    int rt1 = InsertPos(&sl, 1, 4);
    printf("rt %d:%d\n", 11, rt1);
    Show(&sl);
    int rt2 = DeleteKey(&sl, 4);
    printf("rt %d:%d\n", 12, rt2);
    Show(&sl);
    Clear(&sl);
    Destroy(&sl);
    system("pause");
    return 0;
}