---------当然这里讲的是完全二叉树的一个排序
直接上代码
int[] _test = { 99, 5, 36, 2, 19, 1, 46, 12, 7, 22, 25, 28, 17, 92 };//这个就是我们的完全二叉树
n = _test.Length - 1;
for (int i = n / 2; i >-1; i--)//在这里除以2是因为,所有的子叶节点都不用计算!!!
{
siftdown(i);//每次将i传递进来进行排序
}
public void siftdown(int i)
{
int flag = 0, t;
while (i * 2 <=n && flag == 0)
{
//首先判断左儿子
if (_test[i] > _test[i * 2])
{
t = i * 2;
}
else
{
t = i;
}
//判断右儿子
if (i * 2 + 1 <= n)
{
if (_test[i * 2 + 1] < _test[t])//如果右儿子小的话
{
t = i * 2 + 1;
}
}
//交换这两个数
if (t != i)
{
_test[t] ^= _test[i];
_test[i] ^= _test[t];
_test[t] ^= _test[i];
i = t;//继续向下
}
else
{
flag = 1;
}
}
}
进行排序
int deletemax()
{
int t;
t = _test[0];
_test[0] = _test[n];
n--;
siftdown(0);
return t;
}
当然进行排序的方法不止这一个,
public void heapSort()
{
while (n>0)
{
_test[0] ^= _test[n];
_test[n] ^= _test[0];
_test[0] ^= _test[n];
n--;
siftdown1(0);
}
}
上面代码的意思也就是说,每次让第一个数和最后一个数交换位置,因为在这里我们的排序规则和上面的不一样了!!!
所以呢,每次取一个小的数,在堆里面就行排序,排完了顺序也就出来了
public void siftdown1(int i)
{
int flag = 0, t;
while (i * 2 <= n && flag == 0)
{
//首先判断左儿子
if (_test[i] < _test[i * 2])
{
t = i * 2;
}
else
{
t = i;
}
//判断右儿子
if (i * 2 + 1 <= n)
{
if (_test[i * 2 + 1] > _test[t])//如果右儿子小的话
{
t = i * 2 + 1;
}
}
//交换这两个数
if (t != i)
{
_test[t] ^= _test[i];
_test[i] ^= _test[t];
_test[t] ^= _test[i];
i = t;//继续向下
}
else
{
flag = 1;
}
}
}
可以看到,我们只是简单的将判断的符号改了
public void Create()
{
n = _test.Length - 1;
for (int i = n / 2; i >-1; i--)//在这里除以2是因为,所有的子页节点都不用计算!!!
{
siftdown1(i);//每次将i传递进来进行排序
}
for (int i = 0; i < _test.Length; i++)
{
Console.WriteLine(_test[i]);
}
Console.WriteLine("---------->");
heapSort();
for (int i = 0; i < _test.Length; i++)
{
Console.WriteLine(_test[i]);
}
}
从图上我们可以知道我们是从大到小排序的