第一种方法,一个一个插入
第二种方法,全部插进去再从N/2开始一个一个比较向前移动
二话不说上代码,具体的都在注释里了
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int check(int *array, int i);
int main()
{
int array[100]={0};//储存我的所有数据//
int way1[100]={0};//用第一种方法一个一个插入//
int N;
int j=1;
int temp;
int k=0;
scanf("%d",&N);//得到我需要插多少个数//
for(int i=1;i<=N;i++)//从1开始而不是从0开始,这里用的是数组的方法//
{
scanf("%d,",&array[i]);
}
//way1//
for(int i=1;i<=N;i++)
{
way1[j]=array[i];//j为即将对比的第几个数//
k=j;
while(way1[k]<way1[k/2])//从第j个开始,如果它比它的父亲节点小//
{
temp=way1[k];
way1[k]=way1[k/2];
way1[k/2]=temp;//交换它和它的父亲节点//
k=k/2;//继续比较这个数和它新的父亲节点//
}
j++;
}
//按照要求打印出来//
for(int i=1;i<N+1;i++)
{
printf("%d",way1[i]);
if(i!=N)
{
printf(",");
}
}
printf("\n");
//way2//
for(int i=N/2;i>0;i--)
{
check(array,i);//详见check函数//
}
//按照要求打印出来//
for(int i=1;i<N+1;i++)
{
printf("%d",array[i]);
if(i!=N)
{
printf(",");
}
}
return 0;
}
int check(int *array, int i)
{//要对第i个数进行一系列的操作//
int m,n;
int temp;
m=2*i;//m是它的左节点//
n=2*i+1;//n是它的右节点//
//如果两个子节点都存在//
if(array[m]!=0&&array[n]!=0)
{
if(array[m]<array[n])//选出两个子节点中最小的那个和父亲节点交换位置//
{
if(array[i]>array[m])
{
temp=array[i];
array[i]=array[m];
array[m]=temp;
check(array,m);//继续比较新的子节点(也就是我们刚才操作的那个数)和新的子节点的子节点//
}
}
else
{
if(array[i]>array[n])//同理//
{
temp=array[i];
array[i]=array[n];
array[n]=temp;
check(array,n);
}
}
return 0;
}
//如果没有子节点//
else if(array[m]==0&&array[n]==0)
{
return 0;
}
//如果有一个子节点//
//在这种情况下只有左节点存在,因为我们是按照顺序建的树//
else
{
if(array[m]<array[i])
{
temp=array[i];
array[i]=array[m];
array[m]=temp;
check(array,m);
}
else
{
return 0;
}
}
return 0;
}