今天复习了下快排和堆排 ,也上网查了下,随便写点,当笔记,以后忘记了就不用再百度了。
快排:就我理解,如果要从小到大排列,应该是把大数放到后面,然后把小数放前面,每放一个大数就high--;放一个小数low++;然后在high和low相交的时候把Key放在相交的索引上,其实key也就是大数小数的临界点。
下面是代码:
public static void QuickSort(int[] a, int low, int high)
{
if (low < high)
{
int middle = NewGetMiddleSort( a, low, high);
QuickSort( a, low, middle - 1);
QuickSort( a, middle + 1, high);
}
}
//先保存a[low],因为从高的开始比,遇到小的把把a[low]替换掉;然后从小的开始比;
//把大于枢轴的放在右边,小于的放在左边,然后每放一个大的high--,小的Low++;
//low==high的时候是相对枢轴的临界点,把枢轴放上去;
public static int NewGetMiddleSort( int[] a, int low, int high)
{
//Set the key
//If you want to set a[i] as the key,you can exchange the a[low] and a[i]
//value outside the method,and then set the a[low] as the key;
int key = a[low];
while (low < high)
{
while ((low < high) && (a[high] >=key)) high--;
a[low] = a[high];
while ((low < high) && (a[low] <key)) low++;
a[high] = a[low];
}
//更新枢轴
a[low] = key;
return low;
}
参考资料:百度;
堆排:
堆排,n个元素,从小到大排列的话先建大顶堆;然后每次把根结点与要排序的最后一个结点交换,再重新建 i 个元素的大顶堆;
//重建大顶堆的时候因为只有根元素发生的变动,所以只要判断根结点和它的孩子的大小,若符合大顶堆,
//则无需重建,若根结点与子结点进行了交换,则需对以该子结点为父结点的树进行检索并使它符合大顶堆
public static void Heap(int[] a, int startRoot,int length)
{
//index from 0;
//左孩子;2*root+1
int root=startRoot;
for (int j = 2 * root + 1; j < length; j = j * 2+1)
{
if (j + 1 <= length - 1 && a[j + 1] > a[j])
{
j++;
}
if (a[j] <= a[root])
{
break;
}
int temp = a[j];
a[j] = a[root];
a[root] = temp;
//由于更换了root的子结点,则以该子结点为父结点的树重新调整;
root = j;
}
}
//length 表示结点个数;
public static void CreateBigHeap(int[] a)
{
int length = a.Length;
for (int i = (length - 1) / 2; i >= 0; i--)
{
Heap(a, i, length);
}
}
public static void HeapSort(int[] a)
{
CreateBigHeap(a);
int temp;
for (int i = a.Length - 1; i >= 1; i--)
{
temp = a[i];
a[i] = a[0];
a[0] = temp;
Heap(a, 0, i);
}
}