日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

双端堆c语言,数据结构——双端堆(C语言)

發布時間:2025/3/8 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 双端堆c语言,数据结构——双端堆(C语言) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

定義

雙端堆:是一棵完全二叉樹,該完全二叉樹要么為空,要么同時滿足下列性質:

(1)?根節點不包含元素;

(2)?左子樹是一個最小堆;

(3)?右子樹是一個最大堆;

(4)?如果右子樹不空,令i是左子樹中任意一節點,j是i在右子樹中的對應節點。如果i在右子樹中的對應節點不存在,則令j為i父節點在右子樹中的對應節點。對于節點i和j,節點i的關鍵字小于等于j的關鍵字。

雙端堆的插入操作

步驟

(1)若插入的新元素是在最小堆,將新插入節點與其在最大堆中對應節點相比較,如果大于對應節點,則將兩個節點元素互換,對最大堆執行max_insert操作;否則,只需對最小堆執行min_insert操作。

(2)若插入的新元素是在最大堆,將新插入節點與其在最小堆中對應節點相比較,如果小于對應節點,則將兩個節點元素互換,對最小堆執行min_insert操作;否則,只需對最大堆執行max_insert操作。

雙端堆的刪除操作

以下以刪除最小元素為例,刪除最大元素相似。

刪除最小元素基本思想:

首先,將從最小堆的根節點刪除的元素轉換為從最小堆的葉子節點中刪除元素的操作。這種轉換是通過在沿根節點到葉子節點的路徑上選擇關鍵字值較小的節點逐步上移來完成的。其結果是把初始時位于最小堆根節點處的空位移到一個葉子節點p。然后,用初始時位于雙端堆最后位置的元素temp插入到該葉子節點p。插入操作類似雙端堆的插入操作,只是插入操作僅在最小堆中進行,且其中max_paretner(i)的返回值j有改變。

程序

函數聲明:

#ifndef HEAP_H_INCLUDED

#define HEAP_H_INCLUDED

#include

#include

#include

#include

#define MAX_SIZE 10

int heap[MAX_SIZE];

void deap_insert(int *heap,int *n,int item);//雙端堆插入操作

int delete_deap_min(int *heap,int *n);//刪除雙端堆的最小元素

bool max_heap(int n);//判斷節點是否在最大堆中

int min_partner(int n);

int max_partner(int n);

void min_insert(int *heap,int n,int item);

void max_insert(int *heap,int n,int item);

void modified_deap_insert(int *heap,int i,int temp,int n);

int modified_max_partner(int i,int n);

#endif // HEAP_H_INCLUDED

函數定義:

#include"Heap.h"

/*雙端堆的插入操作*/

void deap_insert(int *heap,int *n,int item)

{

int i;

(*n)++;

if((*n)==MAX_SIZE)//滿堆

{

printf("The heap is full.\n");

exit(1);

}

if(2==(*n))//原來為空堆

heap[2]=item;

else

{

bool flag;

flag=max_heap(*n);//插入的節點是否在最大堆

switch(flag)

{

case true://節點在最大堆

i=min_partner(*n);//插入節點在最小堆所對應的節點

if(item

{

heap[*n]=heap[i];//交換元素

min_insert(heap,i,item);//把數據item插入到最小堆中

}

else

max_insert(heap,*n,item);//否則插入到最大堆中

break;

case false:

i=max_partner(*n);//插入節點在最大堆中對應的節點

if(item>heap[i])//比較最大堆節點和插入元素的大小

{

heap[*n]=heap[i];//交換元素

max_insert(heap,i,item);//插入到最大堆中

}

else

min_insert(heap,*n,item);//否則插入到最小堆

break;

}

}

}

/*刪除雙端堆的最小元素操作*/

int delete_deap_min(int *heap,int *n)

{

int i,j;

int temp;

int item;

if(*n<2)

{

fprintf(stderr,"The heap is empty.\n");

exit(1);

}

item=heap[2];//要刪除的元素

temp=heap[(*n)--];//最后元素賦給temp;

for(i=2;2*i<=*n;)

{//將從最小堆根節點刪除元素的操作

//轉換為從最小堆的葉子節點中刪除元素的操作

j=2*i;//j為i的葉子節點

if(j+1<=*n)

{

if(heap[j]>heap[j+1])

j++;//找出葉子節點中最小的關鍵字值節點

}

heap[i]=heap[j];//將葉子節點上移

i=j;//其結果是把初始時位于根節點處的空位移動到葉子節點i;

}

modified_deap_insert(heap,i,temp,*n);//用初始時位于雙端堆最后位置的節點元素插入到葉節點i;

//該插入操作與deap_insert()的插入操作基本類似;只是插入操作僅在最小堆中;且其中max_partner(i)

//的返回值j改變;

return item;

}

/*判斷節點n是否在最大堆中*/

bool max_heap(int n)

{

double a = log(n)/log(2);

double j = n + pow(2, (int)a-1);

double b = log(j)/log(2);

if((int)a == (int)b)

return false;

else

return true;

}

/*返回最大堆節點n對應最小堆的結點*/

int min_partner(int n)

{

double k = log(n)/log(2);

double a = pow(2, (int)k-1);

return n - (int)a;

}

/*返回最小堆節點n對應最大堆的結點*/

int max_partner(int n)

{

double k = log(n)/log(2);

double a = pow(2, (int)k-1);

return (n + (int)a)/2;

}

/*最小堆的插入操作*/

void min_insert(int *heap,int n,int item)

{

int i,parent;

i=n++;

parent=i/2;

while(parent>=1)

{

if(heap[parent]>item)

{

heap[i]=heap[parent];

i=parent;

parent/=2;

}

else break;

}

heap[i]=item;

}

/*最大堆的插入操作*/

void max_insert(int *heap,int n,int item)

{

int i,parent;

i=n++;

parent=i/2;

while(parent>1)

{

if(heap[parent]

{

heap[i]=heap[parent];

i=parent;

parent/=2;

}

else break;

}

heap[i]=item;

}

/*調整雙端堆*/

void modified_deap_insert(int *heap,int i,int temp,int n)

{

int j;

int item=temp;

i++;

if(i==MAX_SIZE)//滿堆

{

printf("The heap is full.\n");

exit(1);

}

if(2==i)//原來為空堆

heap[2]=item;

else

{

bool flag;

flag=max_heap(i);//插入的節點是否在最大堆

switch(flag)

{

case true://節點在最大堆

j=min_partner(i);//插入節點在最小堆所對應的節點

if(item

{

heap[i]=heap[j];//交換元素

min_insert(heap,j,item);//把數據item插入到最小堆中

}

else

max_insert(heap,i,item);//否則插入到最大堆中

break;

case false:

j=modified_max_partner(i,n);//插入節點在最大堆中對應的節點

if(item>heap[j])//比較最大堆節點和插入元素的大小

{

heap[i]=heap[j];//交換元素

max_insert(heap,j,item);//插入到最大堆中

}

else

min_insert(heap,i,item);//否則插入到最小堆

break;

}

}

}

int modified_max_partner(int i,int n)

{

double k = log(i)/log(2);

double a = pow(2, (int)k-1);

int j;

j=(i + (int)a);

if(j>n)

return j/2;

else return NULL;

}

程序測試:

#include"Heap.h"

int main()

{

int i,item;

int n=1;

for(i=2;i

{

scanf("%d",&item);

deap_insert(heap,&n,item);

}

for(i=2;i<=n;i++)

printf("%d ",heap[i]);

printf("\n");

item=delete_deap_min(heap,&n);

printf("The deleted data is:%d",item);

printf("\n");

for(i=2;i<=n;i++)

printf("%d ",heap[i]);

return 0;

}

總結

以上是生活随笔為你收集整理的双端堆c语言,数据结构——双端堆(C语言)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。