• 优先队列


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

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

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

         (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));
    }
    
  • 相关阅读:
    一、HTML基础学习
    算法之求正整数的二进制
    JavaScript ajax返回状态
    ajax实现异步校验
    比较喜欢的一种求阶乘的方法:用递归求阶乘
    java中自定义异常类
    我对多态的理解
    包装类和基本类型区别?(integer和int取值范围一样大)
    JAVA中默认的编码方式
    抽象类和接口的区别
  • 原文地址:https://www.cnblogs.com/fightingxu/p/2848492.html
Copyright © 2020-2023  润新知