算法與數據結構01(基礎篇)——邏輯結構與存儲結構

思惟導圖

1、什麼是數據結構

官方定義:數據結構(英語:data structure)是計算機中存儲、組織數據的方式。算法

數據的組織形式,數據元素之間存在的一種或多種特定關係的數據元素集合數組

通俗地講,數據結構 = 存儲結構 + 邏輯結構bash

1.1 基本概念

數據對象:

性質相同的數據元素的集合,是數據的一個子集markdown

數據元素:

數據的基本單位數據結構

數據項

組成數據元素的最小單位 spa

結構體Student就是一種數據結構,定義的name、age數據項Student 建立的 s一、s2... 是具體的 數據元素,由多個s一、s2...構成的數組studentArr[10] 便是數據對象指針

1.2 由此,咱們總結出下方的關係圖

2、邏輯結構

你們耳熟能詳的:線性表(順序表、鏈表)、棧、隊列、字符串、各類圖結構、集合結構、各類樹結構、二維數組、多維數組code

邏輯結構又分爲 線性結構非線性結構orm

2.1 線性結構

一個有序數據元素的集合對象

2.1.1 特色

1.集合中必存在惟一的一個"第一個元素";<br>
2.集合中必存在惟一的一個"最後的元素";<br>
3.除最後元素以外,其它數據元素均有惟一的"後繼";<br>
4.除第一元素以外,其它數據元素均有惟一的"前驅"。<br>
複製代碼

2.1.2 舉例:

線性表(順序表、鏈表)、棧、隊列、字符串

2.2 非線性結構

各個數據元素再也不保持在一個線性序列中,每一個數據元素可能與零個或者多個其餘數據元素髮生聯繫
複製代碼

2.2.1 舉例

各類圖結構、集合結構、樹結構、二維數組、多維數組等

2.3 邏輯結構總結

3、存儲結構

數據元素之間的關係有兩種不一樣的表示方法:順序映象非順序映象,並由此獲得兩種不一樣的存儲結構:順序存儲結構鏈式存儲結構數據的存儲結構是指數據的邏輯結構在計算機中的表示。

下面分別講順序存儲結構和鏈式存儲結構

3.1 順序存儲結構

須要在內存中先開闢一塊 連續的 存儲空間

注意:必定是先開闢空間,並且是連續的。
複製代碼

順序存儲由於須要開闢一塊連續的空間,因此在內存的利用率上不如鏈式結構,當處理增、刪、改的操做時,須要處理後續的每個數據元素,可是在執行查找操做時,按索引找到對應數據元素便可。

3.1.1 順序表的操做

用爲僞代碼或文字演示

// 定義
typedef int ElemType;

typedef struct {
    ElemType *data;
    int length;
} List;
複製代碼

建立

// 建立順序表
List L;
L->data =  malloc(sizeof(ElemType) * MAXSIZE);
L->length = 0;

複製代碼

清空

L->length = 0;
複製代碼

銷燬

free(L)
複製代碼

插入

插入位置i 插入元素e 
一、在L中找到插入位置i,
二、從i到L爲元素依次向後移動一位,此時,L中i的位置空出,
三、將e放入i的位置中,L長度+1,完成插入操做。
複製代碼

刪除

一、根據刪除位置i找到i+1至表尾的全部元素
二、i+1到表尾的元素依次向前移動一位
三、L長度-1 ,完成刪除操做
複製代碼

3.2 鏈式存儲結構

鏈式存儲結構,又叫連接存儲結構。在計算機中用一組任意的存儲單元存儲線性表的數據元素(這組存儲單元能夠是連續的,也能夠是不連續的).
複製代碼

它不要求邏輯上相鄰的元素在物理位置上也相鄰.所以它沒有順序存儲結構所具備的弱點,但也同時失去了順序表可隨機存取的優勢.

3.2.1 鏈式存儲的操做 (以雙鏈表爲例)

只寫出核心步驟

// 定義節點等數據結構
typedef struct Node{
    ElemType data;  // 數據
    struct Node *next;  // 後繼指針 指向下一個節點
    struct Node *pre;   // 前驅指針 指向前一個節點
}Node;

typedef struct Node * List;
複製代碼

3.2.1.1 建立

List L = (List)malloc(sizeof(Node));
L->next = NULL;
L->pre = NULL;
複製代碼

3.2.1.2 插入

問題描述:向p和q節點之間插入s
算法描述:

一、新元素s的後繼指針指向後面的q;
二、q的前驅指針指向s;
三、s的前驅動指針指向前面的p;
四、p的後繼指針指向s;
複製代碼

代碼描述:

s->next = q;
q->pre = s;
s->pre = p;
p->next = s;
複製代碼

或者只用節點p和s

s->next = p->next;
p->next>-pre = s;
s->pre = p;
p->next = s
複製代碼

3.2.1.3 刪除

問題描述:刪除p、s、q順序中的s
算法描述:

一、p的後繼指針指向q;
二、q的前驅指針指向p;
三、銷燬s
複製代碼

代碼描述:

p-next = p->next->next;
p->next->pre = p;
free(s);
複製代碼

3.2.1.4 前插法建立鏈表

算法描述:

核心思想:根據持有的頭節點,新節點始終插入在頭節點以後,成爲新的首元節點
步驟:
一、根據頭節點後找到首元節點,即頭節點以後的節點;
二、建立新節點,新節點的後繼指針指向首元節點;
三、首元節點的前驅指針指向新節點;
四、頭節點的後繼指針指向新節點;
五、新節點的前驅指針指向頭節點;
複製代碼
/* 隨機產生n個元素值,創建帶表頭結點的雙鏈線性表L(前插法)*/
void CreateListHead(LinkList *L, int n)
{
    LinkList p;
    LinkList list;
    
    //創建1個帶頭結點的雙鏈表
    *L = (LinkList)malloc(sizeof(Node));
    list = *L;
    
    list->next = NULL;
    list->pre = NULL;
    
    //循環前插入隨機數據
    for(int i = 0; i < n;i++)
    {
        //生成新結點
        p = (LinkList)malloc(sizeof(Node));
       
        //i賦值給新結點的data
        p->data = i;
        
        // 將原先list的後繼節點和p創建雙指向
        p->next = list->next;
        if (list->next != NULL) list->next->pre = p;
        
        //將結點P插入到頭結點
        list->next = p;
        p->pre = list;
    }
}
複製代碼

3.2.1.5 尾插法建立鏈表

算法描述

核心思想:根據持有的尾節點,每次新插入的節點均插入到鏈表的尾節點以後,成爲新的尾節點。
步驟:
一、將尾節點p的後繼指針指向新節點q;
二、新節點q的前驅指針指向原尾節點p;q已經成了尾節點;
三、尾節點q的next置爲NULL。
複製代碼
/* 隨機產生n個元素值,創建帶表頭結點的單鏈線性表L(後插法)*/
void CreateListTail(LinkList *L, int n)
{
    // p 每次新產生的節點, r 當前的尾節點,每次尾插入後,及時更新r
    LinkList p,r;
 
    //創建一個帶頭結點的雙鏈表
    *L = (LinkList)malloc(sizeof(Node));
    //r指向尾部的結點
    r = *L;
    
    for (int i=0; i<n; i++) {
        
        //生成新結點
        p = (Node *)malloc(sizeof(Node));
        p->data = i;
        
        // 將表尾終端結點的指針指向新結點
        r->next = p;
        // 新尾節點p的前驅指針指向前面的r
        p->pre = r;
        
        //將當前的新結點定義爲表尾終端結點
        r = p;
    }
    
    //將尾指針的next = null
    r->next = NULL;
    
}
複製代碼

3.4 存儲結構總結

相關文章
相關標籤/搜索