實現堆的各種操作


 
#include<stdio.h>
//實現堆的各種操作 加入數據 刪除數據 調整堆 獲取數據
//為方便編程 數組從1開始 小頂堆
int a[100];
int size = 0;
int c,b;

void swap(int *a,int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}

void addAdjust(int a[],int size)
{
int id = size;
while(id/2!=0&&a[id]<a[id/2])//向上調整直至堆頂
{
swap(&a[id],&a[id/2]);
id = id/2;//id 向上前進
}
}

void deleteAdjust(int a[])
{
a[1] = a[size--];
int id = 1;
int child = id*2;
for(;id*2<size;id = child)//保證其至少有左兒子
{
child = id*2;
if(child+1<=size&&a[child]>a[child+1])//在有右兒子的前提下判斷誰最小
{
child +=1;
}
if(a[id]>a[child])//若倆兒子中最小值比父節點值小 交換
{
swap(&a[id],&a[child]);
}
else
{
break;
}
}
//id = child 這一步很巧妙的
}
int main()
{
char s[3];
printf("請輸入相關命令和數據:\n-a 添加數據\n-d 刪除堆頂 \n-g 獲取堆頂元素\n-p 打印堆\n-0 退出\n");
while(1)
{
fflush(stdin);
scanf("%s",s);
if(s[1]=='a')
{
scanf("%d",&a[++size]);
addAdjust(a,size);
//printf("-a\n");
}
else if(s[1]=='d')
{
deleteAdjust(a);
printf("堆頂元素已經刪除成功!");
//printf("-d\n");
}
else if(s[1]=='g')
{
printf("目前堆頂元素(即最小元素)為:%d\n",a[1]);
//printf("-g\n");
}
else if(s[1]=='p')
{
int i;
for(i=1;i<=size;i++)
printf("%d ",a[i]);
printf("\n");
//printf("-p\n");
}
else if(s[1]=='0')
{
break;
}
else
{
printf("命令錯誤\n");
printf("請輸入相關命令和數據:\n-a 添加數據\n-d 刪除堆頂 \n-g 獲取堆頂元素\n-p 打印堆\n-0 退出\n");
}
}
printf("操作完成\n");
return 0;
}
 
#include<stdio.h>
//實現堆的各種操作 加入數據 刪除數據 調整堆 獲取數據
//為方便編程 數組從1開始 小頂堆
int a[100];
int size = 0;
int c,b;

void swap(int *a,int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}

void addAdjust(int a[],int size)
{
int id = size;
while(id/2!=0&&a[id]<a[id/2])//向上調整直至堆頂
{
swap(&a[id],&a[id/2]);
id = id/2;//id 向上前進
}
}

int max(int a,int b)
{
return a=a>b?a:b;
}

void heapAdjust(int *a,int i,int size)
{
int lchild = 2*i;
int rchild = 2*i+1;
int max = i;
if(lchild<=size&&a[max]>a[lchild])
{
max = lchild;
}
if(rchild<=size&&a[max]>a[rchild])
{
max = rchild;
}
if(max!=i)
{
swap(&a[max],&a[i]);
heapAdjust(a,max,size);
}
else
return;
}

void deleteAdjust(int a[])
{
a[1] = a[size--];
int id = 1;
int child = id*2;
for(;id*2<size;id = child)//保證其至少有左兒子
{
child = id*2;
if(child+1<=size&&a[child]>a[child+1])//在有右兒子的前提下判斷誰最小
{
child +=1;
}
if(a[id]>a[child])//若倆兒子中最小值比父節點值小 交換
{
swap(&a[id],&a[child]);
}
else
{
break;
}
}
//id = child 這一步很巧妙的
}
int main()
{
char s[3];
printf("請輸入相關命令和數據:\n-a 添加數據\n-d 刪除堆頂 \n-g 獲取堆頂元素\n-p 打印堆\n-0 退出\n");
while(1)
{
fflush(stdin);
scanf("%s",s);
if(s[1]=='a')
{
scanf("%d",&a[++size]);
addAdjust(a,size);
//printf("-a\n");
}
else if(s[1]=='d')
{
/*deleteAdjust(a);
printf("堆頂元素已經刪除成功!");
//printf("-d\n");*/
///*
a[1] = a[size--];
heapAdjust(a,1,size);
//*/
}
else if(s[1]=='g')
{
printf("目前堆頂元素(即最小元素)為:%d\n",a[1]);
//printf("-g\n");
}
else if(s[1]=='p')
{
int i;
for(i=1;i<=size;i++)
printf("%d ",a[i]);
printf("\n");
//printf("-p\n");
}
else if(s[1]=='0')
{
break;
}
else
{
printf("命令錯誤\n");
printf("請輸入相關命令和數據:\n-a 添加數據\n-d 刪除堆頂 \n-g 獲取堆頂元素\n-p 打印堆\n-0 退出\n");
}
}
printf("操作完成\n");
return 0;
}


 

 

#include<stdio.h>
//實現堆的各種操作 加入數據 刪除數據 調整堆 獲取數據
//為方便編程 數組從1開始 小頂堆
int a[100];
int size = 0;
int c,b;

void swap(int *a,int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}

void addAdjust(int a[],int size)
{
int id = size;
while(id/2!=0&&a[id]<a[id/2])//向上調整直至堆頂
{
swap(&a[id],&a[id/2]);
id = id/2;//id 向上前進
}
}

int max(int a,int b)
{
return a=a>b?a:b;
}

void heapAdjust(int *a,int i,int size)
{
int lchild = 2*i;
int rchild = 2*i+1;
int max = i;
if(lchild<=size&&a[max]>a[lchild])
{
max = lchild;
}
if(rchild<=size&&a[max]>a[rchild])
{
max = rchild;
}
if(max!=i)
{
swap(&a[max],&a[i]);
heapAdjust(a,max,size);
}
else
return;
}

void deleteAdjust(int a[])
{
a[1] = a[size--];
int id = 1;
int child = id*2;
for(;id*2<size;id = child)//保證其至少有左兒子
{
child = id*2;
if(child+1<=size&&a[child]>a[child+1])//在有右兒子的前提下判斷誰最小
{
child +=1;
}
if(a[id]>a[child])//若倆兒子中最小值比父節點值小 交換
{
swap(&a[id],&a[child]);
}
else
{
break;
}
}
//id = child 這一步很巧妙的
}


void minDelete(int a[])
{
int id=1;
while(id*2<=size)
{

if(id*2+1<=size&&a[id*2]>a[id*2+1])
{
a[id] = a[id*2+1];
id = id*2+1;
}
else
{
a[id] = a[id*2];
id = id*2;
}
}
if(id!=size)
{
a[id] = a[size];
while(id>=1)
{
if(a[id/2]>a[id])
{
swap(&a[id/2],&a[id]);
id = id/2;
}
else
{
return;
}
}
}
}
int main()
{
char s[3];
printf("請輸入相關命令和數據:\n-a 添加數據\n-d 刪除堆頂 \n-g 獲取堆頂元素\n-p 打印堆\n-0 退出\n");
while(1)
{
fflush(stdin);
scanf("%s",s);
if(s[1]=='a')
{
scanf("%d",&a[++size]);
addAdjust(a,size);
//printf("-a\n");
}
else if(s[1]=='d')
{
/*deleteAdjust(a);
printf("堆頂元素已經刪除成功!");
//printf("-d\n");*/
/*
a[1] = a[size--];
heapAdjust(a,1,size);
*/
minDelete(a);
size--;

}
else if(s[1]=='g')
{
printf("目前堆頂元素(即最小元素)為:%d\n",a[1]);
//printf("-g\n");
}
else if(s[1]=='p')
{
int i;
for(i=1;i<=size;i++)
printf("%d ",a[i]);
printf("\n");
//printf("-p\n");
}
else if(s[1]=='0')
{
break;
}
else
{
printf("命令錯誤\n");
printf("請輸入相關命令和數據:\n-a 添加數據\n-d 刪除堆頂 \n-g 獲取堆頂元素\n-p 打印堆\n-0 退出\n");
}
}
printf("操作完成\n");
return 0;
}


 

本次試驗提供了三個進行堆刪除操作的函數  分別利用了不同的方法

前兩種都是通過將a[size] 與a[1] 交換或者說覆蓋然后自上而下的進行調整,一個采用for循環,一個采用遞歸方式。

最后一種直接將堆頂默認為空 然后通過比較子樹 選擇堆頂  然后向下依次延伸  最后跳出循環之后判斷 空出來的位置是不是a[size]

如果不是 將a[id] = a[size]  然后再向上進行調整,當然這樣的話復雜度是前兩種的兩倍。

注意此時size是沒有減小的



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com