数据结构中的堆,是一颗完全二叉树,以连续地址存储。插入的方式是,先将元素放到vector尾部,然后vector不断和父母节点比较交换,直到找到合适的位置,所以时间复杂度是O(lgN),也就是树的高度。删除第一个元素的方式是,先将最后的元素跟第一个元素交换,然后将最后的元素删除,然后第一个元素再跟两个孩子节点中的一个交换,直到找到合适的位置,所以时间复杂度也是O(lgN)。
其中堆排序就是每次调整都是从父结点、左孩子结点、右孩子结点三者中选择最大者跟父结点进行交换(交换之后可能造成被交换的孩子结点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。
根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最小者的堆称为小根堆。 根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大根堆
//堆排序
void HeapAdjust(int*a,int i,int size)
{
int lchild = 2*i;
int rchild = 2*i+1;
int max = i;
if (i<=size/2)
{
if (lchild<=size&&a[lchild]>a[max])
{
max= lchild;
}
if (rchild<=size&&a[rchild>a[max])
{
max = rchild;
}
if (max!=i)
{
swap(a[i],a[max]);
HeapAdjust(a,max,size);
}
}
}
void buidheap(int *a,int size)
{
for (int i=size/2;i>0;i--)
{
HeapAdjust(a,i,size);
}
}
void HeapSort(int*a,int size)
{
if (a==NULL&&size<2)
{
return;
}
buidheap(a,size);
for (int i=size;i>0;i--)
{
swap(a[1],a[i]);
HeapAdjust(a,1,i-1);
}
}
//归并排序的实现代码: //将有二个有序数列a[first...mid]和a[mid...last]合并。 void mergearray(int a[], int first, int mid, int last, int temp[]) { int i = first, j = mid + 1; int m = mid, n = last; int k = 0; while (i <= m && j <= n) { if (a[i] <= a[j]) temp[k++] = a[i++]; else temp[k++] = a[j++]; } while (i <= m) temp[k++] = a[i++]; while (j <= n) temp[k++] = a[j++]; for (i = 0; i < k; i++) a[first + i] = temp[i]; } void mergesort(int a[], int first, int last, int temp[]) { if (first < last) { int mid = (first + last) / 2; mergesort(a, first, mid, temp); //左边有序 mergesort(a, mid + 1, last, temp); //右边有序 mergearray(a, first, mid, last, temp); //再将二个有序数列合并 } } bool MergeSort(int a[], int n) { int *p = new int[n]; if (p == NULL) return false; mergesort(a, 0, n - 1, p); delete[] p; return true; }
转载请注明原文地址: https://ju.6miu.com/read-1298405.html