您的位置:首页 > 其它

选择排序

2016-03-21 21:26 218 查看
  选择排序的基本方法是:每步从带排序的元素中选出关键词最小(或最大)的元素,顺序放在已排序的元素的最后,直到全部排序完为止。这里介绍简单选择排序和堆排序。

简单选择排序

1.算法思想

  每次从无序区中挑选出一个最小的值,将其与无序区的第一个元素交换,初始有序区为空,无序区包含所有待排序元素。

2.性能分析

  简单选择排序算法的效率与初始数据的顺序无关。



3.完整代码

#include<iostream>
using namespace std;

void select_sort(int a[], int n) {
int k,temp=0;
//每次从无序区中选出最小的元素与无序区的第一个元素交换
for(int i=0;i<n;++i) {
//k标记无序区最小元素
k=i;
for(int j=i+1;j<n;++j)
if(a[j]<a[k])
k = j;

if(k!=i) {
temp = a[i];
a[i] = a[k];
a[k] = temp;
}
}
}

//输出数组
void print_array(int a[],int n) {
for(int i=0;i<n;++i){
cout<<a[i]<<" ";
}
cout<<endl;
}

int main() {
//简单选择排序测试数据
int a[] = {7,3,1,12,5,9};
int n = 6;
cout<<"Before sort:";
print_array(a,n);
cout<<"After binary insertion:";
select_sort(a,n);
print_array(a,n);

return 0;
}


测试结果如下:



堆排序

1.算法思想

  首先按照大根推的定义将数组调整为堆(初始建堆),交换根结点a[0]和最后一个结点a[n-1](将最大元素a[0]归位);然后将a[0]~a[n-2]重新调整为堆,交换a[0]和a[n-2];如此反复,直到交换了a[0]和a[1]。

2.算法过程

(1)维护堆的性质

  AMX-HEAPIFY是用于维护最大堆性质的重要过程。它的输入为一个数组a和一个下标i。在调用MAX-HEAPIFY的时候,我们假定根结点为LEFT(i)和RIGHT(i)的二叉树都是最大堆,但这时a[i]有可能小于其孩子,这样就违背了最大堆的性质。MAX-HEAPIFY通过让a[i]在最大堆中“逐级下降”,从而使得以下标i为根结点的字数重新遵循最大堆的性质。

//假设以index为结点的左右子树Left(index)和Right(index)都为最大堆
//这时a[index]可能小于其孩子
//maxHeapify通过让a[index]在最大堆中“逐级下降”来维持最大堆的性质
void maxHeapify(int a[], int index) {
int l = Left(index);
int r = Right(index);
int largest = 0;
if(l<heapSize && a[l]>a[index])
largest = l;
else largest = index;
if(r<heapSize && a[r]>a[largest])
largest = r;
if(largest != index) {
swap(&a[largest],&a[index]);
maxHeapify(a,largest);
}
}


(2)建堆

  我们可以用自底向上的方法利用过程MAX-HEAPIFY把一个大小为n=A.length的数组a[0]~a[n-1]转换为最大堆。我们知道,每个叶子节点都可以堪称只包含一个元素的堆,通过过程BUILD-MAX-HEAP对树中非叶子结点从下标最大的开始都调用一次MAX-HEAPIFY来建堆。

void buildMaxHeap(int a[],int length) {
heapSize = length;
//含有n个结点的堆的下标最大的非叶子结点的标号为(n-2)/2
for(int i=(length-2)>>1;i>=0;--i)
maxHeapify(a,i);
}


(3)堆排序算法

  调用过程BUILD-MAX-HEAP初始化堆,交换a[0]与堆中最后一个结点,调用MAX-HEAPIFY(a,0),重复这一过程直到堆的大小为1。

void heap_sort(int a[], int length) {
//初始化堆
buildMaxHeap(a,length);
//选择堆的根结点与最后一个结点交换
for(int i=length-1;i>=1;--i){
swap(&a[i],&a[0]);
--heapSize;
maxHeapify(a,0);
}
}


3.性能分析

  堆排序的时间效率与带排序数据的顺序无关。



4.完整代码

#include<iostream>
using namespace std;

int heapSize = 0;

int Left(int index) {
return (index<<1)+1;
}

int Right(int index) {
return (index<<1)+2;
}

void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
//假设以index为结点的左右子树Left(index)和Right(index)都为最大堆 //这时a[index]可能小于其孩子 //maxHeapify通过让a[index]在最大堆中“逐级下降”来维持最大堆的性质 void maxHeapify(int a[], int index) { int l = Left(index); int r = Right(index); int largest = 0; if(l<heapSize && a[l]>a[index]) largest = l; else largest = index; if(r<heapSize && a[r]>a[largest]) largest = r; if(largest != index) { swap(&a[largest],&a[index]); maxHeapify(a,largest); } }

void buildMaxHeap(int a[],int length) {
heapSize = length;
for(int i=(length-2)>>1;i>=0;--i)
maxHeapify(a,i);
}

void heap_sort(int a[], int length) {
buildMaxHeap(a,length);
for(int i=length-1;i>=1;--i){
swap(&a[i],&a[0]);
--heapSize;
maxHeapify(a,0);
}
}

//输出数组
void print_array(int a[],int n) {
for(int i=0;i<n;++i){
cout<<a[i]<<" ";
}
cout<<endl;
}

int main() {
//直接插入测试数据
int a[] = {4,10,16,2,12,9,7};
int n = 7;
cout<<"Before sort:";
print_array(a,n);
cout<<"After heap-sort:";
heap_sort(a,n);
print_array(a,n);
cout<<endl;

return 0;
}


测试结果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息