學習筆記2 4 加工並儲存資料的資料結構

2021-10-03 10:20:26 字數 4236 閱讀 3384

2.4.2.1優先佇列

能夠完成下列操作的資料結構叫做優先佇列。

1.插入乙個數值

2.取出最小的數值(獲得數值,並且刪除)

能夠使用二叉樹高效地解決上述問題地,是一種叫做的資料結構。

2.4.2.2 堆的結構

堆最重要的性質就是兒子的值一定不小於父親的值。除此之外,樹的節點是按從上到下,從左到右的順序緊湊排列的。

在向堆種插入數值時,首先在堆的末尾插入該數值,然後不斷向上提公升直到父親節點小於當前節點為止。

從堆中刪除最小值時,首先把堆的最後乙個節點的數值複製到根節點上,並且刪除最後乙個節點。然後不斷向下交換直到沒有大小顛倒為止

堆的操作的複雜度:堆的兩種操作所化的時間都和樹的深度成正比。因此,如果一共有n個元素,那麼每個操作可以在o(logn)的時間內完成。

堆的實現:

1.左兒子的編號是自己的編號 x 2 + 1

2.右兒子的編號是自己的編號 x 2 + 2

int heap[maxn]

,sz=0;

void

push

(int x)

heap[i]

=x;}

intpop()

heap[i]

=x;return ret;

}

程式語言的標準庫:實際上,大部分情況下不需要自己實現堆。c++的stl裡的priority_queue就是乙個堆(這個堆預設的是最大值在前面)push()入堆,top()堆頂元素,pop()刪除堆頂元素,empty()堆是否為空。

例題:poj 2431 expedition

由於加油站數量n非常大,必須想乙個高效的解法。

我們稍微變換下思考方式。在卡車開往終點的途中,只有在加油站才可以加油。但是,如果認為「在到達加油站i時,就獲得了一次在之後的任何時候都可以加bi單位汽油的權利」,在解決問題上應該也是一樣的。而在之後需要加油時,就認為是在之前經過的加油站加的油就可以了。

那麼,因為希望到達終點時加油次數盡可能少,所以當燃料為0了之後再進行加油看上去是乙個不錯的方法,並且每次選擇加油量最大的加油站。

1.在經過加油站i時,往優先佇列裡加入bi

2.當燃料箱空了時,(1)如果優先佇列也是空,則無法到達終點。(2)否則取出優先佇列的最大元素,並用來給卡車加油。

int l,p,n;

//l代表路程長度,p代表初始油量,n代表加油站個數

int a[maxn+1]

,b[maxn+1]

;void

solve()

tank+

=pq.

top();

pq.pop();

ans++;}

tank-

=d; pq.

push

(b[i]);

pos=a[i];}

cout << ans << endl;

}

fence repair 我們重寫一下之前的貪心例題

我們只需要從板的集合裡取出最短的兩塊,並且把長度為兩塊板長度之和的板加入集合中即可。o(nlogn)

typedef

long

long ll;

int n,l[maxn]

;void

solve()

que.

push

(t);

} cout << ans << endl;

}

2.4.3.1 二叉搜尋樹的結構

二叉搜尋樹是能夠高效地進行如下操作的資料結構。

//表示節點的結構體

struct node

;node *

insert

(node * p,

int x)

else

}bool

find

(node * p,

int x)

node *

remove

(node * p,

int x)

else

if(p-

>lch-

>rch==

null

)else

node * r=q-

>rch;

r->rch=p-

>rch;

q->rch=

null

;delete p;

return r;

}return p;

}

程式語言的標準庫

c++中,stl有set和map容器。set是像前面所說的一樣使用二叉搜尋樹維護集合的容器,而map則是維護鍵和鍵對應的值的容器。set方法insert()新增元素,find()查詢元素,count()也是查詢元素,set<>::iterator it迭代器,begin()開始指標,end()結束後一位指標,erase()刪除元素。

map方法,insert()插入元素(需要是乙個pair物件)map<,>::iterator it迭代器,find()根據鍵查詢物件,返回乙個pair型別的迭代器物件。

1.並查集是什麼

並查集是一種用來管理元素分組情況的資料結構。並查集可以高效地進行如下操作。不過需要注意並查集雖然可以進行合併操作,但是無法進行分割操作。

2.並查集的結構

並查集也是用樹形結構實現的。

每個元素對應乙個節點,每個組對應一棵樹。在並查集中,哪個節點是哪個節點的父親節點以及形狀等資訊無需多加關注,整體組成乙個樹形結構才是重要的。

(1).初始化

我們準備n個節點來表示n個元素,最開始時沒有邊。

(2).合併

從乙個組的根向另乙個組的根連邊,這樣兩棵樹就變成了一棵樹了。也就把兩個組合並為乙個組了。

(3)查詢

為了查詢兩個節點是否屬於同一組,我們需要沿著樹往上走,來查詢包含這個元素的樹的根是誰。如果兩個節點走到了同乙個根,那麼就可以知道它們屬於同乙個組。

3.並查集實現中的注意點

在樹形資料結構中,如果發生了退化的情況,那麼複雜度就會變得很高。並查集中,只需要按照這種方法就可以避免退化。

對於每棵樹,記錄這棵樹的高度(rank)

合併時如果兩棵樹的rank不同,那麼從rank小的rank大的連邊。

此外通過路徑壓縮,可以使得並查集更加高效,對於每個節點一旦向上走到了乙個根節點,就把這個點到父親的邊改為直接連向根。

在此之上,不僅僅使所查詢的節點,在查詢過程中向上所經過的所有的節點,都改為直接連到根上,這樣再次查詢這些節點時就很快知道根是誰了。

4.並查集的複雜度

o(α(n)),是o(logn)的反函式,比o(logn)還快。

5.並查集的實現

int par[maxn]

;int rank[maxn]

;void

init

(int n)

}int

find

(int x)

void

unite

(int x,

int y)

else

}bool

same

(int x,

int y)

例題:poj 1182 食物鏈

對於每只動物i建立三個元素i-a,i-b,i-c,並用這3 x n元素建立並查集。這個並查集維護如下資訊:

int n,k;

int t[maxn]

,x[maxn]

,y[maxn]

;//這裡省略了並查集的部分**

void

solve()

if(t==1)

unite

(x,y)

;unite

(x+n,y+n)

;unite

(x+2

*n,y+

2*n);}

else

unite

(x,y+n)

;unite

(x+n,y+

2*n)

;unite

(x+2

*n,y);}

}}

《誰說菜鳥不會資料分析》 學習筆記四 資料加工

一 資料抽取 資料抽取,是指保留原資料表中某些欄位的部分資訊,組合成乙個新字段。可以是某一字段的部分資訊 欄位分列 也可以是將某幾個字段合併為乙個新字段 欄位合併 還可以是將原資料表沒有但其他資料表中有的字段,有效的匹配起來 欄位匹配。a 字段分列 1 選單法。資料 分列 分隔符號 按相同的分隔符進...

Android 學習筆記14 資料儲存

android的資料儲存有4中方式 sharedpreferences sqlite content provider和file sharepreferences 提供輕量型資料儲存,一般使用者儲存配置資訊 本質上是xml檔案上的鍵值對,通常用來儲存一些簡單的配置資訊。其儲存位置在 data dat...

HIVE學習筆記 資料儲存

基於hdfs 沒有專門的資料儲存格式 儲存結構主要包括 資料庫 檔案 表 檢視 可以直接載入文字檔案 txt csv等 建立表時,指定hive資料的列分隔符與行分隔符 表 內部表 分割槽表 外部表 桶表 內部表 與資料庫中的tale在概念上類似 每乙個table在hive中都有乙個相應的目錄儲存資料...