在線性表中,數據元素在邏輯上具有一對一的關係,線性表的順序表示是指用一組地址連續的存儲單元依次存儲線性表的數據元素。我們可以這樣理解,線性表的順序存儲結構其實是用計算機內“物理位置相鄰”來表示線性表中數據元素之間的邏輯關係。因爲內存地址是連續的,我們恰好可以通過這種特點來表示線性表,這樣順序線性表的特點是:數據元素不僅邏輯上相鄰,在物理地址上也是相鄰的。同樣我們只要知道了存儲順序線性表的基地址,就可以隨機的存取數據元素,所以順序線性表是一種隨機存取的存儲結構。而程序設計語言中的數組也滿足隨機存取的特性,所以可以用C語言中的數組來描述線性表的順序存儲結構。
應當要注意的是,線性表是可變長的,所以得用動態分配數組去表示。我們可以通過結構體來定義順序線性表的存儲結構,定義一個數組指針elem來指向動態分配內存函數malloc所分配的地址,用一個整數length來記錄當前線性表的長度,除此之外,還要定義一個保存順序表當前分配的存儲空間大小的變量listsize,當因插入元素空間不足時,可以進行再分配。以下是定義的具體代碼:
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2 //溢出
typedef int Status;
/*
*使用c語言中的一維數組來描述順序線性表
**/
#define LIST_INIT_SIZE 5 //線性表存儲空間的初始分配量
#define LISTINCREMENT 10 //線性表存儲空間的分配增量
/*
*定義線性表的結構
**/
typedef struct{
int * elem; //存儲空間基地址(數組指針,指向預分配數組的首地址)
int length; //當前線性表的長度
int listsize; //當前分配的存儲容量
}SqList;
以下是構造一個空的線性表
/*
*func:InitList()
*desc:構造一個空的線性表L
*@param:&L SqList
*@return OK int
*/
Status InitList(SqList &L){
L.elem=(int *)malloc(LIST_INIT_SIZE*sizeof(int)); //動態開闢一維數組
if(!L.elem) exit(OVERFLOW); //存儲分配失敗
L.length=0; //空表長度初始化爲0
L.listsize=LIST_INIT_SIZE; //存儲的初始容量
return OK;
}
在順序線性表L中第i個位置插入新的元素e
/*
*fun:ListInsert_Sq()
*desc:在順序線性表L中第i個位置之前插入新的元素e
*@param:&L SqList
*@param: i int
*@param: e int
*@ret OK int
*/
Status ListInsert_Sq(SqList &L,int i,int e){
//i需要滿足1<=i<=ListLength_Sq(L)+1
if(i<1||i>L.length+1) return ERROR;
if(L.length>=L.listsize){ //當前存儲空間已滿,增加分配
int *newbase=(int *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(int));
if(!newbase) exit(OVERFLOW); //存儲分配失敗
L.elem=newbase; //新地址
L.listsize+=LISTINCREMENT; //增加存儲容量
}
int *q=&(L.elem[i-1]); //q爲插入的位置(注意數組的下標是從0開始計數)
for(int *p=&(L.elem[L.length-1]);p>=q;p--) *(p+1)=*p; //插入位置及之後的元素後移
*q=e; //插入e
L.length+=1; //表長增1
return OK;
}
在順序線性表L中刪除第i個元素,並用e返回其值
/*
*fun:ListDelete_Sq()
*desc:在順序線性表L中刪除第i個元素,並用e值返回
*@param:&L SqList
*@param: i int
*@param: e int
*@ret OK int
*/
Status ListDelete_Sq(SqList &L,int i,int &e){
//i的合法性爲1<=i<=ListLength_Sq(L)
if(i<1||i>L.length) return ERROR;
e=L.elem[i-1]; //把被刪除的元素賦給e
int *p=&L.elem[i-1]; //指針p爲被刪除元素的位置
for(int *q=p+1;q<=p+(L.length-i);q++) *(q-1)=*q; //被刪除位置之後的元素都往前移
L.length-=1; //表長減一
return OK;
}