線性表:(list)由零個或多個資料元素組成的有限序列。
抽象:是指抽取出事物具有的普遍性的本質。他要求抽出問題的特徵而忽略非本質的細節,是對具體事物的乙個概括,抽象是一種思考問題的方式,他隱藏了繁雜的細節。
線性表的抽象資料型別:(所謂抽象資料型別就是把資料型別和相關操作**在一起,這就像我們物件導向這類高階語言的做法一樣,把屬性和方法**在一塊那就是類。)
我們對已有的資料型別進行抽象,就有了抽象資料型別(abstract data type,adt)是指乙個資料型別及定義在該模型上的一組操作。(也可以自定義)
抽象資料型別的標準格式:
adt 抽象資料型別名
data
資料元素之間邏輯關係的定義
operation
操作endadt
線性表抽象資料型別的定義:
adt 線性表(list)//他的名字叫做線性表有乙個英文名字叫做list
data//是什麼資料呢?//下面具體描述資料的型別
線性表的資料物件集合為
操作:
operation
initlist(*l):初始化操作,建立乙個空的線性表l。
listempty(l):判斷線性表是否為空表,若線性表為空,返回true ;否則返回false。
clearlist(*l):將線性表清空。//就是把裡邊的資料都給清楚掉事實上呢就是把他們都填0,因為我們知道在記憶體中的資料不可能是真正的清除,他不能登一聲就沒有了,記憶體中乙個位置總要放乙個東西,你可以認為說0那時候就是乙個空氣啥都沒有表示清空的意思。因為記憶體上的資料只能被覆蓋。
getelem(l,i,*e):將線性表l中的第i個位置元素值返回給e。
listdelete(*l,i,*e):刪除線性表l中第i個位置元素,並用e返回其值。
listlength(l):返回線性表l的元素個數。
endadt
對於不同的應用,線性表的基本操作是不同的,上述操作是最基本的,對於實際問題中涉及的關於線性表的更複雜的操作,完全可以用這些基本操作的組合來實現。
舉例:比如想實現a和b的並集u。運用到的基本操作:
listlength(l);//知道線性表的長度。
getelem(l,i,*e);//獲取元素。
locateelem(l,e);//定位。
listinsert(*l,i,e)//插入。
實現**如下:
//la表示a集合,lb表示b集合
void unionl(list *la,list lb)//有兩個線性表,為什麼乙個帶指標,乙個不帶呢?
線性表有兩種物理儲存結構:順序儲存結構和鏈式儲存結構。
a1a2
a3a4
...ai-1
aiai+1
...an
物理上的儲存方式事實上就是在記憶體中找個初始位址,然後通過佔位的形式,把一定的記憶體空間給佔位了,然後把相同資料型別的資料元素依次放在這塊空地中。
線性表順序儲存的結構**:
#define maxsize 20//3定義下邊陣列的最大長度
typedef int elemtype;
typedef struct
sqlist;//4通過乙個結構這個結構的名字叫做sqlist對陣列進行封裝,多了乙個length長度的變數。
//1這裡封裝了乙個結構,事實上就是對陣列進行了封裝,增加了個當前長度的變數
總結:順序儲存結構封裝需要三個屬性
ps:注意陣列的長度與線性表的當前長度需要區分一下:陣列的長度是存放線性表的儲存空間的總長度,一般初始化後不變。而線性表的當前長度是線性表中元素的個數,是會變化的。
我們習慣了陣列從下標0開始計算,但是線性表是從1開始計算的。假設elemtype占用的是c個儲存單元(位元組)(比如int占用4個位元組),那麼線性表中第i+1個資料元素和第i個資料元素的儲存位置的關係是(loc表示獲得儲存位置的函式):loc(ai+1)=loc(ai)+c(表示ai+1這個元素的位址相當於ai元素的位址+c(因為c是儲存單元的寬度)),所以對於第i個資料元素ai的儲存位置可以由a1儲存推算出來:loc(ai)=loc(a1)+(i-1)*c。
------實現getelem獲取元素的具體操作,即將線性表l中第i個位置元素值返回,就程式而言非常簡單如下,我們只需要把陣列第i-1下標的值返回即可。
#define ok 1//這裡用define ok表示1
#define error 0
#define true 1
#define false 0
typedef int status;
//status 是函式型別,其值是函式結果狀態**,如ok等。
//初始條件:順序線性表l已存在,1<=i<=listlength(l)
//操作結構:用e返回l中第i個資料元素的值。
status getelem(sqlist l,int i,elemtype *e)//有三個引數,第乙個是線性表l;第二個是他的索引位置;第三個是他要返回的把他存放的再存放的乙個值乙個位址乙個指標。
*e=l.data[i-1]; //其他情況下要把i-1這個下標的值把他放在e這個指標變數裡邊,那就可以了。
return ok;//表示getelem這個結果正確
}
注意上述返回值型別status是乙個整型,約定返回1代表ok,返回0代表error。
插入演算法的思路:
如果插入位置不合理,丟擲異常;
如果線性表長度大於等於陣列長度,則丟擲異常或動態增加陣列容量;
從最後乙個元素開始向前遍歷到第i個位置,分別將他們都向後移動乙個位置。
將要插入元素填入位置i處;
線性表長+1。
實現**如下:
//初始條件:順序線性表l已經存在,1<=i<=listlength(l)。
//操作結果:在l中第i個位置之前插入新的資料元素e,l長度+1。
status listinsert(sqlist *l,int i,elemtype e)
if(i<1||i>l->length+1)//當i不在範圍內時
if(i<=l->length)//若插入資料位置不在表尾
}l->data[i-1]=e;//將新元素插入,i-1是因為線性表i是從1開始的,陣列是從0開始的。
l->length++;
return ok;
}
------實現listdelete刪除具體操作, listdelete(*l,i,*e)即刪除線性表l中第i個位置元素,並用e返回其值。
刪除演算法的思路:
如果刪除位置不合理,丟擲異常;
取出刪除元素;(看一下怎麼取的)
從刪除位置元素開始遍歷到最後乙個元素位置,分別將他們都向前移動乙個位置;
表長-1。
//初始條件:順序線性表l已經存在,1<=i<=listlength(l)。
//操作結果:刪除l的第i個資料元素,並用e返回其刪除的值,l的長度-1。
status listdelete(sqlist *l,int i,elemtype *e)
if(i<1||i>l->length+1)//當i不在範圍內時
*e=l->data[i-1];//把他的值放到這個指標e裡邊去(因為上邊定義的是乙個指標變數)//因為是第i個元素,所以他的陣列裡邊的索引就是i-1;
if(i<=l->length)//只要i小於他的length,接下來就是移位
}l->length--;
return ok;
}
資料結構 線性表演算法
1.線性表 線性表是n個具有相同特性的資料元素的有限序列。線性表的主要儲存結構 順序儲存結構 順序表 鏈式儲存結構 鍊錶 2.順序儲存 儲存空間連續,用一組連續的儲存單元依次存放資料元素 即邏輯上相鄰的元素,其物理位置也相鄰。優點 隨機訪問 缺點 插入刪除結點困難 擴充套件不靈活 3.鏈式儲存 儲存...
資料結構和演算法之線性表
因為要準備筆試,要涉及到一些資料結構和演算法基礎。所以準備重新學習和整理下資料結構演算法的的知識。按照但不全按照下圖的思維導圖展開。定義 元素一條線布局,可以不同,有先後順序。除了第乙個沒有直接前驅,最後乙個沒有直接後繼。其他節點都有直接前驅和後繼。下儲存可分順序儲存和鏈式儲存。定義 元素放在一塊連...
資料結構(線性表)
1.試寫一演算法,在無頭結點的動態單鏈表上實現線性表操作insert l,i,b 並和在帶頭結點的動態單鏈表上實現相同操作的演算法進行比較。status insert linklist l,int i,int b 在無頭結點鍊錶l的第 i個元素之前插入元素 belse insert 2.已知線性表中...