优先队列

           首先搞清楚 什么是优先队列,优先队列是一种数据结构,它与一般的队列先入先出的性质不同,它每次出队的是优先级最大的元素,当一个指定的优先级元素入队时,能够很快的把它排到队列中。看到这里,可以发现,优先队列其实就是堆排序方法的设计与实现。

    堆 其实是一种完全二叉树,这个结构明显的好处是可以用数组来表示,不用指针来表示,这样我们可以省去很多不必要的麻烦。这里最大堆和最小堆的概念可以查看严蔚敏的数据结构神书。堆排序的过程大家可以再百度上寻找,这里也不详细介绍。

     然后说一下优先队列,需要如下集中关键的操作。

     (1)push() :将元素插入到优先队列。

     (2)top():返回优先级最高的元素.

     (3) pop():弹出优先级最高的元素。

     (4)increase():将某一个元素的优先级提升到某个数。

  top()函数只要返回数组的第一个元素就可以了,期就为最大值,   pop函数主要功能是弹出最大的元素,让数组的第一个元素与最后一个元素交换一下,然后将数组的长度减1,然后调整堆就可以了,   increase函数将A[i]的设为指定的优先级。然后在i>1且A[i]的父节点一直小于A[i]的情况下,一直做两件事:a.交换A[i]与它的父节点的值。b.将i递增为父节点的序号。

 

 

   具体的实现代码

 

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct List
{
	int *data;
	int length;
	int size;
}*pArrayList;

void heapAdjust(pArrayList list,int index,int length)
{
	int lchild=index*2+1;
	
	int rchild=index*2+2;
	int largest;
	if(lchild<=length && list->data[lchild]>list->data[index])
	{
		largest=lchild;
	}
	else
		 largest=index;
	if(rchild<=length && list->data[rchild]>list->data[largest])
	{
		largest=rchild;
	}

	if(largest!=index)
	{
		int tmp=list->data[index];

		list->data[index]=list->data[largest];
		list->data[largest]=tmp;
		heapAdjust(list,largest,length);
	}
}

void BuildMaxHeap(pArrayList list)
{
	for(int i=(list->length-2)/2;i>=0;i--)
	{
		heapAdjust(list,i,list->length);
	}
}


void printArrayList(pArrayList list)
{
	for(int i=0;i<list->length;i++)
	{
		printf("%d  ",list->data[i]);
	}
	printf("\n");
}

void heapSort(pArrayList list)
{
	BuildMaxHeap(list);

	printf("构成最大堆:");
	printArrayList(list);


	int len=list->length-1;
	for(int i=list->length-1;i>0;--i)
	{
		int tmp=list->data[0];

		list->data[0]=list->data[i];
		list->data[i]=tmp;

		printf("交换以后:");

		printArrayList(list);

		--len;


		heapAdjust(list,0,len);
	}

	printf("最终结果:");
	printArrayList(list);

}


int top(pArrayList list)
{
	return list->data[0];
}
int pop(pArrayList list)
{
	int head=list->data[0];
	list->data[0]=list->data[list->length-1];
	--list->length;

	heapAdjust(list,0,list->length);

	return head;
}


int max(int a,int b)
{
	return a>b?a:b;
}
void decreaseKey(pArrayList list,int index,int key)
{
	if(list->data[index]<key)
	{
		printf("new key must be smaller");

		return ;
	}
	else
	{
		list->data[index]=key;
	}

	int tmp;
	while(index<list->length&& max(list->data[index*2+1],list->data[index*2+2])>list->data[index])
	{
			
			int itmp;
		     tmp=list->data[index];

			list->data[index]=max(list->data[index*2+1],list->data[index*2+2]);
            if(list->data[index*2+1]==max(list->data[index*2+1],list->data[index*2+2]))
			{
				itmp=index*2+1;
			}
			else
			{
				itmp=index*2+2;
			}

			list->data[itmp]=tmp;
			index=itmp;
	}
}

void increaseKey(pArrayList list,int index ,int key)
{
	if(list->data[index]>key)
	{
		printf("new Key must be bigger ");
		return ;
	}

	else
	{
		list->data[index]=key;
	}

	int tmp;

	while(index>0  && list->data[(index-2)/2]<list->data[index])
	{
		tmp=list->data[index];


		list->data[index]=list->data[(index-2)/2];
		list->data[(index-2)/2]=tmp;


		index=(index-2)  / 2;
	}
}


void push(pArrayList   list, int key)
{
	if(list->length==list->size)
	{
		list->data=(int *)realloc(list->data,sizeof(int) * list->size * 2);
		list->size=list->size*2;
	}

	list->data[list->length]=-1;
	increaseKey(list,list->length,key);
	++list->length;
	BuildMaxHeap(list);
}
void main()
{
   pArrayList list;
  
   list=(pArrayList)malloc(sizeof(List));

   list->data=(int *)malloc(sizeof(int)*5);

   for(int i=0;i<5;i++)
   {
	   list->data[i]=i;
   }
   list->length=5;
   list->size=5;
BuildMaxHeap(list);
   
  //increaseKey(list,3,7);
   decreaseKey(list,0,1);

  //push(list,8);

  //BuildMaxHeap(list);
  printArrayList(list);
  printf("%d\n",top(list));
}

 

posted @ 2013-01-07 00:22  helloyu  阅读(1077)  评论(0编辑  收藏  举报