資料結構與演算法 串(基礎)

2021-10-06 21:45:50 字數 3918 閱讀 8395

上上週學習了串的部分知識,今天得空將其中的一些點整理下來。

資料結構中,字串要單獨用一種儲存結構來儲存,稱為串儲存結構。這裡的串指的就是字串。

嚴格意義上講,串儲存結構也是一種線性儲存結構,因為字串中的字元之間也具有"一對一"的邏輯關係。只不過,與之前所學的線性儲存結構不同,串結構只用於儲存字元型別的資料。

一些特殊的命名

空串:儲存 0 個字元的串,例如 s = 「」(雙引號緊挨著);

空格串:只包含空格字元的串,例如 s = " "(雙引號包含 5 個空格);

子串和主串:假設有兩個串 a 和 b,如果 a 中可以找到幾個連續字元組成的串與 b 完全相同,則稱 a 是 b 的主串,b 是 a 的子串。例如,若 a = 「shujujiegou」,b = 「shuju」,由於 a 中也包含 「shuju」,因此串 a 和串 b 是主串和子串的關係;

需要注意的是,空格串和空串不同,空格串中含有字元,只是都是空格而已。另外,只有串 b 整體出現在串 a 中,才能說 b 是 a 的子串,比如 「shujiejugou」 和 「shuju」 就不是主串和子串的關係。

另外,對於具有主串和子串關係的兩個串,通常會讓你用演算法找到子串在主串的位置。子串在主串中的位置,指的是子串首個字元在主串中的位置。

例如,串 a = 「shujujiegou」,串 b = 「jiegou」,通過觀察,可以判斷 a 和 b 是主串和子串的關係,同時子串 b 位於主串 a 中第 6 的位置,因為在串 a 中,串 b 首字元 『j』 的位置是 6。

串儲存結構的具體實現

儲存乙個字串,資料結構包含以下 3 種具體儲存結構:

(1)定長順序儲存:實際上就是用普通陣列(又稱靜態陣列)儲存。

(2)堆分配儲存:用動態陣列儲存字串;

(3)塊鏈儲存:用鍊錶儲存字串;

首先介紹一下串的定長順序儲存:

串的定長順序儲存結構,可以簡單地理解為採用 「固定長度的順序儲存結構」 來儲存字串,因此限定了其底層實現只能使用靜態陣列。

使用定長順序儲存結構儲存字串時,需結合目標字串的長度,預先申請足夠大的記憶體空間。

#include

intmain()

上面這段 c 語言**給大家完美地展示了使用定長順序儲存結構儲存字串。

串的堆分配儲存結構,其具體實現方式是採用動態陣列儲存字串。

通常,程式語言會將程式占有的記憶體空間分成多個不同的區域,程式包含的資料會被分門別類並儲存到對應的區域。拿 c 語言來說,程式會將記憶體分為 4 個區域,分別為堆區、棧區、資料區和**區,其中的堆區是本節所關注的。

與其他區域不同,堆區的記憶體空間需要程式設計師手動使用 malloc 函式申請,並且在不用後要手動通過 free 函式將其釋放。

c 語言中使用 malloc 函式最多的場景是給陣列分配空間,這類陣列稱為動態陣列。例如:

char

* a =

(char*)

malloc(5

*sizeof

(char))

;

此行**建立了乙個動態陣列 a,通過使用 malloc 申請了 5 個 char 型別大小的堆儲存空間。

a =

(char*)

realloc

(a,10

*sizeof

(char))

;

通過使用這行**,之前具有 5 個 char 型儲存空間的動態陣列,其容量擴大為可儲存 10 個 char 型資料。

#include

#include

#include

intmain()

//合併兩個串到 a1 中

for(

int i = lengtha1; i < lengtha1 + lengtha2; i++

)//串的末尾要新增 \0,避免出錯

a1[lengtha1 + lengtha2]

='\0'

;printf

("%s"

, a1)

;//用完動態陣列要立即釋放

free

(a1)

;free

(a2)

;return0;

}

程式執行結果:

data.biancheng.net
注意,程式中給 a1 和 a2 賦值時,使用了 strcpy 複製函式。這裡不能直接用 a1 =「data.biancheng」,程式編譯會出錯,報錯資訊為 「沒有 malloc 的空間不能 free」。因為 strcpy 函式是將字串複製到申請的儲存空間中,而直接賦值是字串儲存在別的記憶體空間(本身是乙個常量,放在資料區)中,更改了指標 a1 和 a2 的指向,也就是說,之前動態申請的儲存空間雖然申請了,結果還沒用呢就丟了。

串的塊鏈儲存,指的是使用鍊錶結構儲存字串。

我們知道,單鏈表中的 「單」 強調的僅僅是鍊錶各個節點只能有乙個指標,並沒有限制資料域中儲存資料的具體個數。因此在設計鍊錶節點的結構時,可以令各節點儲存多個資料。

鍊錶各節點儲存資料個數的多少可參考以下幾個因素:

1.串的長度和儲存空間的大小:若串包含資料量很大,且鍊錶申請的儲存空間有限,此時應盡可能的讓各節點儲存更多的資料,提高空間的利用率(每多乙個節點,就要多申請乙個指標域的空間);反之,如果串不是特別長,或者儲存空間足夠,就需要再結合其他因素綜合考慮;

2.程式實現的功能:如果實際場景中需要對儲存的串做大量的插入或刪除操作,則應盡可能減少各節點儲存資料的數量;反之,就需要再結合其他因素。

#include

#include

#include

#define linknum 3

//全域性設定鍊錶中節點儲存資料的個數

typedef

struct link link;

// nk為節點名,每個節點都是乙個 link 結構體

link *

initlink

(link * head,

char

* str)

;void

displaylink

(link * head)

;int

main()

//初始化鍊錶,其中head為頭指標,str為儲存的字串

link *

initlink

(link * head,

char

* str)

//建立並初始化首元節點

head =

(link*

)malloc

(sizeof

(link));

head->next =

null

; link *temp = head;

//初始化鍊錶

for(

int i =

0; i)else

temp->a[j]

='#';}

if(i*linknum + j < length)

}return head;

}//輸出鍊錶

void

displaylink

(link * head)

temp = temp->next;

}}

程式輸出結果為:

data.biancheng.net
串的基礎就先整理到這裡啦,下次將更新bf演算法(串模式匹配演算法)。

資料結構與演算法(串)

引言 在上次佇列學習後,現在我們再學習串。主要包含kmp演算法,現在就開始資料結構與演算法的 串的學習。定義 串是由零個或者多個字元組成的有限序列,又叫字串。串的大部分操作我們曾經都實現過,這裡重點介紹kmp演算法。樸素模式匹配演算法是我們最容易思考到的一種普通演算法,其時間複雜度可以認為是o n ...

資料結構與演算法基礎

電腦科學的研究物件是問題 解決問題的過程,以及通過該過程得到解決方案。演算法是具有有限步驟的過程,依照這個過程能解決問題。因此,演算法就是解決方案。電腦科學是研究問題及其解決方案,以及研究目前無解的問題的科學。可以簡答的認為電腦科學就是研究演算法的科學。抽象資料元素 沒有實際含義的資料元素,例如 a...

資料結構與演算法基礎

一 資料結構概述 資料結構的主要任務是通過分析資料物件的結構特徵,包括邏輯結構及資料物件之間的關係,然後把邏輯結構表示成計算機課實現的物理結構,從而便於計算機處理。概念術語 二 資料的邏輯結構與物理結構 邏輯結構 logical structure 是指在資料物件中資料元素之間的相互關係。資料元素之...