心胸决定格局,眼界决定境界...

堆排序代码

const int max_num = 10;
int n = max_num;
int data[max_num + 1] = { 0, 1, 3, 10, 5, 8, 6, 7, 9, 2, 4 };
void shiftup(int i)
{
   //新来一个节点i,将其放在最后,然后与其父节点比较

	int flag = 1;
	int tmp;
	while (i > 1 && data[i] < data[i / 2] && flag)
	{
		//交换元素
		tmp = data[i / 2];
		data[i / 2] = data[i];
		data[i] = tmp;
		i = i / 2;
		if (i == 1)
			flag = 0;
	}
}

void shiftdown(int i)
{

	int t = data[i];
	int tmp;
	int min_index = i;
	int flag = 1;

	while (2 * i <= n  && flag == 1)
	{
		if (data[i] > data[2 * i])
		{
			t = data[2 * i];//记录当前最小值
			min_index = 2 * i;
		}



		if (2 * i + 1 <= n)
		{
			if (t > data[2 * i + 1])
			{
				t = data[2 * i + 1];//记录当前最小值
				min_index = 2 * i + 1;
			}
		}

		if (min_index != i)
		{
			//交换
			tmp = data[i];
			data[i] = data[min_index];
			data[min_index] = tmp;
			i = min_index;

		}
		else
		{
			flag = 0;
		}

	}

}

void creatHeap1(int* data, int len)
{
	for (int i = 1; i <= max_num; i++)//从1开始
	{
		shiftup(i);//假设已有小堆k(已经有序,上层的根节点肯定小于下层的子节点,往下延伸,只会逐渐增大),再来一个节点,从第一个非叶子节点开始比较,一直比较到根节点,是否往上移, 直到顶点
	}
}
//方法二  
void creatHeap2(int* data, int len)
{
	for (int i = len / 2; i >= 1; i--)//从1开始
	{
		shiftdown(i);//从第1个非叶子节点开始,本层节点与下层节点比较,是否需要往下移(当本层节点大于下层节点时,往下移)
	}
}


int main(int argc, const char* argv[])
{
	//堆排序

	//首先创建堆,此处以小堆为例(父节点小于两个子节点)
	//creatHeap1(data, max_num);
	//for (int i = 1; i <= max_num; i++)
	//{
	//	printf("%d ", data[i]);
	//}
	
	creatHeap2(data, max_num);
	for (int i = 1; i <= max_num; i++)
	{
		printf("%d ", data[i]);
	}
	printf("\n");
	//建成堆后,如何有序展示
	//方式1:取出堆顶,然后将最后一个元素放置,往下移,调整成堆,直到堆为空

	
	//n = max_num;
	//while (n >= 1)
	//{
	//	int top = data[1];
	//	data[1] = data[n];
	//	n--;
	//	shiftdown(1);//此处n的值需要变化,所以内部不能用max_num
	//	printf("%d ", top);
	//}


	//方式2:将最后一个元素与根节点位置交换,最后一个位置保存的是最小值,向下移

	
	while (n >= 1)
	{
		int tmp = data[n];
		data[n] = data[1];
		data[1] = tmp;
		n--;
		shiftdown(1);
	}
	for (int i = 1; i <= max_num; i++)
	{
		printf("%d ", data[i]);
	}
	//如果要获得从小到大,则事先创建大顶堆




	return 0;
}

  

 

找出第k大的元素

	//找出第k大的元素
	int k = 5;
	creatHeap2(data, k);//创建小堆
	for (int i = 1; i <= k; i++)
	{
		printf("%d ", data[i]);
	}
	for (int i = k+1; i <= max_num; i++)
	{
		if (data[i] > data[1])//如果大于堆顶点,则加上去,向上移
		{
			data[1] = data[i];
			shiftdown(1);
		}
		
		
	}
	printf("\n");
	//堆顶元素就是第k大
	printf("%d ", data[1]);//6; 第5大的元素

  

posted @ 2019-01-28 23:26  WELEN  阅读(175)  评论(0)    收藏  举报