1. 程式人生 > >【資料結構和演算法】8 線性表:線性表的順序儲存結構

【資料結構和演算法】8 線性表:線性表的順序儲存結構

線性表的順序儲存結構

線性表有兩種物理儲存結構:

順序儲存結構 和 鏈式儲存結構。

物理上的儲存方式事實上就是在記憶體中找個初始地址,然後通過佔位的形式,把一定的記憶體空間給佔了,然後把相同資料型別的資料元素依次放在這塊空地中。

順序儲存結構:指的是用一段地址連續的儲存單元依次儲存線性表的資料元素。如下,線性表(a1,a2,......,an)的順序儲存結構:

a1

a2

a3

a4

ai-1

ai

ai+1

an

下面來個小甲魚的栗子:

背景:小甲魚帶著咱的魚C旅遊團去看電影,看那個叫3D*蒲團有木有?!哎喲,去到電影院人山人海,但妹子的身影還是難以逃過小甲魚的火眼精金,所以小甲魚猛地帶領眾魚油一把奪下了妹子旁邊的一排位置。。。。。。

建立線性表:小甲魚拿下第一個位置後,魚油們果斷依次坐下,這樣子我們就建立了一個線性表;

特性:例如黑夜喜歡亂吃零食,所以他又拉肚子了。。。但是黑夜買票了,所以他的位置就算空著,也沒有人會坐上去。這就是順序儲存結構的特性之一

線性表的順序儲存結構的程式碼:

#define MAXSIZE 20    
typedef int ElemType;#定義一個型別
typedef struct
{
ElemType data[MAXSIZE];
int length;    // 線性表當前長度
} SqList

這裡我們封裝了一個結構,事實上就是對陣列進行了封裝,增加了一個當前長度的變數罷了;

總結:線性儲存結構封裝需要的三個屬性

(1)線性空間的起始位置,資料data,它的儲存位置就是線性表儲存空間的儲存位置。

(2)線性表的最大儲存容量:陣列的長度MaxSize。

(3)線性表的當前長度:length。

注意:

陣列長度與線性表的當前當度需要區分一下:陣列的長度就是存放線性表的儲存空間總長度,一般初始化後不發生變化;而線性表的當前長度是線性表中元素的個數,是會變化的;

地址計算方法

假設ElemType佔用的是c個儲存單元(位元組),那麼線性表中第i+1個數據元素和第i個數據元素的儲存位置的關係是(LOC表示獲得儲存位置的函式):

LOC(ai+1) = LOC(ai) + c

所以對於第i個數據元素ai的儲存位置可以由a1推算得出:

LOC(ai) = LOC(a1) + (i-1)*c

結合下圖

元素

a1

a2

ai-1

ai

an

空閒空間

下標

0

1

i-2

i-1

n-1

通過這個公式,我們可以隨時計算出線性表中任意位置的地址,不管它是第一個還是最後一個,都是相同的時間。那麼它的儲存時間效能當然就為O(1),我們通常稱為隨機儲存結構;

獲得元素操作

實現getElem:將線性表L中的第i個位置的元素值返回。

分析:就程式而言,我麼你只需要把陣列的第i-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)
{
    if( L.length==0 || i<1 || i>L.length )
    {
        return ERROR;
    }
    *e = L.data[i-1];

    return OK;
}

注意:

(1)根據定義,返回值型別Status是一個整型;

2)約定返回1代表OK,返回0代表ERROR。今後還會出現,也是使用同樣的約定

插入操作

實現listInsert(*L, i, e):線上性表L中的第i個位置插入新元素e。

例子接著舉,剛才的妹子表示願意加入我們魚C旅遊團,因為大家都希望小甲魚把妹子排到自己身邊。但是我們要按我們定下的規則來排:按身高順序

插入演算法的思路:

(1)如果插入的位置不合理,丟擲異常;

(2)如果線性表長度大於等於陣列長度,則丟擲異常或動態增加陣列容量;

(3)從最後一個元素開始向前遍歷到第i個位置,分別將它們都向後移動一個位置;

(4)將要撤入的元素填入位置i處;

(5)線性表的長度增加1;

程式碼實現:

/* 初始條件:順序線性表L已存在,1<=i<=ListLength(L)。 */
/* 操作結果:在L中第i個位置之前插入新的資料元素e,L長度+1。*/

Status ListInsert(SqList *L, int i, ElemType e)
{
    int k;

    if( L->length == MAXSIZE )  // 順序線性表已經滿了
    {
        return ERROR;
    }
    if( i<1 || i>L->length+1)   // 當i不在範圍內時
    {
        return ERROR;
    }
    if( i <= L->length )   // 若插入資料位置不在表尾
    {
        /* 將要插入位置後資料元素向後移動一位 */
        for( k=L->length-1; k >= i-1; k-- )
        {
            L->data[k+1] = L->data[k];
        }
    }

    L->data[i-1] = e;  // 將新元素插入
    L->length++;//線性表長度+1

    return OK;
}

★finished by songpl ,2018.11.26

相關推薦

資料結構演算法8 線性線性順序儲存結構

線性表的順序儲存結構 線性表有兩種物理儲存結構: 順序儲存結構 和 鏈式儲存結構。 物理上的儲存方式事實上就是在記憶體中找個初始地址,然後通過佔位的形式,把一定的記憶體空間給佔了,然後把相同資料型別的資料元素依次放在這塊空地中。 順序儲存結構:指的是用一段地址連續的儲

資料結構演算法6 線性1

線性表的定義 線性表像是排隊一樣,具有像線一樣的性質。 官方定義:線性表(List),是有零個或多個數據元素組成的有限序列; 關於線性表幾個關鍵的地方: (1)首先它是一個序列,也就是說,元素之間是有個先來後到的順序; (2)若元素存在多個,則第一個元素無前驅,而最後一個元素無後

資料結構演算法3~5 時間複雜度空間複雜度

演算法效率的度量方法 容易想到的方法是:把演算法跑若干次,然後拿個計時器在旁邊計時。這種方法被稱為“事後諸葛亮”方法,也稱為事後分析估算方法。 事前分析估算方法:在計算機程式比編寫前,依據統計方法對演算法進行估算。 通過總結,我們發現,一個高階語言編寫程式在計算機上執行所消耗的時間取決於

資料結構演算法2談談演算法

演算法初體驗 高斯演算法"1+2+3+...+100" 普通的解決方法 int i, sum = 0, n = 100; for(i=1; i <= n; i++) { sum = sum + i; } printf(“%d”, sum); 利用高斯的演算法 int i,

資料結構演算法1緒論

寫在前面 本系列博文還是學習小甲魚系列課程《資料結構與演算法》的筆記,目的為了督促自己的學習,順便記錄學習程序! 系列視訊地址:https://www.bilibili.com/video/av21828275 魚C論壇:https://fishc.com.cn/forum.php

資料結構演算法全面剖析樹的各類遍歷方法

面試中常考到樹的前序,中序,後序和層序遍歷,這篇博文就帶你深度剖析一下二叉樹的各類遍歷演算法的實現 二叉樹的遍歷主要有四種,前序、中序、後序和層序 遍歷的實現方式主要是:遞迴和非遞迴 遞迴遍歷的實現非常容易,非遞迴的實現需要用到棧,難度係數要高一點。

scala 資料結構演算法Scala實現氣泡排序

主要內容: 1、氣泡排序演算法原理 2、scala實現 3、python實現 4、goland實現 氣泡排序演算法原理: 1、比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。 2、對

資料結構演算法001 單鏈 LinkedList

   小朋友,你是否有很多問號?為什麼?別人都在看漫畫,而我在學畫畫,對著鋼琴說話...         一、單鏈表(LinkedList)介紹和記憶體佈局 連結串列是有序的列表,它在記憶體中的實際儲存結構如下:     &n

西瓜書學習筆記第3章線性模型

課程前言: arg max的引數是函式最大化的某個函式的域的點,與全域性最大值相比引數函式的最大輸出,arg max指的是函式輸出儘可能大的輸入或引數 閉式解: 給出任意自變數,就可以求出因變數 最小二乘法: 通過最小化誤差的平方和尋找資料的最佳函式匹配

線性(二)——順序儲存結構

線性表的順序儲存結構 構造原理 用一組地址連續的儲存單元依次儲存線性表的資料元素,資料元素之間的邏輯關係通過資料元素的儲存位置直接反映。 記做 ( a1,a2,a3,… … , an ) 所謂一個元素的地址是指該元素佔用的若干(連續的)儲存單元的第一個單元的地址。記做LOC(a

python資料結構演算法總結

一。什麼是演算法 演算法是計算機處理資訊的本質,因為計算機程式本質上是一個演算法來告訴計算機確切的步驟來執行一個指定的任務。一般地,當演算法在處理資訊時,會從輸入裝置或資料的儲存地址讀取資料,把結果寫入輸出裝置或某個儲存地址供以後再呼叫。 通俗的來講,演算法就是你解決問題的思路。 二。演

資料結構演算法線性——刪除重複元素

線性表是一種隨機存取的結構,和連結串列不同,連結串列順序存取的結構。但是,線性表是一種順序儲存的結構,而連結串列是鏈式儲存結構。兩者都是線性的,但區別不同。   進入主題: 1.假如有一串資料元素,要求刪除其中的重複元素。 首先想到的是用兩層迴圈,第一層從第一個元素開始,第

專欄資料結構演算法之美-為什麼很多程式語言中的陣列都是從 0 開始的

學習筆記 陣列的特徵 1.線性表 資料排成像一條線一樣的結構,資料之間只是簡單的前後關係。除了陣列是一種線性表結構外,連結串列、佇列和棧也是。與之對應的像二叉樹、堆、圖等就是非線性表。 2.使用連續

資料結構演算法062-3-4樹

    從第4節的分析中可以看出,二叉搜尋樹是個很好的資料結構,可以快速地找到一個給定關鍵字的資料項,並且可以快速地插入和刪除資料項。但是二叉搜尋樹有個很麻煩的問題,如果樹中插入的是隨機資料,則執行效果很好,但如果插入的是有序或者逆序的資料,那麼二叉搜尋樹的執行速度就變得很慢

資料結構演算法自己動手實現圖的BFSDFS(附完整原始碼)

圖的儲存結構    本文的重點在於圖的深度優先搜尋(DFS)和廣度優先搜尋(BFS),因此不再對圖的基本概念做過多的介紹,但是要先大致瞭解下圖的幾種常見的儲存結構。    鄰接矩陣    鄰接矩陣既可以用來儲存無向圖,也可以用來儲存有向圖。該結構實際上就是用一個二維陣列(鄰接

資料結構演算法14歸併排序

        歸併演算法的中心是歸併兩個已經有序的陣列。歸併兩個有序陣列A和B,就生成了第三個陣列C,陣列C包含陣列A和B的所有資料項,並且使它們有序的排列在陣列C中。首先我們來看看歸併的過程,然後看它是如何在排序中使用的。         假設有兩個有序陣列,不要求有相

資料結構演算法內部排序之四歸併排序快速排序(含完整原始碼)

前言      之所以把歸併排序和快速排序放在一起探討,很明顯兩者有一些相似之處:這兩種排序演算法都採用了分治的思想。下面來逐個分析其實現思想。歸併排序實現思想       歸併的含義很明顯就是將兩個或者兩個以上的有序表組合成一個新的有序表。歸併排序中一般所用到的是2-路歸併

資料結構演算法17拓撲排序

        這一節我們學習一個新的排序演算法,準確的來說,應該叫“有向圖的拓撲排序”。所謂有向圖,就是A->B,但是B不能到A。與無向圖的區別是,它的邊在鄰接矩陣裡只有一項(友情提示:如果對圖這種資料結構部不太瞭解的話,可以先看一下這篇博文:資料結構和演算法之 無向

練習資料結構演算法複習題

題目:a=10,b=15,將a / b的值互換。 通常我們的做法是(尤其是在學習階段):定義一個新的變數,藉助它完成交換。程式碼如下: int a,b; a=10; b=15; int t; t=a; a=b; b=t; 這種演算法易於理解,特別適合幫助初學者瞭解計算機程式的特點,是賦值語句的經典應用。在實際

Python資料結構演算法陣列列表

2018-7-17 北京暴雨 一週多沒更新了,總是往醫院跑。 根據Pegasus Wang 大佬的教程,邊學邊做 抽象資料型別ADT Abstract Data Type,抽象資料型別,我們在組合已有的資料結構來實現一種新的資料型別, ADT 定義了型別