排序算法:堆排序


参考博客:http://blog.csdn.net/xiaoxiaoxuewen/article/details/7570621

堆排序:

即给定一个数组,

第一阶段是先初始化堆:

       步骤是:1. 从倒数第一个非叶子节点开始,与它的左右孩子比较,若小于任何一个,即把它们交换;(注意,交换后,若不是倒数第一个非叶子节点,一旦交换,有可能引起新的堆顶元素小于它的左或者右孩子,需要再交换(递归处理)

                      2. 依次从倒数第二个非叶子节点开始......


第二个阶段:排序:

    步骤是:1. 把顶元素R[1]与倒数第一个元素R[n]进行交换,然后这时堆原有秩序有可能打破(R[1....n-1]需要重新检查排序,用初始化的方式)

                   2. 吧顶元素R[1]与倒数第二个元素R[n-1]进行交换,........

                    3. 依次类推。。。

注意这使得堆是先序的形式完全二叉树

void main()
{
    int[] list = new int[] { 3, 9, 8, 5, 7, 7, 12, 1 };
            int len=list.Length;

            HeapSort heap = new HeapSort();
            heap.InitHeap(list, len);
            for(int i = 0;i<len;i++)
            {
                Console.Write(list[i] + " ");
            }
            Console.WriteLine("");

            heap.SortHeap(list, len);
            for (int i = 0; i < len; i++)
            {
                Console.Write(list[i] + " ");
            }
            Console.WriteLine("");
}



 public class HeapSort
    {
        //初始化堆的流程:1. 从最后一个非叶子节点开始判断(判断改节点与他的左右节点比较,是不是最大的;若不是最大的,就交换这两个节点, 注意交换之后,若它的孩子节点的不符合大顶堆,也要通过递归再做调整)
        //               2. 依次类推去判断倒数第二个非叶子节点.....
        public void InitHeap(int[] list, int len)
        {
            if(list==null||len<=0) return;

            for (int i = len / 2 - 1; i >= 0; i--)
            {
                AdjustHeap(list, i, len);
            }
        }

        private void swap(int[] list, int index1, int index2)
        {
            int temp = list[index1];
            list[index1] = list[index2];
            list[index2] = temp;
        }

        //判断改节点与他的左右节点比较,是不是最大的;若不是最大的,就交换这两个节点, 注意交换之后,若它的孩子节点的不符合大顶堆,也要通过递归再做调整
        public void AdjustHeap(int[] list, int currentIndex, int len)
        {
            if (list == null || currentIndex < 0 || len <= 0) return;
            int lChildIndex = 2 * (currentIndex + 1) - 1;
            int rChidIndex = 2 * (currentIndex + 1);

            if (currentIndex <= len / 2 - 1)
            {
                int maxIndex = currentIndex;
                if (lChildIndex<len && list[maxIndex] < list[lChildIndex])
                {
                    maxIndex = lChildIndex;
                }

                if (rChidIndex<len && list[maxIndex] < list[rChidIndex])
                {
                    maxIndex = rChidIndex;
                }

                if (maxIndex != currentIndex)
                {
                    swap(list, maxIndex, currentIndex);
                    AdjustHeap(list, maxIndex, len);
                }
            }
        }

        //堆排序:1. 就是拿堆顶元素R[1]与倒数第一个叶子节点R[n]进行交换,交换后,看R[1...R-1]是否仍是大顶堆,若不是,需要调整(注意这里有递归)
        //        2. 依次拿堆定元素R[1]余倒数第二个叶子节点R[n-1]进行交换,交换后,看R[1...n-2]是否仍是大顶堆........
        //        3. 依次到最后一个元素
        public void SortHeap(int[] list, int len)
        {
            for(int i=len-1; i>=0; i--)
            {
                swap(list, 0, i);
                AdjustHeap(list, 0, i - 1);
            }
        }
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值