C#实现堆排序

来源:互联网 发布:c语言入门到精通 pdf 编辑:程序博客网 时间:2024/05/21 12:45

感谢morewindows http://blog.csdn.net/morewindows/article/details/6709644


using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace 排序{    class HeapSort    {        //堆的插入,a[i]为待插入的数值,其父节点为(i-1)/2        public void InsertHeap(int[]a,int i)        {            print(a, a.Length);            int temp = a[i];            int j = (i - 1) / 2; //父节点            //加入判断条件i!=0是为了防止在j=0是陷入死循环            while(j>=0 && i!=0)            {                if (a[j] <= a[i]) break;                a[i] = a[j];                i = j;                j = (i - 1) / 2;            }            a[i] = temp;            print(a, a.Length);        }       //堆插入的简短表达        public void InsertHeap2(int[]a,int i)        {            int j;           // print(a, a.Length);            //注意这里应该是a[i]<a[j].因为求得是最小堆            for(j=(i-1)/2;(j>=0&&i!=0)&&(a[i]<a[j]);i=j,j=(i-1)/2)                swap(ref a[i],ref a[j]);           // print(a, a.Length);        }                                                                                                                                     private void print(int[] a, int n)        {            for (int i = 0; i < n; i++)            {                Console.Write("{0}  ", a[i]);            }            Console.WriteLine("\t");        }                                                                                                                                    private void swap(ref int a, ref int b)        {            int t = a; a = b; b = t;        }                                                                                                                                   //堆删除:“按定义,堆中每次都只能删除第0个数据。为了便于重建堆,实际的操作是将最后一个数据的值赋给根结点,然后再从根结点开始进行一次从上向下的调整。调整时先在左右儿子结点中找最小的,如果父结点比这个最小的子结点还小说明不需要调整了,反之将父结点和它交换后再考虑后面的结点。相当于从根结点将一个数据的“下沉”过程。”来自morewindows        public void DeleteHeap(int[]a,int n)        {            print(a, a.Length);         InsertHeap2(a, n-1);             print(a, a.Length);            swap(ref a[0], ref a[n - 1]);            print(a, a.Length);            int i = 0;            int j = 2 * i + 1;            int temp = a[i];            while(j<n-1)            {                //2*i+2 的节点小于2*i+1节点的值,j++                if (j + 1 < n-1 && a[j + 1] < a[j]) j++;                if (a[j] >= temp) break;                //a[i] = a[j]; 1式                swap(ref a[i], ref a[j]);// 2式,也可以用1式和3式代替2式                i = j;                j = 2 * i + 1;            }           // a[i] = temp; 3式            print(a, a.Length);        }    }}

堆化数组,因为最底层的每个子节点都可以认为已经是一个标准堆,所以i=n/2-1还是算起

public void ToHeap(int[]a,int n)        {            print(a, a.Length);            for(int i=n/2-1;i>=0;i--)            {                FixDown(a,i,n);            }            print(a, a.Length);        }        public void FixDown(int[]a,int i,int n)        {            //和deleteheap基本一致            //int i = 0;            int j = 2 * i + 1;            int temp = a[i];            while (j < n - 1)            {                //2*i+2 的节点小于2*i+1节点的值,j++                if (j + 1 < n - 1 && a[j + 1] < a[j]) j++;                if (a[j] >= temp) break;                a[i] = a[j];                //swap(ref a[i], ref a[j]);                i = j;                j = 2 * i + 1;            }            a[i] = temp;        }



0 0
原创粉丝点击