国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站建設(shè)優(yōu)質(zhì)公司百度怎么搜索網(wǎng)址打開網(wǎng)頁

網(wǎng)站建設(shè)優(yōu)質(zhì)公司,百度怎么搜索網(wǎng)址打開網(wǎng)頁,網(wǎng)頁設(shè)計(jì)心得體會總結(jié),怎么修改網(wǎng)站源文件🐶博主主頁:??. 一懷明月? ???🔥專欄系列:線性代數(shù),C初學(xué)者入門訓(xùn)練,題解C,C的使用文章,「初學(xué)」C,數(shù)據(jù)結(jié)構(gòu) 🔥座右銘:“不要等到什么都沒…

🐶博主主頁:@??. 一懷明月??

???🔥專欄系列:線性代數(shù),C初學(xué)者入門訓(xùn)練,題解C,C的使用文章,「初學(xué)」C++,數(shù)據(jù)結(jié)構(gòu)

🔥座右銘:“不要等到什么都沒有了,才下定決心去做”

🚀🚀🚀大家覺不錯(cuò)的話,就懇求大家點(diǎn)點(diǎn)關(guān)注,點(diǎn)點(diǎn)小愛心,指點(diǎn)指點(diǎn)🚀🚀🚀

目錄

樹的概念

樹的表示

二叉樹

二叉樹概念:

特殊的二叉樹

二叉樹的性質(zhì)

二叉樹的存儲結(jié)構(gòu)

2. 鏈?zhǔn)酱鎯?/p>

二叉樹的順序結(jié)構(gòu)

堆的概念及結(jié)構(gòu)

堆排序?

堆排序的實(shí)現(xiàn)

建堆

堆排序

TOPK


樹的概念

樹是一種非線性的數(shù)據(jù)結(jié)構(gòu),它是由n(n>=0)個(gè)有限結(jié)點(diǎn)組成一個(gè)具有層次關(guān)系的集合。把它叫做樹是因?yàn)樗雌饋硐褚豢玫箳斓臉?#xff0c;也就是說它是根朝上,而葉朝下的。

圖1

圖2

節(jié)點(diǎn)的度:一個(gè)節(jié)點(diǎn)含有的子樹的個(gè)數(shù)稱為該節(jié)點(diǎn)的度;如圖2:A的度為6

葉節(jié)點(diǎn)(終端節(jié)點(diǎn)):度為0的節(jié)點(diǎn)稱為葉節(jié)點(diǎn);如圖2:B、C、H、I...等為葉節(jié)點(diǎn)

父節(jié)點(diǎn)(雙親節(jié)點(diǎn)):若一個(gè)節(jié)點(diǎn)含有子節(jié)點(diǎn),則這個(gè)節(jié)點(diǎn)稱為其子節(jié)點(diǎn)的父節(jié)點(diǎn);如圖2:A是B的父節(jié)點(diǎn)

子節(jié)點(diǎn)(孩子節(jié)點(diǎn)):一個(gè)節(jié)點(diǎn)含有的子樹的根節(jié)點(diǎn)稱為該節(jié)點(diǎn)的子節(jié)點(diǎn);如圖2:B是A的子節(jié)點(diǎn)

兄弟節(jié)點(diǎn):具有相同父節(jié)點(diǎn)的節(jié)點(diǎn)互稱為兄弟節(jié)點(diǎn);如圖2:B、C是兄弟節(jié)點(diǎn)

樹的度:一顆樹中,最大的節(jié)點(diǎn)的度稱為樹的度;如圖2:樹的度為6

節(jié)點(diǎn)的層次:從根開始定義起,根為第一層,根的子節(jié)點(diǎn)為第二層,依次類推

樹的高度(樹的深度):樹中節(jié)點(diǎn)的最大層次;如圖2:樹的高度為4

堂兄弟節(jié)點(diǎn):雙親在同一層的節(jié)點(diǎn)互為堂兄弟;如圖2:H、I互為堂兄弟節(jié)點(diǎn)

節(jié)點(diǎn)祖先:從根到該節(jié)點(diǎn)所經(jīng)分支上的所有節(jié)點(diǎn);如圖2;A是所有節(jié)點(diǎn)的祖先

子孫:以某節(jié)點(diǎn)為根的子樹中任一節(jié)點(diǎn)都稱為該節(jié)點(diǎn)的子孫;如圖2:所有節(jié)點(diǎn)都是A的子孫

森林:由m(m>0)棵互不相交的樹的集合稱為森林

樹的表示

樹結(jié)構(gòu)相對線性表就比較復(fù)雜了,要存儲表示起來就比較麻煩了,既然保存值域,也要保存結(jié)點(diǎn)和結(jié)點(diǎn)之間的關(guān)系,實(shí)際中樹有很多種表示方式如:雙親表示法,孩子表示法、孩子雙親表示法以及孩子兄弟表示法等。我們這里就簡單的了解其中最常用的孩子兄弟表示法,即左孩子右兄弟表示法。

typedef int DataType;
struct Node
{
struct Node* _firstChild1; // 第一個(gè)孩子結(jié)點(diǎn)
struct Node* _pNextBrother; // 指向其下一個(gè)兄弟結(jié)點(diǎn)
DataType _data; // 結(jié)點(diǎn)中的數(shù)據(jù)域
};

圖3

樹在實(shí)際中的運(yùn)用:表示文件系統(tǒng)的目錄樹結(jié)構(gòu)

圖4

二叉樹

二叉樹概念:

二叉樹(Binary Tree)是n(n>=0)個(gè)結(jié)點(diǎn)的有限集合,該集合或者空集(稱為空二叉樹),或者由一個(gè)根節(jié)點(diǎn)和兩顆互不相交的,分別稱為根節(jié)點(diǎn)的左子樹和右子樹的二叉樹組成。

圖5

(1)二叉樹的最大度為2;

(2)每個(gè)結(jié)點(diǎn)最多有兩棵子樹;

(3)左子樹和右子樹是有順序的;

(4)即使樹中某結(jié)點(diǎn)只有一顆子樹,也要區(qū)分左右;

注意:對于任意的二叉樹都是由以下幾種情況復(fù)合而成的:

圖6

特殊的二叉樹

1.滿二叉樹:一個(gè)二叉樹,如果每一層的節(jié)點(diǎn)數(shù)都達(dá)到了最大值,則這個(gè)二叉樹就是滿二叉樹。也就是說,如果一個(gè)二叉樹的層數(shù)為k,且節(jié)點(diǎn)總數(shù)是2^k-1,則它是滿二叉樹。

2.完全二叉樹:完全二叉樹是效率很高的數(shù)據(jù)結(jié)構(gòu),完全二叉樹是由滿二叉樹而引出來的。對于深度為k的,有n個(gè)節(jié)點(diǎn)的二叉樹,當(dāng)且僅當(dāng)每一個(gè)節(jié)點(diǎn)都與深度為k的滿二叉樹中編號從1至n的節(jié)點(diǎn)————對應(yīng)時(shí)稱之完全二叉樹。要注意滿二叉樹是一種特殊的完全二叉樹。

?圖7

二叉樹的性質(zhì)

1. 若規(guī)定根節(jié)點(diǎn)的層數(shù)為1,則一棵非空二叉樹的第i層上最多有2^(i-1)個(gè)結(jié)點(diǎn).

2. 若規(guī)定根節(jié)點(diǎn)的層數(shù)為1,則深度為h的二叉樹的最大結(jié)點(diǎn)數(shù)是2^h-1.

3. 對任何一棵二叉樹, 如果度為0其葉結(jié)點(diǎn)個(gè)數(shù)為n0, 度為2的分支結(jié)點(diǎn)個(gè)數(shù)為 n2,則有n0=n2+1

4. 若規(guī)定根節(jié)點(diǎn)的層數(shù)為1,具有n個(gè)結(jié)點(diǎn)的滿二叉樹的深度,h=log2^(n+1) (是log以2為底,n+1為對數(shù))

5. 對于具有n個(gè)結(jié)點(diǎn)的完全二叉樹,如果按照從上至下從左至右的數(shù)組順序?qū)λ泄?jié)點(diǎn)從0開始編號,則對于序號為i的結(jié)點(diǎn)有:

(1. 若i>0,i位置節(jié)點(diǎn)的雙親序號:(i-1)/2;i=0,i為根節(jié)點(diǎn)編號,無雙親節(jié)點(diǎn)

(2. 若2i+1<n,左孩子序號:2i+1,2i+1>=n否則無左孩子

(3. 若2i+2<n,右孩子序號:2i+2,2i+2>=n否則無右孩子

二叉樹的存儲結(jié)構(gòu)

二叉樹一般可以使用兩種結(jié)構(gòu)存儲,一種順序結(jié)構(gòu),一種鏈?zhǔn)浇Y(jié)構(gòu)。

1.順序存儲

順序結(jié)構(gòu)存儲就是使用數(shù)組來存儲,一般使用數(shù)組只適合表示完全二叉樹,因?yàn)椴皇峭耆鏄鋾锌臻g的浪費(fèi)。而現(xiàn)實(shí)中使用中只有堆才會使用數(shù)組來存儲。二叉樹順序存儲在物理上是一個(gè)數(shù)組,在邏輯上是一顆二叉樹

圖8

2. 鏈?zhǔn)酱鎯?/h2>

...

二叉樹的順序結(jié)構(gòu)

普通的二叉樹是不適合用數(shù)組來存儲的,因?yàn)榭赡軙嬖诖罅康目臻g浪費(fèi)。而完全二叉樹更適合使用順序結(jié)構(gòu)存儲?,F(xiàn)實(shí)中我們通常把堆(一種二叉樹)使用順序結(jié)構(gòu)的數(shù)組來存儲,需要注意的是這里的堆和操作系統(tǒng)虛擬進(jìn)程地址空間中的堆是兩回事,一個(gè)是數(shù)據(jù)結(jié)構(gòu),一個(gè)是操作系統(tǒng)中管理內(nèi)存的一塊區(qū)域分段

堆的概念及結(jié)構(gòu)

如果有一個(gè)關(guān)鍵碼的集合K = {k0,k1,k2,...,k[n-1] },把它的所有元素按完全二叉樹的順序存儲方式存儲

在一個(gè)一維數(shù)組中,并滿足: Ki<=K[2*i+1] 且Ki<=K[2*i+2](Ki>=K[2*i+1] 且Ki>=K[2*i+2]),i=0,1,2...n

則稱為小堆(或大堆)。將根節(jié)點(diǎn)最大的堆叫做最大堆或大根堆,根節(jié)點(diǎn)最小的堆叫做最小堆或小根堆。

堆的性質(zhì):

堆中某個(gè)節(jié)點(diǎn)的值總是不大于或不小于其父節(jié)點(diǎn)的值;

堆總是一棵完全二叉樹

圖9

堆排序?

堆排序是利用堆這種數(shù)據(jù)結(jié)構(gòu)而設(shè)計(jì)的一種排序算法,他的時(shí)間復(fù)雜度是O(N*logN)相較于冒泡排序(O(N*N))他的時(shí)間效率非常高。

堆排序的實(shí)現(xiàn)

1.將無序序列構(gòu)建成一個(gè)堆,根據(jù)升序(降序)需求選擇大根堆(小根堆)

2.將堆頂元素與末尾元素交換,將最大元素(最小元素)“沉”到數(shù)組末端

3.重新調(diào)整結(jié)構(gòu)使其滿足堆定義,然后繼續(xù)交換堆頂元素與當(dāng)前末尾元素,反復(fù)執(zhí)行調(diào)整+交換步驟,直到整個(gè)序列有序

建堆

建堆有著兩種建堆的方法,向上調(diào)整建堆和向下調(diào)整建堆,不管是建大根堆還是小根堆這兩種方法都可以。

向上調(diào)整:

這里是準(zhǔn)備建小根堆,Swap是交換函數(shù)(交換兩個(gè)變量的值),判斷最后一個(gè)孩子節(jié)點(diǎn)child的值是否比其父節(jié)點(diǎn)parent的值小,如果child的值比parent的值小,就交換父子節(jié)點(diǎn)的值,然后孩子節(jié)點(diǎn)child的位置移到父節(jié)點(diǎn)parent的位置,父節(jié)點(diǎn)parent移到父節(jié)點(diǎn)的父節(jié)點(diǎn),然后再次判斷孩子節(jié)點(diǎn)child的值與父節(jié)點(diǎn)parent的值的大小,直到child移到了根節(jié)點(diǎn),如果child的值比parent的值如果大,就不用交換并且說明本次調(diào)整完成。

void AdjustUP(int* a,int n)
{int child=n-1;int parent=(child-1)/2;while(child>0){if(a[child]<a[parent]){Swap(&a[child], &a[parent]);child=parent;parent=(child-1)/2;}else{break;}}
}

向下調(diào)整:

這里是準(zhǔn)備建小根堆,判斷父節(jié)點(diǎn)parent的值是否比其孩子節(jié)點(diǎn)child(一般父節(jié)點(diǎn)都有兩個(gè)孩子節(jié)點(diǎn),這里的孩子節(jié)點(diǎn)是兩個(gè)中較小的那個(gè))的值小,如果child的值比parent的值小,就交換父子節(jié)點(diǎn)的值,然后父節(jié)點(diǎn)parent的位置移到孩子節(jié)點(diǎn)child的位置,孩子節(jié)點(diǎn)child移到孩子節(jié)點(diǎn)的孩子節(jié)點(diǎn)的位置,然后再次判斷孩子節(jié)點(diǎn)child的值與父節(jié)點(diǎn)parent的值的大小,直到child的值大于元素個(gè)數(shù),如果child的值比parent的值如果大,就不用交換并且說明本次調(diào)整完成。

void AdjustDown(int* a,int n,int parent)
{int child=parent*2+1;while(child<n){if(child+1<n&&a[child]>a[child+1]){child++;}if(a[child]<a[parent]){Swap(&a[child], &a[parent]);parent=child;child=parent*2+1;}else{break;}}
}

向上調(diào)整建堆:

?向上建堆是從第二層開始直到第h層,所以其時(shí)間復(fù)雜度為O(N*logN)

  for(int i=1;i<n;i++){AdjustUP(a, i);}

向下調(diào)整建堆

向下建堆是從第h-1層直到第一層,所以其時(shí)間復(fù)雜度為O(N)

for(int i=(n-1-1)/2;i>=0;i--){AdjustDown(a, n,i);}

堆排序

由于有兩種建堆方式,向上調(diào)整建堆和向下調(diào)整建堆,所以就有兩種堆排序方式。

HeapSort_UP(向上建堆排序):

//時(shí)間復(fù)雜度為O(N*logN)
void HeapSort_UP(int* a,int n)
{//向上建堆是從第二層開始直到第h層,所以其時(shí)間復(fù)雜度為O(N*logN)for(int i=1;i<n;i++){AdjustUP(a, i);}int end=n-1;//建堆完成后,需要進(jìn)行向下調(diào)整其時(shí)間復(fù)雜度為O(N*logN)while(end>0){Swap(&a[0], &a[end]);AdjustDown(a, end,0);end--;}
}

HeapSort_Down(向下建堆排序):

//時(shí)間復(fù)雜度為N*logN
void HeapSort_Down(int* a,int n)
{//向下建堆是從第h-1層直到第一層,所以其時(shí)間復(fù)雜度為O(N)for(int i=(n-1-1)/2;i>=0;i--){AdjustDown(a, n,i);}int end=n-1;//建堆完成后,需要進(jìn)行向下調(diào)整其時(shí)間復(fù)雜度為O(N*logN)while(end>0){Swap(&a[0], &a[end]);AdjustDown(a, end,0);end--;}
}

總結(jié):向上建堆從第二層開始直到第h層,向下建堆是從第h-1層直到第一層,雖然它們經(jīng)歷的層數(shù)相同,但是向上建堆中第一層不用調(diào)整,向下建堆中第h層不用調(diào)整(h為最后一層),第一層的元素只有一個(gè),第h層元素有2^(h-1)個(gè)。所以他們的時(shí)間復(fù)雜度不同,向上建堆為O(N*logN),向下建堆為O(N),盡量使用向下建堆的方式來實(shí)現(xiàn)堆排序。

TOPK

TOP-K問題:即求數(shù)據(jù)結(jié)合中前K個(gè)最大的元素或者最小的元素,一般情況下數(shù)據(jù)量都比較大。
比如:專業(yè)前10名、世界500強(qiáng)、富豪榜、游戲中前100的活躍玩家等。
對于Top-K問題,能想到的最簡單直接的方式就是排序,但是:如果數(shù)據(jù)量非常大,排序就不太可取了(可能數(shù)據(jù)都不能一下子全部加載到內(nèi)存中)。最佳的方式就是用堆來解決,基本思路如下:
1. 用數(shù)據(jù)集合中前K個(gè)元素來建堆
前k個(gè)最大的元素,則建小堆
前k個(gè)最小的元素,則建大堆
2. 用剩余的N-K個(gè)元素依次與堆頂元素來比較,不滿足則替換堆頂元素,將剩余N-K個(gè)元素依次與堆頂元素比完之后,堆中剩余的K個(gè)元素就是所求的前K個(gè)最小或者最大的元素。

例如:我們這里實(shí)現(xiàn)在1000000個(gè)數(shù)中找出5個(gè)最大的數(shù),為了方便實(shí)現(xiàn)我們使用rand()生成1000000個(gè)數(shù)。為了貼近實(shí)戰(zhàn)項(xiàng)目,我們會將這1000000個(gè)數(shù)據(jù)寫到文件中,然后文件中讀取。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void Swap(int* e1,int* e2)
{int temp=*e1;*e1=*e2;*e2=temp;
}
void AdjustDown(int* a,int n,int parent)
{int child=parent*2+1;while(child<n){if(child+1<n&&a[child]>a[child+1]){child++;}if(a[child]<a[parent]){Swap(&a[child], &a[parent]);parent=child;child=parent*2+1;}else{break;}}
}
void CreatData(void)
{//system("pwd\n");int n=1000;srand((unsigned int)time(NULL));const char* file="data.txt";FILE* fout=fopen(file, "w");for(int i=0;i<n;i++){int x=rand()%1000000;fprintf(fout, "%d\n",x);}fclose(fout);
}
void PrintTopk(int k)
{const char* file="data.txt";FILE* fin=fopen(file, "r");int* kminheap=(int*)malloc(sizeof(int)*k);for(int i=0;i<k;i++){fscanf(fin,"%d",&kminheap[i]);}//建小堆,for(int i=(k-1-1)/2;i>=0;i--){AdjustDown(kminheap, k, i);}int val=0;while(!feof(fin)){fscanf(fin, "%d",&val);if(val>kminheap[0]){kminheap[0]=val;AdjustDown(kminheap, k, 0);}}for(int i=0;i<k;i++){printf("%d ",kminheap[i]);}
}
int main()
{//CreatData();PrintTopk(5);return 0;
}

?🌸🌸🌸如果大家還有不懂或者建議都可以發(fā)在評論區(qū),我們共同探討,共同學(xué)習(xí),共同進(jìn)步。謝謝大家! 🌸🌸🌸???

http://m.aloenet.com.cn/news/37466.html

相關(guān)文章:

  • 沈陽三好街做網(wǎng)站公司長春seo快速排名
  • c 網(wǎng)站建設(shè)網(wǎng)絡(luò)營銷推廣計(jì)劃
  • 公司做自己的網(wǎng)站2020國內(nèi)十大小說網(wǎng)站排名
  • 實(shí)戰(zhàn)直播2021百度新算法優(yōu)化
  • 椒江網(wǎng)站建設(shè)578做網(wǎng)站百度文庫官網(wǎng)首頁
  • 網(wǎng)站建設(shè)方案策劃書app推廣渠道
  • 無錫網(wǎng)站建設(shè)人員新聞稿在線
  • 怎么介紹自己做的企業(yè)網(wǎng)站頁面提高網(wǎng)站收錄的方法
  • 大型網(wǎng)站的制作seo基本步驟
  • 怎樣建個(gè)網(wǎng)站杭州千鋒教育地址
  • 培訓(xùn)網(wǎng)站建設(shè)谷歌瀏覽器 安卓下載2023版官網(wǎng)
  • 什么軟件做美食視頻網(wǎng)站學(xué)生個(gè)人網(wǎng)頁制作教程
  • html5+css3 網(wǎng)站seo刷關(guān)鍵詞排名工具
  • wordpress改造成mip站網(wǎng)站建設(shè)小程序開發(fā)
  • 北京品牌網(wǎng)站營銷型網(wǎng)站有哪些功能
  • 上市企業(yè)網(wǎng)站設(shè)計(jì)相似圖片在線查找
  • 網(wǎng)站營銷的重要價(jià)值百度旗下有哪些app
  • 網(wǎng)站開發(fā)論文題目足球世界排名
  • 國內(nèi)銀行網(wǎng)站做的很垃圾跨境電商seo什么意思
  • 建設(shè)外貿(mào)企業(yè)網(wǎng)站搜索引擎優(yōu)化入門
  • 網(wǎng)站跟app的區(qū)別是什么網(wǎng)站排名大全
  • ASP動態(tài)網(wǎng)站開發(fā)案例教程競價(jià)網(wǎng)官網(wǎng)
  • 西安網(wǎng)站開發(fā)企業(yè)網(wǎng)站的在線推廣方法有
  • 汽車網(wǎng)站更新怎么做搜狗網(wǎng)
  • 鞍山今日頭條新聞東莞seo顧問
  • 做門戶網(wǎng)站主要技術(shù)哪一塊業(yè)務(wù)推廣方式有哪些
  • 可做商業(yè)用途的圖片網(wǎng)站新開網(wǎng)店自己如何推廣
  • DW做網(wǎng)站下拉列表怎么做寧波seo怎么做推廣渠道
  • 唐山盤古做網(wǎng)站多少錢長尾詞seo排名
  • 政府網(wǎng)站建設(shè)調(diào)研報(bào)告營銷型網(wǎng)站優(yōu)化