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

當前位置: 首頁 > news >正文

用bootstrap基礎教程做的網(wǎng)站百度熱詞指數(shù)

用bootstrap基礎教程做的網(wǎng)站,百度熱詞指數(shù),官方網(wǎng)站哪家做的最好,wordpress雪花在數(shù)據(jù)結(jié)構(gòu)之《二叉樹》(上)中學習了樹的相關概念,還了解的樹中的二叉樹的順序結(jié)構(gòu)和鏈式結(jié)構(gòu),在本篇中我們將重點學習二叉樹中的堆的相關概念與性質(zhì),同時試著實現(xiàn)堆中的相關方法,一起加油吧! 1.實現(xiàn)順序結(jié)構(gòu)二叉樹 在…

在數(shù)據(jù)結(jié)構(gòu)之《二叉樹》(上)中學習了樹的相關概念,還了解的樹中的二叉樹的順序結(jié)構(gòu)和鏈式結(jié)構(gòu),在本篇中我們將重點學習二叉樹中的堆的相關概念與性質(zhì),同時試著實現(xiàn)堆中的相關方法,一起加油吧!


1.實現(xiàn)順序結(jié)構(gòu)二叉樹

在實現(xiàn)順序結(jié)構(gòu)的二叉樹中通常把堆使用順序結(jié)構(gòu)的數(shù)組來存儲,因此我們先要了解堆的概念與結(jié)構(gòu)

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

如果有一個關鍵碼的集合 K??= ?{k0 , k1 , k2 , ...,kn?1 } ,把它的所有元素按完全二叉樹的順序存儲方式式存儲,在?個?維數(shù)組中,并滿足: Ki??<= ?K2?i+1 ( Ki >= K2?i+1 且 Ki??<= ?K2?i+2 ),i = 0、1、2... ,則稱為小堆(或大堆)。將根結(jié)點最大的堆叫做最大堆或大根堆,根結(jié)點最小的堆叫做最小堆或小根堆。

以上的堆的概念簡單來說就是堆是完全二叉樹,在大堆中根結(jié)點為最大的元素,在此之后的每個孩子結(jié)點都要小于或者等于它的父結(jié)點;在小堆中根結(jié)點為最小的元素,在此之后的每個孩子結(jié)點都要大于或者等于的父結(jié)點

因此通過堆的概念的了解需要知道堆有以下的性質(zhì):
? 堆中某個結(jié)點的值總是不大于或不小于其父結(jié)點的值
? 堆總是一棵完全二叉樹

例如以下圖示就是大堆,并且將其結(jié)點的數(shù)據(jù)存儲到數(shù)組當中

以下圖示就是小堆,并且將其結(jié)點的數(shù)據(jù)存儲到數(shù)組當中

1.2二叉樹的性質(zhì)?

在了解的堆的相關概念和結(jié)構(gòu)后,之后我們要來實現(xiàn)堆,因此在此之前還要再了解二叉樹的相關性質(zhì)

💡 二叉樹性質(zhì)
? 對于具有 n 個結(jié)點的完全二叉樹,如果按照從上至下從左至右的數(shù)組順序?qū)λ薪Y(jié)點從0 開始編號,則對于序號為 i 的結(jié)點有:
1. 若 i>0 ,i 位置結(jié)點的雙親序號: \frac{i-1}{2} ; i=0 , i 為根結(jié)點編號,無雙親結(jié)點
2. 若 2i+1<n ,左孩?序號: 2i+1 , 2i+1>=n 否則無左孩子
3. 若 2i+2<n ,右孩?序號: 2i+2 , 2i+2>=n 否則無右孩子

對以上的性質(zhì)來通過一個示例來加深理解

以下就是根據(jù)二叉樹的性質(zhì)來求出各節(jié)點的孩子結(jié)點以及父結(jié)點的圖示

1.3堆的實現(xiàn)

在了解了堆相關的性質(zhì)與結(jié)構(gòu)后接下來就可以來試著實現(xiàn)堆
在實現(xiàn)堆的程序中還是將代碼分為三個文件

1.堆結(jié)構(gòu)的定義?

//堆結(jié)構(gòu)的定義
typedef int HDataType;
typedef struct Heap
{HDataType* arr;int size;//有效數(shù)據(jù)個數(shù)int capacity;//空間大小
}Heap;

在定義堆的結(jié)構(gòu)中,使用一個結(jié)構(gòu)體來定義堆的結(jié)構(gòu),里面的成員變量和順序表中相同arr為數(shù)組首元素的指針,size為數(shù)組中有效元素的個數(shù),capacity為數(shù)組空間的大小

2.堆的初始化

在堆的初始化函數(shù)的實現(xiàn)中先要在Heap.h內(nèi)完成初始化函數(shù)的聲明

//初始化堆
void HeapInit(Heap* php);

將該函數(shù)命名為HeapInit,函數(shù)的參數(shù)為結(jié)構(gòu)體指針

在完成了函數(shù)的聲明后就是在Heap.c內(nèi)完成函數(shù)的定義

//初始化堆
void HeapInit(Heap* php)
{assert(php);php->arr = NULL;php->size = php->capacity = 0;
}

3.堆的插入

?在堆的插入函數(shù)的實現(xiàn)中先要在Heap.h內(nèi)完成插入函數(shù)的聲明

//堆的插入
void HeapPush(Heap* php,HDataType x);

將該函數(shù)命名為HeapPush函數(shù)參數(shù)有兩個,第一個為結(jié)構(gòu)體指針,第二個為要插入的數(shù)據(jù)

在完成了函數(shù)的聲明后就是在Heap.c內(nèi)完成函數(shù)的定義

在堆的插入當中我們要實現(xiàn)的是在堆的末尾插入數(shù)據(jù),也就是在數(shù)組的size-1位置插入新的數(shù)據(jù),并且在插入之后由于堆的特性還要將堆中各元素的位置進行調(diào)整,使得其變?yōu)橐粋€小堆或者大堆

因此在插入函數(shù)中我們先要實現(xiàn)向上調(diào)整的函數(shù)

3.1 向上調(diào)整法?

要實現(xiàn)堆中的向上調(diào)整結(jié)點的函數(shù)首先要來分析在調(diào)整過程中需要實現(xiàn)哪些步驟,我們來看下面這個堆的示例

在這個小堆中我們先在堆的末尾插入數(shù)據(jù)為10的結(jié)點,在這之后要將該二叉樹重新調(diào)整為小堆需要哪些操作呢?

首先就是要將新插入的結(jié)點10與它的父結(jié)點做對比,如果比父結(jié)點大就和父結(jié)點交換之后再和父結(jié)點的父結(jié)點比較重復以上操作直到最后父結(jié)點為0時就停止;在此過程中如果比父結(jié)點小就不進行交換

所以以上的二叉樹要調(diào)整為小堆就要經(jīng)過以下的步驟?

在完全向上調(diào)整實例的分析后接下來就可以來實現(xiàn)向上調(diào)整的代碼?

先再Heap.h內(nèi)對向上調(diào)整函數(shù)進行聲明,通過以上的分析就可以推測出函數(shù)的參數(shù)有兩個,一個為數(shù)組的首元素指針,另一個為數(shù)組的有效元素個數(shù)?

//向上調(diào)整法
void AdjustUp(HDataType* arr, int child);

在以下的代碼當中parent就來表示父結(jié)點的數(shù)組下標,child就來表示孩子節(jié)點的下標,因此在知道孩子結(jié)點的下標時要求父結(jié)點的下標就可以用到前面提到的二叉樹的性質(zhì),父結(jié)點的下標等于其孩子結(jié)點下標減一再除以二

//向上調(diào)整法
void AdjustUp(HDataType* arr, int child)
{int parent = (child - 1) / 2;//求父結(jié)點下標while (child>0){//小堆時下面的if判斷部分就用<//大堆時下面的if判斷部分就用>if (arr[child] < arr[parent])//若父結(jié)點大于孩子結(jié)點就交換{Swap(&arr[child], & arr[parent]);child = parent;parent= (child - 1) / 2;}else{break;//若不符合以上if的條件就退出循環(huán)}}
}

例如以上的示例中在以下代碼中parent和child的變化就如以下圖所示

在以上函數(shù)中的Swap是來實現(xiàn)兩個數(shù)的交換,以下是函數(shù)的定義

void Swap(HDataType* p1, HDataType* p2)
{HDataType* tmp = *p1;*p1 = *p2;*p2 = tmp;
}

3.2 插入函數(shù)代碼實現(xiàn)?

在完成了向上調(diào)整的代碼后接下來就可以來完成堆插入函數(shù)的實現(xiàn)

在插入函數(shù)中由于php為結(jié)構(gòu)體指針,因此php不能為空,所以要將php進行assert斷言
并且在插入之前也要判斷數(shù)組空間是否滿了,滿了就要對空間進行調(diào)整,在此的調(diào)整代碼和順序表中相同
之后再將數(shù)據(jù)尾插到數(shù)組當中,再進行向上調(diào)整,最后切記要將size+1

//堆的插入
void HeapPush(Heap* php, HDataType x)
{assert(php);if (php->size == php->capacity)//對數(shù)組空間進行調(diào)整{int newcapacity = php->capacity == 0 ? 4 : 2 * php->capacity;Heap* tmp = (Heap*)realloc(php->arr,sizeof(HDataType) * newcapacity);if (tmp == NULL){perror("malloc file");exit(1);}php->arr = tmp;php->capacity = newcapacity;}php->arr[php->size] = x;//進行尾插AdjustUp(php->arr, php->size);//進行向上調(diào)整php->size++;
}

4.堆的刪除?

在堆的刪除函數(shù)的實現(xiàn)中先要在Heap.h內(nèi)完成刪除函數(shù)的聲明

//堆的刪除
void HeapPop(Heap* php);

將該函數(shù)命名為HeapPop函數(shù)的參數(shù)是結(jié)構(gòu)體指針

在完成了函數(shù)的聲明后就是在Heap.c內(nèi)完成函數(shù)的定義

在堆的刪除中是將跟結(jié)點給刪除,在刪除過程中是將根結(jié)點和最后一個結(jié)點交換,之后將數(shù)組的有效個數(shù)減一這樣就將原來的根結(jié)點給刪除了,之后再進行各結(jié)點的調(diào)整使其重新變?yōu)橐粋€堆

因此在插入函數(shù)中我們先要實現(xiàn)向下調(diào)整的函數(shù)

4.1向下調(diào)整法

要實現(xiàn)堆中的向下調(diào)整結(jié)點的函數(shù)首先要來分析在調(diào)整過程中需要實現(xiàn)哪些步驟,我們來看下面這個堆的示例

在這個小堆中我們?nèi)绻呀?jīng)跟結(jié)點刪除,在這之后要將該二叉樹重新調(diào)整為小堆需要哪些操作呢?

?

首先就是要將新的的跟結(jié)點70與它的兩個孩子結(jié)點中小的做對比,如果比該孩子結(jié)點大就和該孩子結(jié)點交換之后再和該孩子結(jié)點的兩的孩子結(jié)點中小的比較重復以上操作直到最后開始的跟結(jié)點為葉子節(jié)點時就停止;如果在這過程中比孩子結(jié)點中小的那個還小就不進行交換

所以以上的二叉樹要調(diào)整為小堆就要經(jīng)過以下的步驟?

在完全向下調(diào)整實例的分析后接下來就可以來實現(xiàn)向下調(diào)整的代碼?

?先再Heap.h內(nèi)對向上調(diào)整函數(shù)進行聲明,通過以上的分析就可以推測出函數(shù)的參數(shù)有三個,一個為數(shù)組的首元素指針,另一個為數(shù)組的有效元素個數(shù)?,最后一個是要向下調(diào)整的元素的數(shù)組下標

//向下調(diào)整法
void AdjustDown(HDataType* arr, int n, int parent);

之后就是在Heap.c內(nèi)完成函數(shù)的定義
在以下的代碼當中parent就來表示父結(jié)點的數(shù)組下標,child就來表示孩子節(jié)點的下標,因此在知道父結(jié)點的下標時要求孩子結(jié)點的下標就可以用到前面提到的二叉樹的性質(zhì),孩子結(jié)點的下標等于其父結(jié)點下標乘二再加一或二

while循環(huán)中當孩子節(jié)點下標大于數(shù)組有效個數(shù)也就是父節(jié)點為葉子節(jié)點時就退出循環(huán),因此進入while條件為child<n

//向下調(diào)整法
void AdjustDown(HDataType* arr, int n, int parent)
{int child = 2 * parent + 1;//孩子節(jié)點的下標while (child<n){//如果為小堆 以下的if判斷部分就用>//如果為大堆 以下的if判斷部分就用<if (child+1<n && arr[child] > arr[child + 1]){child++;//若為小堆就找孩子節(jié)點中小的,大堆就找孩子節(jié)點中大的}if (arr[parent] > arr[child])//若孩子節(jié)點小于父節(jié)點就交換{Swap(&arr[parent], &arr[child]);parent = child;child= 2 * parent + 1;}else{break;//若不符合以上if的條件就退出循環(huán)}}
}

例如以上的示例中在以下代碼中parent和child的變化就如以下圖所示

?4.2刪除函數(shù)代碼實現(xiàn)

在插入函數(shù)中由于php為結(jié)構(gòu)體指針,因此php不能為空,所以要將php進行assert斷言
在刪除函數(shù)中因為要刪除的是堆的根結(jié)點,所以先將堆的根結(jié)點和堆的最后一個節(jié)點進行交換,之后再將size-1,這樣就可以讓數(shù)組當中的有效個數(shù)減一,使得原來的根結(jié)點被刪除,之后再將該二叉樹使用向下調(diào)整重新調(diào)整為堆

//堆的刪除
void HeapPop(Heap* php)
{assert(php && php->size);php->arr[0] = php->arr[php->size - 1];--php->size;AdjustDown(php->arr, php->size, 0);
}

5.取堆頂?shù)脑?

在堆的取堆頂?shù)脑睾瘮?shù)的實現(xiàn)中先要在Heap.h內(nèi)完成取堆頂?shù)脑?/strong>函數(shù)的聲明

//取堆頂?shù)脑?HDataType HeapTop(Heap* php);

將該函數(shù)命名為HeapTop函數(shù)的參數(shù)是結(jié)構(gòu)體指針,函數(shù)的返回值是堆跟結(jié)點內(nèi)的數(shù)據(jù)

在完成了函數(shù)的聲明后就是在Heap.c內(nèi)完成函數(shù)的定義

//取堆頂?shù)脑?HDataType HeapTop(Heap* php)
{assert(php);return php->arr[0];
}

6.堆的數(shù)據(jù)個數(shù)?

在求堆的數(shù)據(jù)個數(shù)函數(shù)的實現(xiàn)中先要在Heap.h內(nèi)完成堆的數(shù)據(jù)個數(shù)函數(shù)的聲明

//堆的數(shù)據(jù)個數(shù)
int HeapSize(Heap* php);

將該函數(shù)命名為HeapSize函數(shù)的參數(shù)是結(jié)構(gòu)體指針,函數(shù)的返回值是堆的結(jié)點結(jié)點個數(shù)

在完成了函數(shù)的聲明后就是在Heap.c內(nèi)完成函數(shù)的定義
因為堆是用數(shù)組來實現(xiàn)的,所以堆中的結(jié)點個數(shù)就為數(shù)組的有效元素個數(shù)

//堆的數(shù)據(jù)個數(shù)
int HeapSize(Heap* php)
{assert(php);return php->size;
}

7.堆的判空

在判斷堆是否為空函數(shù)的實現(xiàn)中先要在Heap.h內(nèi)完成判斷堆是否為空函數(shù)的聲明

//堆的判空
bool HeapEmpty(Heap* php);

將該函數(shù)命名為HeapEmpty函數(shù)的參數(shù)是結(jié)構(gòu)體指針,函數(shù)的返回類型是布爾類型

在完成了函數(shù)的聲明后就是在Heap.c內(nèi)完成函數(shù)的定義
在該函數(shù)中當當堆為空時就返回true,不為空時返回false

//堆的判空
bool HeapEmpty(Heap* php)
{assert(php);return php->size == 0;
}

8.堆的銷毀

在堆的銷毀函數(shù)的實現(xiàn)中先要在Heap.h內(nèi)完成堆的銷毀函數(shù)的聲明

//銷毀堆
void HeapDestory(Heap* php);

將該函數(shù)命名為HeapDestory函數(shù)的參數(shù)是結(jié)構(gòu)體指針

在完成了函數(shù)的聲明后就是在Heap.c內(nèi)完成函數(shù)的定義

//銷毀堆
void HeapDestory(Heap* php)
{assert(php);if (php->arr){free(php->arr);}php->arr = NULL;php->size = php->capacity = 0;
}

?9.堆實現(xiàn)完整代碼

Heap.h
#define  _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>//堆結(jié)構(gòu)的定義
typedef int HDataType;
typedef struct Heap
{HDataType* arr;int size;//有效數(shù)據(jù)個數(shù)int capacity;//空間大小
}Heap;//初始化堆
void HeapInit(Heap* php);
//銷毀堆
void HeapDestory(Heap* php);
//堆的插入
void HeapPush(Heap* php,HDataType x);
//堆的刪除
void HeapPop(Heap* php);
//取堆頂?shù)脑?HDataType HeapTop(Heap* php);
//堆的數(shù)據(jù)個數(shù)
int HeapSize(Heap* php);
//堆的判空
bool HeapEmpty(Heap* php);
//向上調(diào)整法
void AdjustUp(HDataType* arr, int child);
//向下調(diào)整法
void AdjustDown(HDataType* arr, int n, int parent);
Heap.c
#include"Heap.h"void Swap(HDataType* p1, HDataType* p2)
{HDataType* tmp = *p1;*p1 = *p2;*p2 = tmp;
}//向上調(diào)整法
void AdjustUp(HDataType* arr, int child)
{int parent = (child - 1) / 2;while (child>0){//小堆 <//大堆 >if (arr[child] < arr[parent]){Swap(&arr[child], & arr[parent]);child = parent;parent= (child - 1) / 2;}else{break;}}}//向下調(diào)整法
void AdjustDown(HDataType* arr, int n, int parent)
{int child = 2 * parent + 1;while (child<n){//小堆 >//大堆 <if (child+1<n && arr[child] > arr[child + 1]){child++;}if (arr[parent] > arr[child]){Swap(&arr[parent], &arr[child]);parent = child;child= 2 * parent + 1;}else{break;}}
}//初始化堆
void HeapInit(Heap* php)
{assert(php);php->arr = NULL;php->size = php->capacity = 0;
}//銷毀堆
void HeapDestory(Heap* php)
{assert(php);if (php->arr){free(php->arr);}php->arr = NULL;php->size = php->capacity = 0;
}//堆的插入
void HeapPush(Heap* php, HDataType x)
{assert(php);if (php->size == php->capacity){int newcapacity = php->capacity == 0 ? 4 : 2 * php->capacity;Heap* tmp = (Heap*)realloc(php->arr,sizeof(HDataType) * newcapacity);if (tmp == NULL){perror("malloc file");exit(1);}php->arr = tmp;php->capacity = newcapacity;}php->arr[php->size] = x;AdjustUp(php->arr, php->size);php->size++;
}//堆的刪除
void HeapPop(Heap* php)
{assert(php && php->size);php->arr[0] = php->arr[php->size - 1];--php->size;AdjustDown(php->arr, php->size, 0);
}//取堆頂?shù)脑?HDataType HeapTop(Heap* php)
{assert(php);return php->arr[0];
}//堆的數(shù)據(jù)個數(shù)
int HeapSize(Heap* php)
{assert(php);return php->size;
}//堆的判空
bool HeapEmpty(Heap* php)
{assert(php);return php->size == 0;
}

?2.堆的應用

1.堆排序

在之前的C語言的學習當中我們實現(xiàn)了冒泡排序,但在算法的復雜度中得出了冒泡排序的時間復雜度為O(n^2),因此其實冒泡排序的效率是不高的。接下來我們就要來學習一種使用堆來實現(xiàn)排序的算法。

在此之前通過學習堆的相關概念知道了在小堆中的根結(jié)點是堆中最小的,那么在小堆中只要一直取堆的根結(jié)點就可以得到升序的數(shù)據(jù),以下就是使用這種方法來實現(xiàn)的堆排序

void HeapSort(int* a, int n)
{Heap hp;for(int i = 0; i < n; i++){HeapPush(&hp,a[i]);}int i = 0;while (!HeapEmpty(&hp)){a[i++] = HeapTop(&hp);HeapPop(&hp);}HeapDestroy(&hp);
}

但是在以上的這種算法中需要將數(shù)組中的數(shù)據(jù)先要先存儲在堆當中才能在之后得到堆頂?shù)臄?shù)據(jù),因此以上這種方法的空間復雜度就為O(n),那么有什么方法能在不申請新的空間下來實現(xiàn)堆排序呢?接下來就來看以下的這種基于原來數(shù)組建堆的方法

//堆排序算法
void HeapSort(int* arr, int n)
{for (int i = 0; i < n; i++){AdjustUp(arr, i);}int end = n - 1;while (end > 0){Swap(&arr[end], &arr[0]);AdjustDown(arr, end, 0);end--;}for (int i = 0; i < n; i++){printf("%d ", arr[i]);}
}

在以上這種堆排序中先用向上調(diào)整法來將數(shù)組通過循環(huán)的將數(shù)組數(shù)組調(diào)整為堆,根據(jù)之前向上調(diào)整的代碼在此的建的是小堆。之后的while循環(huán)中實現(xiàn)的是將小堆中的跟結(jié)點和尾結(jié)點進行交換這時數(shù)組中最小的元素就排在了數(shù)組的末尾之后再進行向下排序就可重新變?yōu)樾《?#xff0c;一直重復以上的操作就可以將數(shù)組的元素從小到大依次移動到數(shù)組末尾,最終原數(shù)組就變?yōu)樯虻牧恕?/span>

那么以上除了使用向上調(diào)整建堆外,其實使用向下調(diào)整法也可以建堆,以下是使用向下調(diào)整法建堆的代碼

//堆排序算法
void HeapSort(int* arr, int n)
{for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(arr, n, i);}int end = n - 1;while (end > 0){Swap(&arr[end], &arr[0]);AdjustDown(arr, end, 0);end--;}for (int i = 0; i < n; i++){printf("%d ", arr[i]);}
}

這兩種那一這種效率更好呢,這就需要來分析向上建堆和向下建堆的時間復雜度

先來看向上調(diào)整法

因為堆是完全二叉樹,而滿二叉樹也是完全二叉樹,此處為了簡化使用滿二叉樹來證明(時間復雜度本來看的就是近似值,多幾個結(jié)點不影響最終結(jié)果)

以下是各層的結(jié)點在向上調(diào)整過程中各層結(jié)點在調(diào)整過程中最壞的情況下移動的層數(shù)

需要移動結(jié)點總的移動步數(shù)為:每層結(jié)點個數(shù) * 向上調(diào)整次數(shù)(第?層調(diào)整次數(shù)為0)

由此可得:
💡 向上調(diào)整算法建堆時間復雜度為: O(n ? log2 n)

接下來看向下調(diào)整法

以下是各層的結(jié)點在向下調(diào)整過程中各層結(jié)點在調(diào)整過程中最壞的情況下移動的層數(shù)

則需要移動結(jié)點總的移動步數(shù)為:每層結(jié)點個數(shù) * 向下調(diào)整次數(shù)?

💡 向下調(diào)整算法建堆時間復雜度為: O(n)?

通過以上的分析后可以得出在堆排序中使用向下調(diào)整法建堆更好

堆排序第二個循環(huán)中的向下調(diào)整與建堆中的向上調(diào)整算法時間復雜度計算一致。因此堆排序的時間復雜度為 O(n + n ? log n) ,即 O(n log n)

?

?

2.TOP-K問題

TOP-K問題:即求數(shù)據(jù)結(jié)合中前K個最大的元素或者最小的元素,一般情況下數(shù)據(jù)量都比較大。
比如:專業(yè)前10名、世界500強、富豪榜、游戲中前100的活躍玩家等。
對于Top-K問題,能想到的最簡單直接的方式就是排序,但是:如果數(shù)據(jù)量非常大,排序就不太可取了(可能數(shù)據(jù)都不能一下?全部加載到內(nèi)存中)。最佳的方式就是用堆來解決,基本思路如下:

(1)用數(shù)據(jù)集合中前K個元素來建堆
? ? ? 前k個最大的元素,則建小堆
? ? ? 前k個最小的元素,則建大堆
(2)用剩余的N-K個元素依次與堆頂元素來比較,不滿足則替換堆頂元素
將剩余N-K個元素依次與堆頂元素比完之后,堆中剩余的K個元素就是所求的前K個最小或者大的元素

以下這段代碼可以實現(xiàn)將大量的整型數(shù)據(jù)輸入到data.txt的文件當中

void CreateNDate()
{// 造數(shù)據(jù)int n = 100000;srand(time(0));const char* file = "data.txt";FILE* fin = fopen(file, "w");if (fin == NULL){perror("fopen error");return;}for (int i = 0; i < n; ++i){int x = (rand() + i) % 1000000;fprintf(fin, "%d\n", x);}fclose(fin);
}

?接下來就來實現(xiàn)解決TOP-K問題的代碼,以下是實現(xiàn)的是得出數(shù)據(jù)結(jié)合中前K個最大的元素

void topk()
{int k=0;printf("k:");scanf("%d", &k);//讀取文件中的前k個數(shù)據(jù)FILE* pf = fopen("data.txt", "r");if (pf == NULL){perror("fopen fail");exit(1);}int* pa = (int*)malloc(k * sizeof(int));if (pa == NULL){perror("malloc fail");exit(2);}for (int i = 0; i < k; i++){fscanf(pf, "%d", &pa[i]);}//使用前k個數(shù)據(jù)建堆for (int i = (k - 1 - 1) / 2; i >= 0; i--){AdjustDown(pa, k, i);}int tmp=0;//循環(huán)將k個數(shù)據(jù)之后的數(shù)據(jù)堆中最小的元素比較,若比這個元素大就交換while (fscanf(pf, "%d", &tmp) != EOF){if (tmp > pa[0]){pa[0] = tmp;AdjustDown(pa, k, 0);}}for (int i = 0; i < k; i++){printf("%d ", pa[i]);}fclose(pf);pf = NULL;}


?

?

以上就是二叉樹(中)的全部內(nèi)容了,接下來在二叉樹(下)將繼續(xù)學習二叉樹的知識,在下一篇中我們將重點學習鏈式結(jié)構(gòu)的二叉樹的相關知識,未完待續(xù)……?

http://aloenet.com.cn/news/45434.html

相關文章:

  • html5農(nóng)業(yè)網(wǎng)站模板搜索引擎營銷的手段包括
  • 簡述網(wǎng)站的創(chuàng)建流程百度推廣工具有哪些
  • 網(wǎng)站建設的業(yè)務流程圖競價推廣sem
  • 南昌網(wǎng)站建設公務查詢網(wǎng)站相關網(wǎng)址
  • 怎么做網(wǎng)站計劃寧波企業(yè)網(wǎng)站seo
  • 凡科做網(wǎng)站友情鏈接怎么做百度seo刷排名網(wǎng)址
  • 網(wǎng)站建設私單合同seo建站系統(tǒng)
  • 織夢制作手機網(wǎng)站模板泉州關鍵詞優(yōu)化軟件
  • 獵頭做mapping網(wǎng)站百度關鍵詞查詢排名
  • 做文件的網(wǎng)站手機免費建站系統(tǒng)
  • 公司網(wǎng)站開發(fā)流程百度首頁純凈版
  • 長沙網(wǎng)頁設計網(wǎng)站seo是什么意思
  • 泰興做網(wǎng)站公司外貿(mào)營銷平臺
  • 網(wǎng)站中醫(yī)建設搜索引擎推廣的基本方法有
  • 搭建網(wǎng)站的流程和方法濰坊做網(wǎng)站哪家好
  • 站酷網(wǎng)下載武漢seo關鍵字優(yōu)化
  • 天津做做網(wǎng)站公眾號運營
  • 免費海報在線制作網(wǎng)站河南鄭州最新消息
  • 公司網(wǎng)站怎么更新維護搜外滴滴友鏈
  • 網(wǎng)站 框架網(wǎng)頁建設軟文的概念是什么
  • 招聘網(wǎng)站源碼下載色盲測試圖
  • 精品課程網(wǎng)站建設論文重慶網(wǎng)站seo技術
  • 本地網(wǎng)站建設電話線上營銷課程
  • 晉中網(wǎng)站開發(fā)關鍵詞智能優(yōu)化排名
  • 申請一個域名可以做多少網(wǎng)站廣東seo外包服務
  • 專業(yè)網(wǎng)站制作設計公司哪家好sem培訓班
  • 淄博市臨淄區(qū)建設局網(wǎng)站哪些網(wǎng)站推廣不收費
  • 濰坊專業(yè)空心活塞桿win10優(yōu)化大師有用嗎
  • 天長企業(yè)網(wǎng)站制作軟件開發(fā)公司有哪些
  • 網(wǎng)站被人做跳轉(zhuǎn)了民生熱點新聞