演算法導論_第六章_堆排序

chudongfang2015發表於2016-06-28

演算法導論_第六章_堆排序


對於堆排序,我就不著重介紹,

這是我寫的另一篇介紹堆排序的文章:

http://blog.csdn.net/chudongfang2015/article/details/51173902

這裡貼上程式碼:

#include<stdio.h>
#include<string.h>
#include<math.h> 
int h[1000],n;
void swap(int x,int y);
void siftdown(int i);
void siftup(int i);
void creat();
int deletemax();
void print();
int main()
{
	int i,num;
	printf("please input the number of array:");
	scanf("%d",&num);
	for(i=1;i<=num;i++)
		scanf("%d",&h[i]);
	n=num;
	creat();
	//print();
	for(i=1;i<=num;i++)
		printf("%d ",deletemax());
	return 0;
}
void swap(int x,int y)
{
	int t;
	t=h[x];
	h[x]=h[y];
	h[y]=t;
}

void siftdown(int i)
{
	int t,flag=0;
	while(i*2<=n&&flag==0)//t代表三個裡面最小值 
	{
		if(h[i*2]>h[i])
			t=i;
		else  
			t=i*2;
		if(i*2+1<=n)
			if(h[t]>h[i*2+1])
				t=i*2+1;
		if(t!=i)
		{
			swap(t,i);//交換 
			i=t;//賦值,繼續判斷 
		}
		else //如果父節點不再大於子節點,則跳出迴圈 
			flag=1;
	}
}


void shiftup(int i)
{
	int t,flag=0;
	if(i==1)  return ;
	while(i/2>=1&&flag==0)
	{
		if(h[i/2]>h[i])
		{
			t=i/2;
			swap(i,t);
			i=t;
		}
		else  
			flag=1;//父節點比子節點小 
	}
}

void creat()
{
	int i;
	for(i=n/2;i>=1;i--)
	{
		siftdown(i);
		//print();	
	}
		
}
int deletemax()
{
	int t;
	t=h[1];
	h[1]=h[n];
	n--;
	siftdown(1);
	return t;
}

void print()
{
	int i;
	for(i=1;i<=n;i++)
		printf("%d ",h[i]);
	printf("\n");
}

堆排序的時間複雜度為O(n*lg(n))

每次維護堆為O(lg(n))

要進行n次維護,所以堆排序的時間複雜度為O(n*lg(n))


我在這裡著重介紹佇列優先:

優先佇列是一種用來維護由一組元素構成的集合S的資料結構,其中的每一個元素都有一個相關的值,稱為關鍵字,一個最大優先佇列支援以下操作:

INSERT(S,x)    把X元素插入到集合S中

其時間複雜度為O(lg(n)),


MAXUMUM(S) 返回S中具有最大建字的元素


EXTRACT_MAX(S)  去掉並返回S中的最大鍵值


INCREASE_KEY(S,x,k) 將元素x的關鍵字徵增加到k這裡假設k的值不小於x的原關鍵字

其時間複雜度為O(lg(n)),因為其最大高度為lg(n)


這裡的最大優先佇列可以應用與共享計算機系統的作業排程。最小優先佇列可以被用於

事件驅動的模擬器


下面上程式碼:

/*************************************************************************
	> File Name: HEAP_SORT.cpp
	> Author:chudongfang 
	> Mail:1149669942@qq.com 
	> Created Time: 2016年06月28日 星期二 19時00分47秒
 ************************************************************************/

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int h[1000],n;
void swap(int x,int y);
void siftdown(int i);
void siftup(int i);
void creat();
void print();

int EXTRACT_MAX();
int MAXIMUM();
void INSERT(int k);
void INCREASE_KEY(int x,int k);

int main()
{
	int i,num=5;//初始化
	for(i=5;i>=1;i--)
		h[6-i]=i;
	n=num;
	creat();//建立堆
	
	printf("MAXIMUM=%d\n",MAXIMUM());//輸出有最大鍵值的元素
	
	EXTRACT_MAX();//刪除有最大鍵值的元素
	for(i=1;i<=n;i++)
		printf("%d ",h[i]);
    printf("\n\n");
	
    INCREASE_KEY(3,100);//增加3的關鍵字值到100
	for(i=1;i<=n;i++)
		printf("%d ",h[i]);
    printf("\n\n");
	
    INSERT(200);
	for(i=1;i<=n;i++)
		printf("%d ",h[i]);
	return 0;
}
void swap(int x,int y)//交換
{
	int t;
	t=h[x];
	h[x]=h[y];
	h[y]=t;
}

void siftdown(int i)
{
	int t,flag=0;
	while(i*2<=n&&flag==0)//t代表三個裡面最大值 
	{
		if(h[i*2]<h[i])
			t=i;
		else  
			t=i*2;
		if(i*2+1<=n)
			if(h[t]<h[i*2+1])
				t=i*2+1;
		if(t!=i)
		{
			swap(t,i);//交換 
			i=t;//賦值,繼續判斷 
		}
		else //如果父節點不再小於子節點,則跳出迴圈 
			flag=1;
	}
}


void shiftup(int i)
{
	int t,flag=0;
	if(i==1)  return ;
	while(i/2>=1&&flag==0)
	{
		if(h[i/2]>h[i])
		{
			t=i/2;
			swap(i,t);
			i=t;
		}
		else  
			flag=1;//父節點比子節點小 
	}
}

void creat()//建立堆
{
	int i;
	for(i=n/2;i>=1;i--)
	{
		siftdown(i);
		//print();	
	}
		
}
int EXTRACT_MAX()
{
	int t;
	t=h[1];
	h[1]=h[n];
	n--;
	siftdown(1);
	return t;
}

void print()
{
	int i;
	for(i=1;i<=n;i++)
		printf("%d ",h[i]);
	printf("\n");
}



int MAXIMUM()
{
	return h[1];
}

void INCREASE_KEY(int x,int k)
{
	if(k<h[x]) 
	{
		printf("new key is smaller than current key!");
		return ;
	}
	h[x]=k;
	while(x>1&&h[x/2]<h[x])
	{
		swap(x,x/2);
		x=x/2;
	}
	return ;
}

void INSERT(int k)//實現插入
{
	n++;//增加元素
	h[n]=-INF;
	INCREASE_KEY(n,k);//把其值增加到k
}





相關文章