选择排序
2016-03-21 21:26
218 查看
选择排序的基本方法是:每步从带排序的元素中选出关键词最小(或最大)的元素,顺序放在已排序的元素的最后,直到全部排序完为止。这里介绍简单选择排序和堆排序。
每次从无序区中挑选出一个最小的值,将其与无序区的第一个元素交换,初始有序区为空,无序区包含所有待排序元素。
2.性能分析
简单选择排序算法的效率与初始数据的顺序无关。
3.完整代码
测试结果如下:
首先按照大根推的定义将数组调整为堆(初始建堆),交换根结点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为根结点的字数重新遵循最大堆的性质。
(2)建堆
我们可以用自底向上的方法利用过程MAX-HEAPIFY把一个大小为n=A.length的数组a[0]~a[n-1]转换为最大堆。我们知道,每个叶子节点都可以堪称只包含一个元素的堆,通过过程BUILD-MAX-HEAP对树中非叶子结点从下标最大的开始都调用一次MAX-HEAPIFY来建堆。
(3)堆排序算法
调用过程BUILD-MAX-HEAP初始化堆,交换a[0]与堆中最后一个结点,调用MAX-HEAPIFY(a,0),重复这一过程直到堆的大小为1。
3.性能分析
堆排序的时间效率与带排序数据的顺序无关。
4.完整代码
测试结果如下:
简单选择排序
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;
}
测试结果如下:
相关文章推荐
- JavaScript演示排序算法
- 堆排序
- C#堆排序实现方法
- 算法之排序算法的算法思想和使用场景总结
- PHP版本常用的排序算法汇总
- JavaScript实现多种排序算法
- php 地区分类排序算法
- js三种排序算法分享
- Javascript中的常见排序算法
- java 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序算法的描述
- Java数据结构及算法实例:选择排序 Selection Sort
- Java中的数组排序方式(快速排序、冒泡排序、选择排序)
- 排序算法的javascript实现与讲解(99js手记)
- C++中十种内部排序算法的比较分析
- Java实现几种常见排序算法代码
- php堆排序实现原理与应用方法
- 浅谈javascript实现八大排序
- PHP简单选择排序算法实例
- PHP常用的排序和查找算法
- JavaScript中九种常用排序算法