91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

堆的應用(1000個數據中找最大的前K個元素,堆排序)

發布時間:2020-07-08 03:19:22 來源:網絡 閱讀:1095 作者:下一個明天 欄目:編程語言

(1)從1000個數據中找到k個最大數據

首先看到這個題時,可能會想到先將這1000個數據進行降序排序,即取出的前k個元素最大。時間復雜度為O(N^2),使得程序效率低。

如何解決這個問題呢?我們的堆就派上用場嘍!

解題思路:

   可先創建一個數組topK[k],將100w中的前k個數據放入數組topK中,將topK中的數據建小堆,則可保證堆的第一個元素是最小的,將第k個元素與堆中第一個元素比較,若大于,則交換。對堆進行重新建小堆,取第k+1個元素與堆中第一個元素比較,以此類推,直至100w-k個元素比較完。則此時堆中的元素就是k個最大數據。

   代碼實現:

const int N = 1000;
const int K = 100;

void AdjustDown(int topK[],int parent) //建小堆
{
	int child = 2*parent+1;
	while(child < K)
	{
		if(child+1 < K && topK[child+1] < topK[child])
		{
			++child;
		}
		if(topK[child] < topK[parent])
		{
			swap(topK[child],topK[parent]);
			parent = child;
			child = 2*parent+1;
		}
		else
		{
			break;
		}
	}
}
void GetTopK(int a[],int topK[])
{
	assert(a);
	int i = 0;
	for(i=0;i<K;++i) //將a的前K個元素放入數組中
	{
		topK[i] = a[i];
	}
	for(i=(K-2)/2;i>=0;--i)//對前K個元素建小堆
	{
		AdjustDown(topK,i);
	}
	for(i=K;i<N;++i)
	{
		if(a[i] > topK[0]) //將K個元素之后的每個元素和堆的第一個元素(最小元素)比較
		{
			swap(a[i],topK[0]);//若比第一個元素大,則交換
			AdjustDown(topK,0);//對新堆重新建小堆
		}
	}
}

測試代碼:

void Test2()
{
	int topK[K];
	int a[N];
	srand(time(0)); //隨機數種子
	for(int i=0;i<N;++i)
	{
		a[i] = rand(); //隨機數
	}
	GetTopK(a,topK);
	for(int i=0;i<K;i++)
	{
		cout<<topK[i]<<" ";
	}
}

測試結果:

堆的應用(1000個數據中找最大的前K個元素,堆排序)

時間復雜度為 k*lgk+N*lgk  

當N龐大時,k可忽略,則時間復雜度為O(N),大大提高了效率。


(2)堆排序

既然是排序,那就有兩種可能升序or降序。使得堆是建大堆方便還是建小堆方便。

 <1>若為升序,則需要建大堆。

    堆的第一個元素為最大,將最大元素與末尾元素交換,剩下的元素(除末尾元素)向下調整。 

 <2>若為降序,則需要建小堆。

    堆的第一個元素為最小,將最小元素與末尾元素交換,剩下的元素(除末尾元素)向下調整。 

    代碼實現(以升序為例):

void AdjustDown(int a[],int parent,int size)  //建大堆
{
	assert(a);
	int child = 2*parent+1;
	while(child < size)
	{
		if(child+1 < size && a[child+1] > a[child])
		{
			++child;
		}
		if(a[child] > a[parent])
		{
			swap(a[child],a[parent]);
			parent = child;
			child = 2*parent+1;
		}
		else
		{
			break;
		}
	}
}
void HeapSort(int a[],int size) 
{
	assert(a);
	//建堆
	for(int i=(size-2)/2;i>=0;--i)
	{
		AdjustDown(a,i,size);  //建大堆
	}

	//選擇最大的放到末尾,從剩下數據向下調整
	for(int i=0;i<size;i++)
	{
		swap(a[0],a[size-1-i]);
		AdjustDown(a,0,size-1-i);
	}
}

//測試代碼
void TestHeapSort()
{
	int a[] = {10,16,18,12,11,13,15,17,14,19};
	int size = sizeof(a)/sizeof(a[0]);
	HeapSort(a,size);	
}

測試結果:

堆的應用(1000個數據中找最大的前K個元素,堆排序)

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

加查县| 台东县| 融水| 阿坝| 大方县| 仙桃市| 滨海县| 博乐市| 达州市| 紫阳县| 石林| 龙游县| 金阳县| 日照市| 吉木乃县| 周至县| 台南县| 永胜县| 芷江| 通辽市| 绥化市| 东平县| 中方县| 安宁市| 黎城县| 巴彦淖尔市| 石嘴山市| 阳原县| 牡丹江市| 满洲里市| 马边| 惠东县| 磐安县| 浦城县| 馆陶县| 景泰县| 民和| 大城县| 宜宾县| 德化县| 奇台县|