線性表(上)之順序存儲

線性表
一、線性表定義:
1、線性表的定義
定義:線性表(List):零個或多個數據元素的有限序列。
注意:
1)線性表是一個序列。也就是說,線性表的元素之間是有序的。若元素存在多個,對於其中一個元素來說,它前面的元素叫前驅,後面的元素叫後繼。第一個元素無前驅,最後一個元素無後繼,中間的元素只有一個前驅,一個後繼。
2)線性表是有限的。事實上,在計算機科學領域,我們只研究有限的序列,因爲計算機的處理對象都是有限的。而對於那些無限的序列,只在數學中討論。
線性表的元素個數n(n>=0)定義爲線性表的長度,當n=0時,稱爲空表。
練習:說明以下數據集是否是線性表
1、一年中的十二星座
2、一個公司的組織架構(非皮包公司)
3、一個班級間的同學關係
4、班級同學的點名冊
5、播放器的播放列表
6、linux的文件系統
答案:
1、4、5是,2、3、6不是

2、線性表的操作:
設有線性表L,對線性表的操作有:
⒈建立一個空線性表
⒉清空一個線性表
⒊判斷線性表是否爲空
⒋求表長
⒌獲得表中第i個位置的元素
⒍確定某元素在線性表中的位置
⒎插入一個新的元素
⒏刪除第i個位置的元素
⒐遍歷該線性表
二、線性表的順序存儲結構
1、定義存儲結構
線性表的順序存儲結構,指的是用一段地址連續的存儲單元依次存儲線性表的數據元素。
在C語言中,我們可以使用一維數組來實現順序表的存儲結構。即把表的第一個元素數據存放到數組下標爲0的位置中,接着把線性表相鄰的元素存儲到數組中的相鄰位置。
線性表的順序存儲結構代碼:
#define MAXSIZE 20
typedef int data_t;
typedef struct
{
data_t data[MAXSIZE];
int length;
}SqList;
這裏要區分線性表長度與數組長度的區別。數組長度是存放線性表的存儲空間長度,在編譯後這個存儲空間就不變了。而線性表長度指的是線性表中的數據元素個數,隨着線性表的操作,這個數據是變化的。在任意時刻,線性表長度應該小於等於數組長度。
對於順序表來說,邏輯位置上相鄰的兩個元素,其在存儲位置上也是相鄰的。例如a[i]和a[i+1],二者在邏輯結構上是前後關係,在存儲結構上也是前後關係。
2、插入與刪除
有關於順序表的相關操作,一些操作是十分簡單的。例如:求表長,查詢第i個位置元素,置空,遍歷等。這裏不詳細講解。對於順序表來說,重點要掌握它的插入與刪除操作。
1)獲得元素
對於線性表的順序存儲結構來說,獲取第i個位置的元素是非常簡單的。
//代碼見附錄
2)插入操作
舉個例子:一隊人在排隊買票,這時來了一個插隊的,他插入到的隊伍的第i個位置,那麼在他之後的人都要向後挪一步。
在這個例子中我們已經說明了線性表的順序存儲結構在插入數據時的實現過程。
插入算法思路:
⒈如果插入位置不合理,返回異常
⒉如果線性表長度大於等於數組長度,則返回異常或增加容量
⒊從最後一個位置開始向前遍歷到第i個位置,分別將它們都向後移動一個位置
⒋將要插入元素填入位置i處
⒌表長加1
//代碼見附錄
3)刪除操作
接着剛纔的例子:此時後邊排隊的人意見很大,這時他衝出了隊伍,消失在人羣中。於是排隊的人羣又想蠕蟲一樣向前移動了一步,隊伍又恢復了平靜。
這就是線性表的順序存儲結構刪除元素的過程。
刪除算法思路:
⒈如果刪除位置不合理,返回異常
⒉取出刪除元素
⒊從刪除元素位置開始遍歷到最後一個元素位置,分別將它們都向前移動一個位置
⒋表長減1
//代碼見附錄
3、線性表順序存儲結構的優缺點
優點:
⒈無需爲表示表中元素之間的邏輯關係而額外增加額外的存儲空間
⒉可以快速地存取表中任意位置的元素
缺點:
⒈插入和刪除操作需要移動大量元素
⒉當線性表長度變化較大時,難以確定存儲空間的容量
⒊可能造成存儲空間“碎片”

線性表之順序表代碼
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 20
#define OK 1
#define ERROR 0
typedef int data_t;
typedef struct
{
data_t data[MAXSIZE];//定長情況下
//data_t *data;//變長情況下
int length;//表長
}SqList;
SqList *CreateEmptySqList()//定長
{
SqList *sq;
if(NULL==(sq = (SqList*)malloc(sizeof(SqList))))
{
printf("CreateEmptySqList Error\n");
exit(0);
}
sq->length=0;
return sq;
}

int GetElem(SqList *L,int i,data_t *e)//獲得順序表第i個位置的元素
{
if(i>=L->length && i<0)
{
perror("No this Element");
return ERROR;
}
*e=L->data[i];
return OK;
}
int ListInsert(SqList *L,int i,data_t e)//在線性表的第i個位置插入元素e
{
int k;
if(L->length==MAXSIZE)//線性表已滿
{
printf("SqList is Full\n");
return ERROR;
}
if(i<0 || i>L->length)//i不在線性表的範圍內
{
printf("Position Error\n");
return ERROR;
}
if(i<L->length)//若插入位置不在表尾
{
for(k=L->length-1;k>=i;k--)//當前位置開始到表尾所有元素向後移動1格
L->data[k+1]=L->data[k];
}
L->data[i]=e;//插入新元素
L->length++;
return OK;
}
int ListDelete(SqList *L,int i,data_t *e)//刪除線性表的第i個位置元素,並用e得到刪除的值
{
int k;
if(L->length==0)//線性表爲空
{
printf("SqList is Empty\n");
return ERROR;
}
if(i<0 || i>=L->length)//i不在線性表的範圍內
{
printf("Position Error\n");
return ERROR;
}
*e=L->data[i];//取走元素
if(i<L->length-1)//若刪除位置不在表尾
{
for(k=i;k<L->length-1;k++)
L->data[k]=L->data[k+1];
}
L->length--;
return OK;
}
int PrintList(SqList *L)//遍歷打印整個順序表
{
int k;
data_t temp=0;
if(L->length==0)
{
printf("線性表爲空!\n");
return ERROR;
}
for(k=0;k<L->length;k++)
{
GetElem(L,k,&temp);
printf("%d\t",temp);
}
printf("\n");
return OK;
}
int main()
{
int i;
data_t data;
SqList *sq = CreateEmptySqList();
for(i=0;i<5;i++)
{
sq->data[sq->length]=i;
sq->length++;
}
if(GetElem(sq,3,&data)==OK)
{
printf("data is %d\n",data);
}
PrintList(sq);
ListInsert(sq,2,20);
PrintList(sq);
ListDelete(sq,2,&data);
PrintList(sq);
return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章