您的位置:首页 > 其它

排序--堆排序

2016-06-06 16:52 344 查看
堆排序的时间复杂度是 O( nlogn ) ,由于是跳跃式的排序,所以堆排序属于不稳定排序。

C# 版

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharp
{
class Program
{
static void AdjustHeap(int[] arr, int head, int length)
{
int tmp = arr[head];
for ( int j = head * 2; j < length; j *= 2 )
{
if (arr[j] < arr[j + 1]) ++j; // 从两个子节点中找出值较大者
if (tmp > arr[j]) break; // 如果根节点大于两子节点,退出循环
arr[head] = arr[j]; // 把子节点的值赋给根节点
head = j; // 根节点后移
}
arr[head] = tmp;
}
static void Main(string[] args)
{
int[] arr = { 0, 50, 10, 90, 30, 70, 40, 80, 60, 20 }; // 0作为哨兵,哨兵值小其他元素的值
for (int i = arr.Length / 2; i > 0; --i) // i = length / 2:满足完全二叉树的性质
{
AdjustHeap( arr, i, arr.Length );
}
for ( int i = 0; i < arr.Length; ++i )
{
Console.Write( arr[i] + ", " );
}
Console.WriteLine();

for ( int i = arr.Length - 1; i > 2; -- i )
{
int tmp = arr[1]; // 交换根节点和堆尾节点的值
arr[1] = arr[i];
arr[i] = tmp;
AdjustHeap(arr, 1, i - 1); // 重新做堆排序
}
for (int i = 0; i < arr.Length; ++i)
{
Console.Write(arr[i] + ", ");
}

Console.ReadLine();
}
}
}


C 版

// c.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

void AdjustHeap(int* arr, int head, int length)
{
int tmp = arr[head] ;
int j = 2 * head ;
for (; j < length; j *= 2)
{
if (j < length && arr[j] < arr[j + 1]) ++j ; // 从两个子节点中找出值较大者
if (tmp >= arr[j]) break ; // 如果根节点大于两子节点,退出循环
arr[head] = arr[j] ; // 把子节点的值赋给根节点
head = j ; // 根节点后移
}
arr[head] = tmp ;
}

int _tmain(int argc, _TCHAR* argv[])
{
int arr[] = {0, 50, 10, 90, 30, 70, 40, 80, 60, 20}; // 0作为哨兵,哨兵值小其他元素的值
int length = 10 ;
for (int i = length / 2; i > 0; --i) // i = length / 2:满足完全二叉树的性质
{
AdjustHeap(arr, i, length);
}
for (int i = 0; i < length; ++i)
{
printf("%d, ", arr[i]) ;
}
printf("\n");

for (int i = length - 1; i > 2; --i)
{
int tmp = arr[1] ; // 交换根节点和堆尾节点的值
arr[1] = arr[i] ;
arr[i] = tmp ;
AdjustHeap(arr, 1, i - 1); // 重新做堆排序
}
for (int i = 0; i < length; ++i)
{
printf("%d, ", arr[i]) ;
}
getchar();
return 0;
}


C++ 版

// C++.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <vector>
#include <iostream>
using namespace::std;

void AdjustHeap(vector<int>& vec, int head, int length)
{
int tmp = vec[head] ;
for (int j = head * 2; j < length; j *= 2)
{
if (vec[j] < vec[j + 1]) ++j ; // 从两个子节点中找出值较大者
if (tmp > vec[j]) break ; // 如果根节点大于两子节点,退出循环
vec[head] = vec[j] ; // 把子节点的值赋给根节点
head = j ; // 根节点后移
}
vec[head] = tmp ;
}

int _tmain(int argc, _TCHAR* argv[])
{
int arr[] = {0, 50, 10, 90, 30, 70, 40, 80, 60, 20}; // 0作为哨兵,哨兵值小其他元素的值
vector<int> vec(arr, arr + 10);
for (int i = vec.size() / 2; i > 0; --i)// i = length / 2:满足完全二叉树的性质
{
AdjustHeap(vec, i, vec.size());
}
for (vector<int>::iterator it = vec.begin(); it != vec.end(); ++it)
{
cout << *it << ", " ;
}
cout << endl;

for (int i = vec.size() - 1; i > 2; --i)
{
swap(vec[1], vec[i]); // 交换根节点和堆尾节点的值
AdjustHeap(vec, 1, i - 1); // 重新做堆排序
}
for (vector<int>::iterator it = vec.begin(); it != vec.end(); ++it)
{
cout << *it << ", " ;
}
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: