數(shù)據(jù)結(jié)構(gòu)筆記(一)


第1章 數(shù)據(jù)結(jié)構(gòu)緒論

第2章 算法

第3章 線性表


第1章 數(shù)據(jù)結(jié)構(gòu)緒論

  • 程序設計 = 數(shù)據(jù)結(jié)構(gòu) + 算法

邏輯結(jié)構(gòu)與物理結(jié)構(gòu)

邏輯結(jié)構(gòu)

  1. 集合結(jié)構(gòu)
  2. 線性結(jié)構(gòu)
  3. 樹形結(jié)構(gòu)
  4. 圖形結(jié)構(gòu)

物理結(jié)構(gòu)

  • 物理結(jié)構(gòu):是指數(shù)據(jù)的邏輯結(jié)構(gòu)在計算機中的存儲形式。
  1. 順序存儲結(jié)構(gòu):把數(shù)據(jù)元素存放在地址連續(xù)的存儲單元里,其數(shù)據(jù)間的邏輯關系和物理關系是一致的。
  2. 鏈式存儲結(jié)構(gòu):把數(shù)據(jù)元素存放在任意的存儲單元里,這組存儲單元可以是連續(xù)的,也可以是不連續(xù)的。

第2章 算法

算法是解決特定問題求解步驟的描述,在計算機中表現(xiàn)為指令的有限序列,并且每條指令表示一個或多個操作。

算法的特性

  1. 輸入輸出:有零個或多個輸入,至少有一個或多個輸出。
  2. 有窮性
  3. 確定性
  4. 可行性

算法設計的要求

  1. 正確性
  2. 可讀性
  3. 健壯性
  4. 時間效率高和存儲量低

算法時間復雜度

定義:在進行算法分析時,語句總的執(zhí)行次數(shù)T(n)是關于問題規(guī)模n的函數(shù),進而分析T(n)隨n的變化情況并確定T(n)的數(shù)量級。算法的時間復雜度,也就是算法的時間度量,記作:T(n) = O(f(n))。它表示隨問題規(guī)模n的增大,算法執(zhí)行時間的增長率和f(n)的增長率相同,稱作算法的漸進時間復雜度,簡稱為時間復雜度。其中f(n)是問題規(guī)模n的某個函數(shù)。
這樣用大寫O()來體現(xiàn)算法時間復雜度的記法,稱之為大O記法。

推導大O階

  1. 用常數(shù)1取代運行時間中的所有加法常數(shù)
  2. 在修改后的運行次數(shù)函數(shù)中,只保留最高階項。
  3. 如果最高階項存在且不是1,則去除與這個項相乘的常數(shù)。
    得到的結(jié)果就是大O階。

常用的時間復雜度所消耗的時間從小到大依次是:
O(1) < O(logn) < O(n) < O(nlogn) < O(n(2)) < O(n(3)) < O(2(2)) < O(n!) < O(n(n))

算法的空間復雜度

算法的空間復雜度通過計算算法所需的存儲空間實現(xiàn),算法空間復雜度的計算公式記作:S(n) = O(f(n)),其中,n為問題的規(guī)模,f(n)為語句關于n所占存儲空間的函數(shù)。

第3章 線性表

線性表(List):零個或多個數(shù)據(jù)元素的有限序列。

a(i-1)是a(i)的直接前驅(qū)元素,a(i+1)是a(i)的直接后繼元素。

線性表的抽象數(shù)據(jù)類型定義

ADT 線性表(List)
Data
    線性表的數(shù)據(jù)對象集合為{a1,a2,...,an},每個元素的類型均為DataType。其中,除第一個元素a1外,每一個元素有且只有一個直接前驅(qū)元素,除了最后一個元素an外,每一個元素有且只有一個直接后繼元素。數(shù)據(jù)元素之間的關系是一對一的關系。
Operation
    InitList(*L):初始化操作,建立一個空的線性表L。

    ListEmpty(L):若線性表為空,返回true,否則返回false。

    ClearList(*L):將線性表清空。

    GetElem(L,i,*e):將線性表L中的第i個位置元素返回給e。

    LocaEleme(L,i,*e):將線性表L中查找與定位值e相等的元素,如果查找成功,返回該元素在表中序號表示成功;否則,返回0表示失敗。

    ListInsert(*L,i,e):在線性表L中的第i個位置插入新元素e。

    ListDelete(*L,i,e):在線性表L中的第i個位置元素,并用e返回其值。
    ListLength(L):返回線性表L的元素個數(shù)。
endADT

線性表的順序存儲結(jié)構(gòu)

  • 順序存儲定義:指的是用一段地址連續(xù)的存儲單元依次存儲線性表的數(shù)據(jù)元素。

  • 順序存儲方式:一維數(shù)組來實現(xiàn)順序存儲結(jié)構(gòu)。

線性表的順序存儲的結(jié)構(gòu)代碼:

#define MAXSIZE 20 /*存儲空間初始分配量*/
typedef int ElemType;/*ElemType類型根據(jù)實際情況而定,這里假設為int*/
typedef struct
{
    ElemType data[MAXSIZE];/*數(shù)組存儲數(shù)據(jù)元素,最大值為MAXSIZE*/
    int length;/*線性表當前長度*/
}SQList;

順序存儲結(jié)構(gòu)需要三個屬性:

  • 存儲空間的起始位置:數(shù)組data,它的存儲位置就是存儲空間的存儲位置。
  • 線性表的最大存儲容量:數(shù)組長度MaxSize。
  • 線性表的當前長度:Length。

用數(shù)組存儲順序表意味著要分配固定長度的數(shù)組空間,由于線性表中可以進行插入好人刪除操作,因此分配的數(shù)組空間要大于等于當前線性表的長度。

存儲器中的每個存儲元素都有自己的編號,這個編號成為地址。

順序存儲結(jié)構(gòu)的插入與刪除

  • 獲得元素操作
    實現(xiàn)GetElem操作,將線性表L中的第i個位置元素值返回。就程序而言,只要i的數(shù)值在數(shù)組下標范圍內(nèi),就是把數(shù)組第i-1下標的值返回即可。
#define ok 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Status;
Status是函數(shù)的類型,其值是函數(shù)結(jié)果狀態(tài)代碼,如OK等
初始條件:順序線性表L已存在,1<= i <= ListLength(L)
操作結(jié)果:用e返回L中第i個數(shù)據(jù)元素的值
Status GetElem (SqList L, int i, ElemType *e)
{
if(L.length==0 || i>L.length)
    return ERROR;
    *e=L.data[i-1];
    return OK;
}

插入操作

插入算法的思路:

  • 如果插入位置不合理,拋出異常;
  • 如果線性表長度大于等于數(shù)組長度,則拋出異常或動態(tài)增加容量;
  • 從最后一個元素開始向前遍歷到第i個位置,分別將它們都向后移動一個位置;
  • 將要插入元素填入位置i處;
  • 表長加1;
    代碼實現(xiàn):
初始條件:順序線性表L已存在,1<= i <= ListLength(L)
操作結(jié)果:在L中第i個位置之前插入新的數(shù)據(jù)元素e,L的長度加1

Status ListInsert(SqLsit *L, int i,ElemType e)
{
int k;
    if (L->length == MAXSIZE)/*順序線性表已經(jīng)滿*/
        return ERROR;
    if(i<1 || i>L->length+1)/*當i不在范圍內(nèi)時*/
        return ERROR;
    if(i<=L->length)/*若插入數(shù)據(jù)位置不在表尾*/
    {
        for(k=L->length-1;k>=i-1;k--)/*將要插入位置后數(shù)據(jù)元素向后移動一位*/
            L->data[k+1] = L->data[k];
    }
    L->data[i-1] = e;/*將新元素插入*/
    L-length++;
    return OK;
}

刪除操作

算法思路:

  • 如果刪除位置不合理,拋出異常;
  • 取出刪除元素;
  • 從刪除元素位置開始遍歷到最后一個元素位置,分別將它們都向前移動一個位置;
  • 表長減1.

線性表順序存儲結(jié)構(gòu)的優(yōu)缺點

優(yōu)點

  • 無須為表示表中元素之間的邏輯關系而增加額外的存儲空間
  • 可以快速的存取表中任一位置元素

缺點

  • 插入和刪除操作需要移動大量元素
  • 當線性表長度變化較大時,難以確定存儲空間的容量
  • 造成存儲空間的"碎片"

線性表的鏈式存儲結(jié)構(gòu)

為了表示每個數(shù)據(jù)元素ai與其直接后繼數(shù)據(jù)元素ai+1之間的邏輯關系,對數(shù)據(jù)元素ai來說,除了存儲其本身的信息之外,還需存儲一個指示其直接后繼的信息(即直接后繼的存儲位置)。我們把存儲數(shù)據(jù)元素信息的域稱為數(shù)據(jù)域,把存儲直接后繼位置的域稱為指針域。指針域中存儲的信息稱為指針或鏈。
數(shù)據(jù)域 + 指針域 = 結(jié)點

鏈表中第一個結(jié)點的存儲位置叫做頭指針,最后一個結(jié)點指針為“空”,用NULL或^表示。

頭指針與頭結(jié)點的異同

頭指針
  • 頭指針是指鏈表指向第一個結(jié)點的指針,若鏈表有頭結(jié)點,則是指向頭結(jié)點的指針
  • 頭指針具有標示作用,所以常用頭指針冠以鏈表的名字
  • 無論鏈表是否為空,頭指針均不為空。頭指針是鏈表的必要元素。
頭結(jié)點
  • 頭結(jié)點是為了操作的統(tǒng)一和方便而設立的,放在第一元素的結(jié)點之前,其數(shù)據(jù)域一般無意義(也可存放鏈表的長度)
  • 有了頭結(jié)點,對在第一元素結(jié)點前插入結(jié)點和刪除第一結(jié)點,其操作與其他結(jié)點的操作系統(tǒng)就統(tǒng)一了
  • 頭結(jié)點不一定是鏈表必須要素

單鏈表的讀取

獲取鏈表第i個數(shù)據(jù)的算法思路

  1. 聲明一個結(jié)點p指向鏈表第一個結(jié)點,初始化j從1開始;
  2. 當j<i時,就遍歷鏈表,讓p的指針向后移動,不斷指向下一結(jié)點,j累加1;
  3. 若到鏈表末尾p為空,則說明第i個元素不存在;
  4. 否則查找成功,返回結(jié)點p的數(shù)據(jù)。

單鏈表的插入與刪除

單鏈表第i個數(shù)據(jù)插入結(jié)點的算法思路

  1. 聲明一節(jié)點p指向鏈表第一個結(jié)點,初始化j從1開始;
  2. 當j<i時,就遍歷鏈表,讓p的指針向后移動,不斷指向下一結(jié)點,j累加1;
  3. 若到鏈表末尾p為空,則說明第i個元素不存在;
  4. 否則查找成功,在系統(tǒng)中生成一個空結(jié)點s;
  5. 將數(shù)據(jù)元素e賦值給s->data;
  6. 單鏈接的插入標準語句s -> next = p -> next; p ->next = s;
  7. 返回成功。

單鏈表第i個數(shù)據(jù)刪除結(jié)點的算法思路

  1. 聲明一節(jié)點p指向鏈表第一個結(jié)點,初始化j從1開始;
  2. 當j<i時,就遍歷鏈表,讓p的指針向后移動,不斷指向下一個結(jié)點,j累加1;
  3. 若到鏈表末尾p為空,則說明第i個元素不存在;
  4. 否則查找成功,將欲刪除的結(jié)點p->next賦值給q;
  5. 單鏈表的刪除標準語句p->next = q->next;
  6. 將q結(jié)點中的數(shù)據(jù)賦值給e,作為返回;
  7. 釋放q結(jié)點;
  8. 返回成功。

對于插入或刪除數(shù)據(jù)越頻繁的操作,單鏈表的效率優(yōu)勢就越是明顯

單鏈表的整表創(chuàng)建

單鏈表整表創(chuàng)建的算法思路:

  1. 聲明一結(jié)點p和計數(shù)器變量i;
  2. 初始化一空鏈表L;
  3. 讓L的頭結(jié)點的指針指向NULL,即建立一個帶頭結(jié)點的單鏈表;
  4. 循環(huán)
    • 生成一新結(jié)點賦值給p;
    • 隨機生成一數(shù)字賦值給p的數(shù)據(jù)域p->datd;
    • 將p插入到頭結(jié)點與前一新結(jié)點之間。

單鏈表的整表刪除

單鏈表整表刪除的算法思路如下:

  1. 聲明一結(jié)點p和q;
  2. 將第一個結(jié)點賦值給p;
  3. 循環(huán)
    • 將下一結(jié)點賦值給q;
    • 釋放p;
    • 將q賦值給p。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內(nèi)容