變長陣列(variable-length array), 簡稱 vla
c語言中,直到c99標準出現之前,宣告陣列時在方括號內只能使用整數常量表示式。
而c99做了很大改進,允許陣列的[ ]中的值是整形變數或是整形表示式。這就解釋了下面的情況:
int n;
scanf ("%d", &n);
int array[n];
雖然n確實是需要執行時動態確定的變數,但是在c99中,以這種變數作為陣列大小的形式已經是允許的了。
這樣的陣列就被稱之為「變長陣列」。
注意:變長陣列是指用整型變數或表示式宣告或定義的陣列,而不是說陣列的長度會隨時變化,變長陣列在其生存期內的長度同樣是固定的。
可變陣列(resizeable array)
陣列的大小可「長大」,具體實現是在前期指定陣列的大小,並在後期重新定義陣列大小。使陣列能在原大小的基礎上「長大」,原來空間定義的資料不改變地拷貝到新定義的空間,並釋放原空間,多出的未利用的空間即為新增空間。可變陣列主要用於事先不明確所需陣列的大小,需要在程式的中後段手工擴充的具體問題中。
為實現可變的功能必須滿足以下條件:
1.可變大小
2.可得到陣列的大小
3.可訪問陣列其中的單元
inte***ce(介面,封裝一定功能的集合)
array array_creat(int init_size);
void array_free(array *a);
int array_size(const array *a);
int *array_at(array *a,int index);
void array_inflate(array *a,int more_size);
需要建乙個專案,包括array.h和array.c檔案,具體步驟省略。
可變陣列的缺陷:陣列每次長大都需要申請新的記憶體空間,並需要拷貝原陣列資料並釋放它。
1.拷貝的時間呈線性增加
2.在記憶體受限的情況下(如微控制器的記憶體空間),明明有足夠的記憶體空間卻不能再申請新的空間了。
//在乙個大小為2n+block_size的記憶體空間中,當前的陣列空間大小是n,n-block_size是之前陣列現已被釋放的空間,2block_size是未利用的記憶體空間。
//對於下乙個陣列的建立所需空間是n+block_size,n-block_size和2block_size都不夠大,雖然他們相加正好是n+block_size,但因為不連續所以不能建立。
對於第乙個缺陷可以用memcpy函式來解決,
函式名: memcpy
功 能: 從源source中拷貝n個位元組到目標destin中
用 法: void *memcpy(void *destin, void *source, unsigned n);
程式例:
#include
#include
int main(void)
鍊錶(linked list)
鍊錶是一種物理儲存單元上非連續、非順序的儲存結構
(相對於陣列和可變陣列而言,陣列的儲存方式是在開創的一片連續空間中存入資料,所以其物理儲存單元是連續且順序的)
資料元素的邏輯順序是通過鍊錶中的
指標 鏈結次序實現的。鍊錶由一系列結點(鍊錶中每乙個元素)組成,結點可以在執行時動態生成。
每個結點包括兩個部分:一 .儲存資料元素
的資料域, 指標
域。 由於不必須按順序儲存,鍊錶在插入的時候可以達到o(1)的複雜度,比線性表順序表快得多,但是查詢乙個節點或者訪問特定編號的節點則需要o(n)的時間,而線性表和順序表相應的時間複雜度分別是o(logn)和o(1)。
鍊錶最明顯的好處就是,常規陣列排列關聯專案的方式可能不同於這些資料專案在記憶體或磁碟上順序,資料的訪問往往要在不同的排列順序中轉換。鍊錶允許插入和移除表上任意位置上的節點,但是不允許隨機訪問。
鍊錶有很多種不同的型別:單向鍊錶,雙向鍊錶以及迴圈鍊錶。
鍊錶的提出主要在於順序儲存中的插入和刪除的時間複雜度是線性時間的,而鍊錶的操作則可以是常數時間的複雜度。
others:
1、鏈結儲存方法
鏈結方式儲存的線性表簡稱為鍊錶(linked list)。
鍊錶的具體儲存表示為:
① 用一組任意的儲存單元來存放線性表的結點(這組儲存單元既可以是連續的,也可以是不連續的)
② 鍊錶中結點的邏輯次序和物理次序不一定相同。為了能正確表示結點間的邏輯關係,在儲存每個結點值的同時,還必須儲存指示其後繼結點的位址(或位置)資訊(稱為指標(pointer)或鏈(link))
注意:鏈式儲存是最常用的儲存方式之一,它不僅可用來表示線性表,而且可用來表示各種非線性的資料結構。
2、鍊錶的結點結構
┌——┬——┐
| data | next |
└——┴——┘
資料域---存放資料元素
指標域---存放下乙個結點位址
注意:①鍊錶通過每個結點的鏈域將線性表的n個結點按其邏輯順序鏈結在一起的。
②每個結點只有乙個鏈域的鍊錶稱為單鏈表(single linked list)。
3、頭指標head和終端結點指標域的表示
單鏈表中每個結點的儲存位址是存放在其前趨結點next域中,而開始結點無前趨,故應設頭指標head指向開始結點。
注意:鍊錶由頭指標唯一確定,單鏈表可以用頭指標的名字來命名。
終端結點無後繼,故終端結點的指標域為空,即null。
4、單鏈表的一般圖示法
由於我們常常只注重結點間的邏輯順序,不關心每個結點的實際位置,可以用箭頭來表示鏈域中的指標
線性表
線性表是一種基本的順序儲存資料結構,線性表都是以棧、佇列、字串等特殊線性表的形式來使用的
線性表中所有的元素所佔的儲存空間是連續的,線性表中常用的有鍊錶和順序表,順序表所佔的儲存空間必須連續,鍊錶沒有這個要求,連續指的是儲存空間的連續
從變長陣列到鍊錶,資料組織方式即資料結構的改變,逐步降低了儲存資料的空間複雜度和時間複雜度。
結構可變陣列
開拓空間 array array create int init size 該段 用malloc來為結構體裡面的陣列指標分配乙個我們需要的空間,然後把位址分配給結構體裡面的array 為array結構體分配乙個空間並返回乙個array型別 用於主函式裡面array結構體型別直接複製 恢復空間,清空記...
資料結構 陣列與鍊錶
陣列的特點 1.在記憶體中,陣列是一塊連續的區域 2.陣列需要預留空間,在使用前需要提前申請所佔記憶體的大小,不知道需要多大的空間,可能會浪費記憶體空間,即陣列空間利用率低 3.在陣列起始位置處,插入資料和刪除資料效率低。插入資料時,待插入位置的的元素和它後面的所有元素都需要向後搬移 刪除資料時,待...
真 資料結構 鍊錶(基於陣列)
1.顧名思義 鍊錶就是用一條鏈把資料連線起來。我們可能在其他書中見過基於指標的鍊錶,但是鍊錶的實現不一定只依靠指標,還可以依靠陣列!2.那麼怎麼創造鏈呢,用date陣列來儲存資料,用next陣列來儲存節點 即date陣列的下標 比如next 0 1 next 1 2 next 2 3.這樣就能由ne...