1. 程式人生 > 其它 >線性表(順序表)——基本操作/實現

線性表(順序表)——基本操作/實現

技術標籤:資料結構#寒假集訓資料結構

線性表(順序表)——基本操作/實現

線性表定義和特點及常用型別定義

  1. 定義:資料型別相同的n個元素構成的有限序列

    #所有呈遞增關係的整數不屬於線性表(無限)

  2. 特點:線性表是線性結構,線性結構的基本特點是:除第一個元素無直接前驅,最後一個元素無直接後繼外,其他每個資料元素都有一個前驅和後繼

  3. 位序:線性表中 第i個 元素,它的位序是從 1 開始的(區別陣列下標從 0 開始)

    #用陣列實現線性表時注意審題

  4. 常用型別定義:

    • InitList(&L):初始化
    • DestroyList(&L):銷燬
    • GetElem(L,i):按位置查詢。獲取表L中的第i個元素
    • LocateElem(L,e):按值查詢
    • InsertLIst(&L,i):插入
    • DeleteList(&L,i):刪除
    • Length(L):求表長。表L中資料元素的個數
    • PrintList(L):輸出。按從前到後的順序輸出表中資料
    • Empty(L):判空。空表返回true,否則返回false
  5. 關於 & :如果呼叫函式時,需要將函式中引數修改的結果帶回來,則使用“&”,如:線性表的初始化,銷燬,插入,刪除等。

順序表定義和基本操作及特點

  1. 定義:按順序儲存的線性表

  2. 基本操作:

    靜態分配——使用陣列

    #definde MaxSize 10;//陣列大小
    typedef struct
    { ElemType data[MaxSize]; /*ElemType 是資料元素型別,在自己使用時 換成相應的資料元素型別即可,如int,string,double等*/ int length; }SqList;//型別定義(別名) //初始化一個順序表 void InitList(SqList &L){ for(int i=0;i<MaxSize;++i) L.data[i]=0;//設定資料元素為預設值0(可省略) L.length=0;//順序表的初始長度 } int main(int argc, char** argv) { SqList L;//宣告一個順序表 InitList
    (L); //初始化順序表 ....... return 0; }

    #設定資料元素為預設值0雖然可以省略,但是如果沒有設定資料元素為預設值,記憶體中會有遺留的“髒資料”。

    動態分配——使用指標

    #definde InitSize 10;//陣列大小
    typedef struct{
       	int *data;//動態分配陣列的指標
       	int MaxSize;//順序表最大容量 
       	int length;//順序表當前長度 
       }SqList;//型別定義(別名)
       
       //初始化一個順序表 
       void InitList(SqList &L){
       	L。data = (int *)malloc(sizeof(ElemType)*InitSize); 
       	 /*動態申請分配記憶體 
       	(int *)使malloc函式返回的指標
       	強制轉換為自己所需的資料元素型別指標 
       	InitSize 指明要分配多大的空間,sizeof()中 * 是乘號 */
       	L.length=0;//順序表的初始長度 
       	L.MaxSize = InitSize; 
       } 
       
       //增加動態陣列的長度
       void IncreaseSize(SqList &L,int len){
       	int *p = L.data;//將L中資料先暫存在p中;
       	//擴容
       	L.data = (int *)malloc(sizeof(int)*L.MaxSize+len);
       	for(int i=0;i<L.length;++i)
       		L.data[i]=p[i] ;//將資料複製到新區域 
       	L.MaxSize = L.MaxSize+len;//增加表長 
       	free(p);//釋放原記憶體空間P; 
       } 
    

    #動態分配記憶體擴容雖然要方便一點,但是由於要將原記憶體的資料複製,所以時間開銷會很大。

  3. 特點:

    • 隨機訪問(隨機存取)。查詢第i個元素,data[i-1],因為線性表的位序是從1開始的,陣列下標是從0開始,所以是 i-1
    • 儲存密度高
    • 拓展容量不方便
    • 插入,刪除資料不方便

順序表的插入和刪除——基於靜態分配

​ 宣告和初始化:

#definde MaxSize 10;//陣列大小
typedef struct{
	int data[MaxSize]//陣列 
	int length;//順序表當前長度 
}SqList;//型別定義(別名)

void InitList(SqList &L){
	for(int i=0;i<MaxSize;++i)
		L.data[i]=0;//設定資料元素為預設值0(可省略)
	L.length=0;//順序表的初始長度 
}

插入

void ListInsert(SqList &L,int i,int e){
	if(i<1||i>L.length+1)//判斷i的範圍是否有效 
		return "輸入i的範圍無效";
	if(L.length>=MaxSize)//如果當前儲存空間已滿,不能插入 
    for(int j=L.length;j>=i;--j)
		L.data[j]=L.data[j-1];//將第i個元素及之後的元素後移 
	L.data[i-1]=e;//在位置i處放入e 
	++L.length;//長度加1 
} 

int main(int argc, char** argv) {
	SqList L;//宣告一個順序表 
	InitList(L); //初始化順序表 
	......
	ListInsert(L,3,3);//插入 
	return 0;
}

插入的時間複雜度

在這裡插入圖片描述

刪除

bool ListDelete(SqList &L,int i,int &e)//用 & 將e的即帶回來 
{
	if(i<1||i>L.length)//判斷i的範圍是否有效 
		return false;
	e = L.data[i-1];//講被刪除的元素賦值給e 
	for(int j=i;j<L.length;++j)
		L.data[j-1]=L.data[j];//將第i個位置後的元素前移 
	--L.length;//長度減1 
} 

int main(int argc, char** argv) {
	SqList L;//宣告一個順序表 
	InitList(L); //初始化順序表 
	......
	int e=-1;
	if(ListDelete(L,3,e))
		printf("已經刪除第3個元素,刪除元素值為=%d\n",e);
	else
		printf("位序i不合法,刪除失敗\n"); 
	return 0;
}

刪除的時間複雜度

在這裡插入圖片描述

順序表的查詢

按位查詢:獲取表L中第i個位置 的元素的值

  1. 靜態分配

    ElemType GetElem(SqList L,int i)
    //ElemType為你所需的返回值型別
    {
    	if(i<1||i>L.length)//判斷i的範圍是否有效 
    		return “位序i不合法,查詢失敗\n”;
    	return L.data[i-1];
    }
    
  2. 動態分配

    和訪問陣列的方法一樣,同上。

按值查詢:獲取表L中具有給定關鍵字值得元素

//在順序表L中查詢第一個元素值等於e的元素,並返回其位序 
int LocateElem(SqList L,int e){
	for(int i=0;i<L.length;++i)
		if(L.data[i]==e)//“==”針對於基本資料型別
			return i+1;
	return 0; 
}

#如果是結果型別的資料元素進行比較是需要依次對比各個分量來判斷結構體是否相等