Java数据结构和算法:字符串、数组和广义表
數組和廣義表是與前述的線性表有所區別的數據結構。它們可以看成是線性表在下述含義上的擴展:線性表中的元素本身也是一個數據結構
字符串
字符串的定義、存儲結構
字符串(string)是由n (n≥0) 個字符組成的有限序列。字符串簡稱為串,一般記為:
s = “a0 a1 … an-1”
其中s是串名;用雙引號括起來的字符序列是串值;ai (0≤i<<n)可以是ASCII碼字符中的可打印字符,通常是字母、數字等字符;
i稱為字符ai 在串中的位置;n稱為串的長度;n =0時,s稱為空串。容易與空串相混淆的一種串是空格串,空格串是由一個或多個空格組成的串,如4個空格組成的空格串“ ”,它的長度是4,而空串的長度為0。
串中任意多個連續的字符組成的子序列稱為該串的子串。子串在該串中的位置就是子串的首字符在該串中的位置。
如果兩個字符串對應位置的字符都相等,且它們長度相等,則稱這兩個字符串相等。
在C++中,串值必須用一對雙引號括起來,但雙引號本身不屬于串。而字符用單引號括起來。串“w”和字符‘w’是兩個不同的概念,前者是字符串,后者是字符。
串是一種線性結構,因此,串既可以用順序存儲結構來存儲,也可以用鏈表存儲結構來存儲。由于每個字符占空間很小,只占8位二進制,所以串通常采用順序存儲結構存儲,它比用鏈式存儲結構存儲效率高,實現起來也方便。
模式匹配算法
設有兩個字符串ob和pat,若要在串ob中查找與串pat相等的子串,則稱ob為主串(或稱目標串),pat為模式串,并稱查找模式串在主串中的匹配位置的運算為模式匹配。
該運算從ob的頭1個字符開始查找一個與串pat (稱作模式串) 相同的子串。
如果在串ob中查找到一個與模式串pat相同的子串,則函數返回模式串pat的頭一個字符在串ob中的位置;
如在主串中未查找到一個與模式串pat相同的子串,則函數返回-1。
在類String中的成員函數find ( )就是模式匹配函數。
Brute-Force算法
Brute-Forc算法的主要思想是:從主串ob = “s0 s1 … sm-1”的第一個字符開始與模式串pat = “t0 t1 … tn-1”的第一個字符比較:
若相等,則繼續比較后續字符;
否則,從主串ob的第二個字符開始重新與模式串pat 的第一個字符比較。
如此繼續,若在主串ob中有一個與模式串相等的連續字符序列,則匹配成功,函數返回模式串pat的首字符在串ob中的位置;
否則,匹配失敗,函數返回-1。
Brute-Force算法是一種帶回溯的算法,也叫樸素的模式匹配算法。在最壞情況下,最多要比較m-n+1趟,每趟比較在最后才出現不等,要做n次比較,總比較次數要達到(m-n+1)?n。通常n會遠遠小于m,因此,算法的最壞情況下運行時間為O(m*n)。
模式匹配的KMP算法
KMP算法是由D.E.Knuth、J.H.Morris和V.R.Pratt三人設計的。該算法是Brute-Force算法的改進。
它消除了Brute-Force算法的如下缺點:主串下標i在若干次對應的字符比較相等后,只要有一次對應字符比較不相等便需要回退。
數組
數組的基本概念
通常,一維數組A(array)是n (n≥0)個相同數據類型的數據元素a0, a1, ?, an-1構成的有限線性序列。其中n叫做數組長度或數組大小,若n=0就是空數組。當每一個數組元素ai(0≤i≤n-1)本身又是一個一維數組時,則A就是一個二維數組。類似地,我們可以構成一個多維數組,一個m(m≥2)維數組中的每一個數組元素是一個m-1維的數組。
可見在一個m(m≥2)維數組中,每一個數組元素受m個線性關系的約束,如果一個元素在每一維中的序號分別為i1、i2、…、im,則稱該元素的下標為:i1、i2、…、im。如果一個數組名為a,則ai1i2…im表示下標為i1、i2、…、im的數組元素。
數組的順序存儲結構
采用順序存儲結構存儲數組的元素,就是按某種順序將數組元素依次存放在內存中的一片連續的存儲單元中。
數組的每個元素的數據類型都相同,因而占有相同的存儲空間。對于一維數組,相鄰元素的起始地址之差為一常數。
稀疏矩陣
在求解科學和工程計算問題時常常會接觸到“矩陣”這類對象。
矩陣本身就是二維數組。對于一個矩陣,如果零元素較多,還是采用上一節所述的存儲方式來存儲的話,就會使得大量的存儲空間存放同一個值零,從而造成事實上的存儲空間的浪費。
本節,將討論這種矩陣如何進行壓縮存儲,以及基本操作的實現。
像這種零元素非常多的矩陣稱為稀疏矩陣。顯然,關于“稀疏”的定義是無法精確給出的。因為稀疏矩陣是非零元素很少的矩陣,我們只要存儲非零元素就行了。
整個稀疏矩陣的存儲結構既可以采用順序結構存儲,也可以采用鏈式結構存儲。
三元組順序表
所有三元組構成了一個三元組表,該三元組表是一個線性表??梢圆捎庙樞虼鎯Y構存儲的三元組表稱為三元組順序表。在三元組順序表中,矩陣非零元素的三元組按照其在矩陣中的位置,以行優先的順序依次存放,并給出行數、列數和非零元素個數。
十字鏈表
當矩陣非零元的位置或個數經常變動時,三元組順序表就不適合于作稀疏矩陣的存儲結構。像作兩個矩陣A與B的加法,把結果保存到A中,將會引起非零元的的變化,并導致非零元的插入和刪除。此時,采用鏈式存儲結構更好些。
稀疏矩陣的十字鏈表,由行鏈表和列鏈表組成,每一個矩陣元素既處于行鏈表中,又處于列鏈表中。這里的行鏈表是一個不帶表頭結點的單鏈表,列鏈表亦是一個不帶表頭結點的單鏈表。
廣義表
線性表、棧、隊列、數組等數據結構都是線性結構,結構中的元素都是同一類型的數據元素。本節所討論的廣義表中元素的數據類型將允許表中元素自身又可以是表。廣義表是線性表的推廣,也有人稱其為列表(lists)。
廣義表的定義
廣義表LS是由n≥0個表元素α1 ,α2 , … , αn 組成的有限序列,其中表元素αi (1≤i≤n) 或者是一個數據元素 (可稱為單元素或原子),或者是一個表(稱為子表)。記作
LS = (α1 ,α2 , … , αn )
其中LS是表名,表的長度為n。長度為0的廣義表為空表。一般用大寫字母表示表名,用小寫字母表示數據元素。如果n≥1,則稱α1 為廣義表LS的表頭(head),稱(α2 , … , αn )為廣義表LS的表尾(tail)。
總結
以上是生活随笔為你收集整理的Java数据结构和算法:字符串、数组和广义表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java数据结构和算法:线性表
- 下一篇: Java数据结构与算法:堆