堆的基本操作

在这里我将会介绍堆的几个基本操作

1.堆的初始化
void HeapInit(Heap *heap,Compare cmp);

在这里我们可以简单粗暴一点,直接将有效值size设置为零,此外我还加了一个排序规则,Compare cmp用来控制大/小堆

2.堆的插入 
void HeapInsert(Heap*heap,HeapType value);

在这里我们需要引入一个思路叫上浮式调整,因为堆可以看作一棵完全二叉树,所以我们将新插入的元素放置在最后一个叶子结点上,这样每次将叶子结点与其对应的父节点相比较,拿小堆距离,如果叶子结点比父节点小,那么交换两个结点的值,这样不停的比较交换,就像是气球一点点上浮一样。

3.查找根结点
 int HeapRoot(Heap*heap,HeapType*value);

这个问题很简单,查找根结点我们只需要找到数组中第一个元素返回即可,这里我用int 为0还是1来判断返回是否成功,用HeapType*value将元素的地址获取出来

4.判断堆中元素是否为0
int HeapEmpty(Heap*heap);

这个我们可以直接用 return heap->size=0? 1:0;来做判断并返回值

 void HeapErase(Heap*heap);删除堆顶元素

在这里我们就要引入另一种思路,叫下沉式调整,首先我们将堆顶元素与最后一个叶子结点中的元素进行交换,此时我们的删除就变成了删除最末尾元素,我们只需要将有效值size-1即可,但此时我们发现我们的堆不再满足堆的关系(大堆/小堆关系),这时候我们就需要进行堆的调整,我们采用下沉式调整。以小堆为例,我们将从根结点开始,先将它的两个子结点进行比较,选出其中较小的一个在与父节点进行比较。如父节点比子结点大,那么将父子结点进行交换,父节点比他小,则不变,这样以此类推,就像是石头在水中下沉一样

 5.堆的销毁
void HeapDestroy(Heap*heap);

我们直接将堆的有效值size赋值为零即可完成

下面我们上代码:

1 #include"heap.h"                                                                                                                                         
  2 #include<stdio.h>
  3 int  Greater(HeapType a,HeapType b)
  4 {
  5     return a>b? 1:0;
  6 }
  7 int  Less(HeapType a,HeapType b)
  8 {
  9     return a<b? 1:0;
 10 }
 11 void HeapInit(Heap*heap,Compare cmp)
 12 {
 13     if(heap==NULL)
 14     {
 15         return;
 16     }
 17     heap->size=0;
 18     heap->cmp=cmp;
 19     return;
 20 }
 21 void Swap(HeapType*a,HeapType*b)
 22 {
 23     HeapType tmp=*a;
 24     *a=*b;
 25     *b=tmp;
 26     return;
 27 }
 28 void AdjustUp(HeapType data[],size_t size,Compare cmp,size_t index)
 29 {
 30     if(index>=size)
 31     {
 32         return;
 33     }
 34     size_t child=index;
 35     size_t parent=(child-1)/2;
 36     while(child>0)
 37     {
 38         if(cmp(data[child],data[parent]))
 39         {
 40             Swap(&data[child],&data[parent]);
 41         }
 42         else
 43         {
 44             break;
 45         }
 46         child=parent;
 47         parent=(child-1)/2;
 48     }
 49     return;
 50 }
 51 void HeapInsert(Heap*heap,HeapType value)
 52 {
 53     if(heap==NULL)
 54     {
 55         return;
 56     }
 57     if(heap->size>=MAXSIZE)
 58     {
 59         return;
 60     }
 61     heap->data[heap->size++]=value;
 62     AdjustUp(heap->data,heap->size,heap->cmp,heap->size-1);
 63 }
 64 void AdjustDown(HeapType data[],size_t size,Compare cmp,size_t index)
 65 {
 66     if(index>size)
 67     {
 68         return;
 69     }
 70     size_t parent=index;
 71     size_t child=parent*2+1;                                                                                                                             
 72     while(child<size)
 73     {
 74     if(child+1<size)
 75     if(cmp(data[child+1],data[child]))
 76     {
 77         child=child+1;
 78     }
 79      if(cmp(data[child],data[parent]))
 80     {
 81         Swap(&data[child],&data[parent]);
 82     }
 83     else
 84     {
 85         break;
 86     }
 87     parent=child;
 88     child=parent*2+1;
 89   }
 90 }
 91 
 92 void HeapErase(Heap*heap)
 93 {
 94     if(heap==NULL)
 95     {
 96         return;
 97     }
 98     if(heap->size==0)
 99     {
100         return;
101     }
102     Swap(&heap->data[0],&heap->data[heap->size-1]);
103     --heap->size;
104     AdjustDown(heap->data,heap->size,heap->cmp,0);
105 }
106 int HeapEmpty(Heap*heap)
107 {
108     if(heap==NULL)
109     {                                                                                                                                                    
110         return;
111     }
112     return heap->size=0? 1:0;
113 }
114 int HeapRoot(Heap*heap,HeapType* value)
115 {
116      if(heap==NULL)
117      {
118          return;
119      }
120      if(heap->size==0)
121      {
122          return;
123      }
124      *value=heap->data[0];
125      return 1;
126 }
127 void HeapDestroy(Heap*heap)
128 {
129     if(heap==NULL)
130     {
131         return;
132     }
133     heap->size=0;
134     return;
135 }
136 void HeapSort(HeapType array[],size_t size)
137 {
138     Heap heap;
139     HeapInit(&heap,Less);
140     size_t i=0;
141     for(i=0;i<size;i++)
142     {
143         HeapInsert(&heap,array[i]);
144     }
145     size_t output_index=0;
146     while(!HeapEmpty(&heap))
147     {                                                                                                                                                    
148         HeapType root=0;
149         HeapRoot(&heap,&root);
150         array[output_index++]=root;
151         HeapErase(&heap);
152     }
153     return;
154 }

 以下为测试代码

157 void HeapPrintchar(Heap*heap,const char *msg)
158 {
159     printf("%s\n",msg);                                                                                                                                  
160     size_t i=0;
161     for(i=0;i<heap->size;i++)
162     {
163         printf("[%lu]:%d ",i,heap->data[i]);
164     }
165     printf("\n");
166 }
167 void TestHeapInit()
168 {
169     Heap heap;
170     HeapInit(&heap,Less);
171     printf("size expected is 0 ,actual is %lu\n",heap.size);
172     printf("Compare expected is %p,actual is %p",Greater,heap.cmp);
173 }
174 void TestHeapInsert()
175 {
176     Heap heap;
177     HeapInit(&heap,Greater);
178     HeapInsert(&heap,10);
179     HeapInsert(&heap,8);
180     HeapInsert(&heap,9);
181     HeapInsert(&heap,1);
182     HeapInsert(&heap,12);
183     HeapPrintchar(&heap,"cha ru 6 ge yuan su");
184 }
185 void TestHeapErase()
186 {
187     Heap heap;
188     HeapInit(&heap,Greater);
189     HeapInsert(&heap,10);
190     HeapInsert(&heap,8);
191     HeapInsert(&heap,9);
192     HeapInsert(&heap,1);
193     HeapInsert(&heap,12);
194     HeapErase(&heap);
195     HeapPrintchar(&heap,"shan chu tou jie dian");
196 }
197 void TestHeapSort()
198 {
199     HeapType array[]={2,8,7,9,5,4,1};
200     HeapSort(array,sizeof(array)/sizeof(array[0]));
201     size_t i=0;
202     for(i=0;i<(sizeof(array)/sizeof(array[0]));i++)
203     {
204         printf("%d",array[i]);
205     }
206     printf("\n");
207 }
208 int main()
209 {
210     TestHeapInit();
211     printf("\n");
212     TestHeapInsert();
213     printf("\n");
214     TestHeapErase();
215     printf("\n");
216     TestHeapSort();
217     return 0;
218 }                                                                                                                                

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最大排序的基本操作包括以下几个步骤: 1. 构建最大:将待排序的数组构造成一个最大。最大是一种满足父节点大于等于子节点的完全二叉树。构建最大的方法是从最后一个非叶子节点开始,依次向上调整每个节点,使其满足最大的性质。 2. 交换顶元素和最后一个元素:将最大顶元素与最后一个元素交换位置,即将最大的元素放到数组的末尾。 3. 调整:将剩下的元素重新调整为最大。从顶开始,比较左右子节点的值,将较大的子节点与父节点交换位置,然后再对交换后的子节点进行调整,直到整个重新满足最大的性质。 4. 重复步骤2和步骤3,直到所有元素都被排序。 下面是一个用C++实现基于最大排序的示例: ```cpp #include <iostream> using namespace std; // 调整 void adjustHeap(int arr[], int n, int i) { int largest = i; // 初始化最大值为根节点 int left = 2 * i + 1; // 左子节点 int right = 2 * i + 2; // 右子节点 // 如果左子节点大于根节点,更新最大值 if (left < n && arr[left] > arr[largest]) { largest = left; } // 如果右子节点大于根节点,更新最大值 if (right < n && arr[right] > arr[largest]) { largest = right; } // 如果最大值不是根节点,交换根节点和最大值 if (largest != i) { swap(arr[i], arr[largest]); // 递归调整交换后的子节点 adjustHeap(arr, n, largest); } } // 排序 void heapSort(int arr[], int n) { // 构建最大 for (int i = n / 2 - 1; i >= 0; i--) { adjustHeap(arr, n, i); } // 交换顶元素和最后一个元素,并调整 for (int i = n - 1; i > 0; i--) { swap(arr[0], arr[i]); adjustHeap(arr, i, 0); } } int main() { int arr[] = {91, 84, 72, 63, 55, 46, 37, 29, 20, 11}; int n = sizeof(arr) / sizeof(arr[0]); heapSort(arr, n); cout << "Sorted array: "; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值