線性表(線性存儲):
其實 線性表理解數據是連續的,意思就是中間不能間隔,不能跳躍式的存儲。
實現方式,一種是線性存儲,一種是鏈式存儲。其實理解線性表其實主要問題在於如何將業務結點存進線性表
1.線性存儲,我們是通過數組來實現的:
譬如我們有一個業務結構,譬如person的結構體:
typedef struct person
{
int age;
char name[64];
}person;
,那麼我們如何將一個一個的person的結點存進線性表呢,我們可以通過void * 可以接收任何指針類型的方式來實現,這樣我們的線性存儲可以這樣定義:
typedef struct _seqlist
{
int length,
int capacity',
void **ptr,
}seqlist;
而線性表的結點,我們可以這樣定義,因爲void * 類型可以接收任意的指針類型
typedef void * seqlistnode;
一、線性表線性存儲的API函數:
1.先創建一個線性表:
//創建一個線性表
seqlist*seqlist_create(int cap)
{
int ret = 0;
if(cap <0)
{
ret = -1;
printf("seqlist_create error ,傳進來的容量小於了0:%d \n",ret);
return NULL;
}
seqlist *tmp = NULL;
tmp = malloc(sizeof(seqlist));
if(NULL == tmp)
{
ret = -2;
printf("seqlist_create error ,申請內存失敗:%d \n",ret);
return NULL;
}
tmp->length = 0;
tmp->capacity = cap;
tmp->ptr = malloc(sizeof(void *) *cap);
if(NULL ==tmp->ptr)
{
ret = -3;
printf("seqlist_create error ,申請內存失敗:%d \n",ret);
return NULL;
}
return tmp;
}
2.獲取線性表的長度
int seqlist_length(seqlist *seq)
{
int ret = 0;
if(NULL == seq)
{
ret = -1;
printf("seqlist_length error ,傳進的參數是無效的:%d \n",ret);
return ret;
}
return seq->length;
}
3.獲取線性表容量
int seqlist_capacity(seqlist *seq)
{
int ret = 0;
if(NULL == seq)
{
ret = -1;
printf("seqlist_capacity error ,傳進的參數是無效的:%d \n",ret);
return ret;
}
return seq->capacity;
}
4.銷燬線性表
void seqlist_dsetroy(seqlist* seq)
{
int ret = 0;
if(NULL == seq)
{
ret = -1;
printf("seqlist_setroy error ,傳進的參數是無效的:%d \n",ret);
return ;
}
if( NULL != seq->ptr)
{
free(seq->ptr);
}
free(seq);
return ;
}
5。清空線性表
void seqlist_clear(seqlist *seq)
{
int ret = 0;
if(NULL == seq)
{
ret = -1;
printf("seqlist_setroy error ,傳進的參數是無效的:%d \n",ret);
return ;
}
seq->length = 0;
return ;
}
6.往線性表插入一個結點
int seqlist_insert(seqlist *seq,seqlistnode * node,int pos)
{
int ret = 0;
if(NULL ==seq || pos <0||NULL == node)
{
ret = -1;
printf("seqlist_insert error ,傳入的參數都是無效的:%d \n",ret);
return -1;
}
if(seq->length >= seq->capacity)
{
ret = -2;
printf("seqlist_insert 線性表已經滿了:%d \n",ret);
return -2;
}
if(pos > seq->length-1)
{
pos = seq->length;
}
//往線性表插入數據,那麼將pos位置的數據往後移一位,這樣就可以將pos位置的數據空出來存放node,、
//這樣操作不管你是長度爲0,並且想頭插,或者你想尾插,或者中間插入都是可以滿足的
for(int i = seq->length -1; i>=pos;i--)
{
seq->ptr[i+1] = seq->ptr[i];
}
seq->ptr[pos] = node;
seq->length++;
return ret;
}
7.從線性表內部刪除一個結點
int seqlist_delete(seqlist *seq,int pos)
{
int ret = 0;
if(NULL == seq|| pos < 0)
{
ret = -1;
printf("seqlist_delete error,傳入的參數不對:%d \n",ret);
return ret;
}
if(seq->length == 0)
{
ret = -2;
printf("seqlist_delete error,線性表長度爲0:%d \n",ret);
return ret;
}
for(int i = pos;i <= seq->length-2;i++)
{
seq->ptr[i] = seq->ptr[i+1];
}
seq->length--;
return ret;
}
這幾個API函數可以卸載一個seqlist.c的源文件裏面
二、seqlist.h的頭文件可以寫爲:
#ifndef __SEQLIST__
#define __SEQLIST__
typedef void seqlistnode;
typedef struct _seqlist
{
int capacity;
int length;
void **ptr;
}seqlist;
seqlist*seqlist_create(int cap);
int seqlist_length(seqlist *seq);
int seqlist_capacity(seqlist *seq);
void seqlist_dsetroy(seqlist* seq);
void seqlist_clear(seqlist *seq);
int seqlist_insert(seqlist *seq,seqlistnode * node,int pos);
int seqlist_delete(seqlist *seq,int pos);
#endif
三、測試的代碼爲main.c
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include"seqlist.h"
typedef struct person
{
int age;
char name[64];
}person;
int main(int argc,char* argv[])
{
seqlist *seq = seqlist_create(10);
person p1;
person p2;
person p3;
person p4;
person p5;
p1.age = 10;
p2.age = 11;
p3.age = 12;
p4.age = 13;
p5.age = 14;
seqlist_insert(seq,(seqlistnode *)&p1,0);
seqlist_insert(seq,(seqlistnode *)&p2,0);
printf("線性表目前長度爲:%d \n",seqlist_length(seq));
seqlist_insert(seq,(seqlistnode *)&p3,0);
seqlist_insert(seq,(seqlistnode *)&p4,0);
printf("線性表目前長度爲:%d \n",seqlist_length(seq));
seqlist_insert(seq,(seqlistnode *)&p5,0);
printf("線性表目前長度爲:%d \n",seqlist_length(seq));
for(int i = 0; i < seq->length;i++)
{
printf("年齡爲:%d \n",((person *)(seq->ptr[i]))->age);
}
for(int i = 0; i < 5;i++)
{
seqlist_delete(seq,0);
}
printf("線性表目前長度爲:%d \n",seqlist_length(seq));
return 0;
}
四、三個源文件編譯成可執行程序的makefile:
main:seqlist.o main.o
gcc seqlist.o main.o -o main
%o:%c
gcc -c $^ -o $@
clean:
rm -rf *.o
rm -rf main
這樣,整個線性表的線性存儲的代碼就寫完了。
刪除節點和插入節點的關鍵在於理解數組元素的移動,插入元素,需要將pos位置所有元素往後移動一個,刪除將往前移動即可。