#define LIST_INIT_SIZE 100 //線性表工作空間初始分配量
#define LISTINCREMENT 10 //每次增加的分配量
typedef struct{
int *elem; //整型的線性表 elem爲地址
int length; //線性表當前長度
int listsize; //當前分配的存儲容量 以sizeof(int)爲單位
}SqList;
這是一個整型的線性表,elem是元素的地址,length表示線性表的當前長度。listsize表示當前分配的存儲空間,在爲線性表增加內容時,一旦超過大小,就再爲其分配大小爲LISTINCREMENT的空間。
接下來,需要創建一個空的表,爲其開闢一個連續的空間。
bool InitList_Sq(SqList &L){
L.elem = (int *)malloc(LIST_INIT_SIZE * sizeof(int));
if(!L.elem){
/*exit (OVERFLOW);錯誤處理語句*/
cout<<"分配失敗"<<endl;
return false;
}
L.length = 0;
L.listsize = LIST_INIT_SIZE;
return true;
}
以上是一個空的表,但是它已經有了地址。接下來是爲其增加內容。
bool ListInsert_Sq(SqList &L,int i,int &q){
//在第i個位置插入新元素
//0 <= i <= L.length
if(i < 0 || i > L.length)return false;//可插入其它錯誤處理語句
/*如果空間不夠 進行擴充*/
if(L.length >= L.listsize){
int *newbase;//創建臨時指針,指向新分配的空間
newbase = (int *)realloc(L.elem,L.listsize+LISTINCREMENT * sizeof(int));//擴大空間
if(!newbase)return false;//可插入其它錯誤處理語句
L.elem = newbase;
L.listsize+=LISTINCREMENT;
}
int *temp;//創建臨時指針
for(temp = L.elem + (L.length+1) * sizeof(int);temp > L.elem+i * sizeof(int);--temp){
*temp = *(temp-sizeof(int));
}
*( L.elem+i * sizeof(int) ) = q;
L.length++;
return true;
}
補充:realloc
指針名=(數據類型*)realloc(要改變內存大小的指針名,新的大小)。新的大小一定要大於原來的大小,不然的話會導致數據丟失!如果重新分配成功則返回指向被分配內存的指針,否則返回空指針NULL
如果有足夠空間用於擴大mem_address指向的內存塊,則分配額外內存,並返回mem_address。
這裏說的是“擴大”,我們知道,realloc是從堆上分配內存的,當擴大一塊內存空間時, realloc()試圖直接從堆上現存的數據後面的那些字節中獲得附加的字節,如果能夠滿足,自然天下太平。也就是說,如果原先的內存大小後面還有足夠的空閒空間用來分配,加上原來的空間大小= newsize。那麼就ok。得到的是一塊連續的內存。
如果原先的內存大小後面沒有足夠的空閒空間用來分配,那麼從堆中另外找一塊newsize大小的內存。
並把原來大小內存空間中的內容複製到newsize中。返回新的mem_address指針。(數據被移動了)。
老塊被放回堆上。
在增加的基礎上進行修改,可以知道刪除元素的代碼。
bool ListDelete_Sq(SqList &L,int i){
if(i < 0 || i > L.length)return false;//可插入其它錯誤處理語句
int *temp;//創建臨時指針
for(temp = L.elem+i * sizeof(int);temp <= L.elem + (L.length-1) * sizeof(int);++temp){
*temp = *(temp+sizeof(int));
}
L.length--;
return true;
}
但是,因爲增加是往後移位,後位=前位,由此 循環是從後往前操作。刪除則反之,往前移位,前位=後位,循環是遞增的。