您的位置:首页 > 其它

算法基础_8大经典排序算法实现回顾

2017-03-31 10:10 579 查看

冒泡排序

//冒泡
void sort(int ary[],int size){
int temp;
int hasChange;
//size-1次比较
for (int i = 0; i < size - 1; i++) {
hasChange = 0;
//前size-1-i个元素比较
for (int j = 0; j < size - 1 - i; j++) {

if (ary[j] > ary[j+1]) {
temp = ary[j];
ary[j] = ary[j+1];
ary[j+1] = temp;
hasChange = 1;
}
}
//优化,如果此轮没有变化,后面就不用再比了
if (!hasChange) {
break;
}
}
}


选择排序

void selectSort(int ary[],int size){
for (int i = 0; i < size; i++) {
int min = i;
int temp = ary[i];
for (int j = i + 1; j < size; j++) {
if (ary[j] <= ary[min]) {
min = j;//记录最小值坐标
}
}
ary[i] = ary[min];//将最小值交换到左侧
ary[min] = temp;
}
}

直接插入排序

void insertSort(int unsorted[],int size)
{
//从头组建,左侧的都是排好的
for (int i = 1; i < size; i++)
{
int temp = unsorted[i];//记住待比较值
int j = i;//设置启始比较位置
// 待比较值往前一个一个比,若成立,将元素后移
while (j > 0 && unsorted[j - 1] > temp)
{
//往后挪
unsorted[j] = unsorted[j - 1];
j--;
}
//找到位置,将待比较值值插入
unsorted[j] = temp;
}
}

折半插入排序

//折半插入排序,不用一个一个往前比,利用二分发找到合适位置
void binaryInsertSort(int ary[],int size){
for (int i = 1; i < size; i++) {
int low = 0;
int high = i - 1;
int temp = ary[i];
while (low <= high) {
int mid = (low + high)/2;
if (temp > ary[mid]) {
low = mid + 1;            }

else{
high = mid - 1;
}
}
for (int j = i; j > low; j--) {
ary[j] = ary[j - 1];
}
ary[low] = temp;
}
}

快速排序

void quickSort(int ary[],int left,int right){
if (left >= right) {
return;
}
int i = left;
int j = right;
int base = ary[i];
while (i < j) {
while (i < j && ary[j] >= base) {
j--;
}
if (i < j) {
ary[i] = ary[j];//把i填上,j空了
}

while (i < j && ary[i] <= base) {
i++;
}
if (i < j) {
ary[j] = ary[i];//j填上,i有空了
}
}
ary[i] = base;
quickSort(ary, left, i - 1);
quickSort(ary, i + 1, right);
}

希尔排序

//先按增量分段,割裂成子序列进行直接插入,减少增量,重复,最后再进行一次直接插入排序
void shellSort(int ary[],int size){
for (int gap = size/2; gap > 0; gap = gap/2) {//每次gap减半,确定间隔
for (int i = 0; i < gap; i++) {//每个组内启始点在gap范围内
for (int j = i + gap; j < size; j+=gap) {//找组内成员
//直接插入排序
int temp = ary[j];
int k = j;
while (k >= 0 && ary[k-gap] >= temp)
{
ary[k] = ary[k - gap];
k -= gap;
}
ary[k] = temp;
}
}
}
}

归并排序

//合并数组
void mergeAry(int ary[],int f,int m,int l,int temp[]){
int midA = m + 1;
int i = 0;
int first = f;
//前后两部分(两部分组内都是有序的)合并到temp中
while (f <= m && midA <= l) {
if (ary[f] <= ary[midA]) {
temp[i++] = ary[f++];
}
else{
temp[i++] = ary[midA++];
}
}
while (f <= m) {
temp[i++] = ary[f++];
}
while (midA <= l) {
temp[i++] = ary[midA++];
}
//把合并好的temp,加回ary
for (int j = 0; j < i; j++) {
ary[first + j] = temp[j];
}
}

void mergeSort(int ary[],int f,int l,int temp[]){
if (f < l) {
int mid = (f+l)/2;
mergeSort(ary,f,mid,temp);//先不断分解
mergeSort(ary,mid + 1,l,temp);
mergeAry(ary, f, mid, l, temp);//再合并
}
}

堆排序

/*
//大根堆 小跟堆,父节点比大(小)于子节点
就是不断整理成堆的格式,输出堆顶,然后再调整
初始时把要排序的n个数的序列看作是一棵顺序存储的二叉树(一维数组存储二叉树),调整它们的存储顺序,使之成为一个堆,将堆顶元素输出,这时堆顶的数最小(或者最大)。然后对前面(n-1)个元素重新调整使之成为堆,输出堆顶元素,得到n 个元素中次小(或次大)的元素。依此类推,直到只有两个节点的堆,并对它们作交换,最后得到有n个节点的有序序列。称这个过程为堆排序。
*/
//堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置
//根放在0位置,以后假定当前位置是i,那么左子结点在2i+1,右子结点在2i+2

//交换元素
void swap(int ary[],int i,int j){
int temp = ary[i];
ary[i] = ary[j];
ary[j] = temp;
}

//大堆化
void beMaxHeap(int ary[],int i,int length){
int l = 2 * i + 1;
int r = l + 1;
int max = i;
if (l < length && ary[l] > ary[i]) {
max = l;
}
if (r < length && ary[r] > ary[max]) {
max = r;
}
if (max != i) {
swap(ary, i, max);
//产生了交换,根被下移,破坏了子树的堆特性,继续逐级下降堆化
beMaxHeap(ary, max, length);
}
}

//初始化堆
void buildMaxHeap(int ary[],int length){
for(int i = length/2 + 1;i>=0;i--){
beMaxHeap(ary, i, length);
}
}

//排序
void heapSort(int ary[],int length){
//初始化堆
buildMaxHeap(ary, length);
int l = length;
for(int i = length - 1;i > 0;i--){
//将堆顶交换至末尾
swap(ary, 0, i);
l--;
//堆化
beMaxHeap(ary, 0, l);
}

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