資料結構-不定長順序表
不定長順序表,顧名思義,就是順序表的長度不定,可以存放任意多個數據。與定長順序表相比,它可以在順序表長度不夠用時自己進行擴容。那麼在設計不定長的順序表時,存放資料的陣列就不能是固定長度的了,這時我們可以考慮用動態陣列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;
}