队列:只允许在表的一端插入,在另一端删除;在某一段插入的叫做对头,在一端删除的叫做对尾;
队列基于数组的存储方式叫做顺序队列,基于单链表存储的叫做链式队列;
循环队列:把数组的前端和后端连接起来,形成一个环,叫做循环队列;
如何判断是空队还是满队?
空队:当front == rear,队列是空对,
满队:当(rear+1)%MaxSize == front
这种情况能够存储数据的大小只能是MaxSize-1;
当想把MaxSize个元素全部用了,区分队空还是对满可设置一个标记记录最近一次该队列执行的是进队还是出队,如果是进队,flag =1;如果是出对flag =0;当front == rear的时候,查看flag的值,如果flag = 1,说明是队尾追上了队头,那么该队列是满对,如果flag =0,说明对头追上了队尾,那么就是空队。不过这样会降低效率;
优先级队列:堆
堆的创建:
template<class E> MinHeap(E)::MinHeap(int sz) { maxHeapSize = (DefaultSize < se)?sz:DefaultSize; if(heap == NULL) { cout<<"堆创建失败"<<endl; exit(1); } currentSize =0; }; template<class E> MinHeap<E>::MinHeap(E arr[],int n) { maxHeapSize = (DefaultSize < n)?n:DefaultSize; heap = new[maxHeapSize]; if(heap == NULL){ cout<<"堆创建失败"<<endl; exit(1); } for(int i =0;i<n;++i) { heap[i]= arr[i]; } currentSize = n; int currentPos = (currentSize-2)/2;//根据完全二叉树的性质,子结点 = 2×(父节点)+1;但是数组的下表是从0开始,传过来的n是数组的个数。 while(currentPos > 0)//自底向上扩大堆; { ShifDown(currentPos,currentSize-1);//局部调整的时候是自顶向下; currentPos--; } } template<class E> void MinHeap::ShiftDown(int start,int m) { int i =start,j =2*i+1; E temp = heap[i]; while(j < m) { while( j< m && heap[j] < heap[j+1])j++;// if(temp < heap[j])break; else { heap[i] = heap[j]; i =j; j =2*j+1; } } heap[i] = temp; }
//向下调整算法;
template<class E> void MinHeap<E>::siftDown(intstart,int m) { int i =start,j = 2*i+1; E temp = heap[i]; while(j <= m) { if(j <m && heap[j] >heap[j+1])j++; if(temp <= heap[j])break; else{heap[i] = heap[j];i =j;j =2*i+1;} } heap[i]=temp; }