各类排序算法模拟实现

28 篇文章 0 订阅
20 篇文章 1 订阅

1、插入排序类


1.1 直接插入排序

时间复杂度O(n^2) 空间复杂度O(1)

1.1.1 基本思想:

每一步将一个待排序的元素,按其排序码的大小,插入到前面已经排好序的一组元素的合适位置上去,直到元素全部插完位置。

这里写图片描述

1.1.2 源码
#include<stdio.h>
#include<Windows.h> 
#include<iostream>

using namespace std;

void InsertSort(int array[], size_t size){
    for (size_t i = 1; i < size; ++i){
        int key = array[i];
        int cur = i - 1;
        while (cur >= 0 && key < array[cur]){
            array[cur + 1] = array[cur];
            cur--;
        }
        array[cur + 1] = key;
    }
}

void Print(int array[], size_t size){
    for (size_t i = 0; i < size; ++i){
        cout << array[i] << "  ";
    }
    cout << endl;
}

void test_InsertSort(){
    int array[] = { 2, 5, 4, 9, 3, 6, 8, 7, 1, 0 };
    Print(array, sizeof(array) / sizeof(array[0]));
    InsertSort(array, sizeof(array) / sizeof(array[0]));
    Print(array, sizeof(array) / sizeof(array[0]));
}

int main(){

    test_InsertSort();
    system("pause");
    return 0;
}

程序运行结果:

这里写图片描述


1.2 直接插入排序算法优化–折半插入排序算法

这里写图片描述

1.2.1 源码实现:
#include<stdio.h>
#include<Windows.h>
#include<iostream>

using namespace std;

int BinSearch(int array[],int key, int start, int last){
    int begin = start;
    int end = last;
    int mid;
    while (begin <= end){
        mid = (begin + end) / 2;
        if (key < array[mid]){
            end = mid-1;
        }
        else{
            begin = mid+1;
        }
    }
    return begin;
}

void InsertSort_op (int array[], size_t size){
    for (size_t i = 1; i < size; ++i){
        int key = array[i];
        int cur = i - 1;
        //折半查找法查找位置
        int find = BinSearch(array, key, 0, cur);

        //搬移元素
        for (size_t j = i; j > find; --j) {
            array[j] = array[j - 1];
        }
        //插入元素
        array[find] = key;
    }
}


void Print(int array[], size_t size){
    for (size_t i = 0; i < size; ++i){
        cout << array[i] << "  ";
    }
    cout << endl;
}

void test_InsertSort(){
    int array[] = { 2, 5, 4, 9, 3, 6, 8, 7, 1, 0 };
    Print(array, sizeof(array) / sizeof(array[0]));
    InsertSort_op(array, sizeof(array) / sizeof(array[0]));
    Print(array, sizeof(array) / sizeof(array[0]));
}

int main(){

    test_InsertSort();
    system("pause");
    return 0;
}
程序运行结果:

这里写图片描述


1.3 希尔排序—缩小增量排序

1.3.1 希尔排序思想

一组元素按照不同的gap值划分成不同的组(gap)

这里写图片描述

gap–;再继续重复以上过程。

1.3.2 程序源码:

#include<stdio.h>
#include<Windows.h>
#include<iostream>

using namespace std;

void Shellsort(int array[], int size){
    int gap = size;
    while (gap > 1){
        gap = gap >> 1;
        for (size_t i = gap; i < size; ++i){
            int key = array[i];
            int cur = i - gap;
            while (cur >= 0 && key < array[cur]){
                array[cur + gap] = array[cur];
                cur-=gap;
            }
            array[cur+gap] = key;
        }
    }

}

void Print(int array[], size_t size){
    for (size_t i = 0; i < size; ++i){
        cout << array[i] << "  ";
    }
    cout << endl;
}

void test_InsertSort(){
    int array[] = { 2, 5, 4, 9, 3, 6, 8, 7, 1, 0 };
    Print(array, sizeof(array) / sizeof(array[0]));
    Shellsort(array, sizeof(array) / sizeof(array[0]));
    Print(array, sizeof(array) / sizeof(array[0]));
}

int main(){

    test_InsertSort();
    system("pause");
    return 0;
}

程序运行结果:

这里写图片描述


2. 选择排序


2.1 选择排序法(单向)

2.1.1 算法思想:

第一趟遍历数组选出最大元素,存入数组最后一个位置。

第二趟遍历数组选出次大元素,存入数组倒数第二个位置。

以此类推…

直到数组有序

2.1.2 源码:
#include<stdio.h>
#include<Windows.h>
#include<iostream>

using namespace std;

void selectsort(int array[], int size){
    for (size_t i = 0; i < size; ++i){
        int max = 0;
        int max_dex = 0;
        for (size_t j = 0; j < size - i; ++j){
            if (array[j]>max){
                max = array[j];
                max_dex = j;
            }

        }
        array[max_dex] = array[size - 1 - i];
        array[size - 1 - i] = max;
    }
}

void Print(int array[], size_t size){
    for (size_t i = 0; i < size; ++i){
        cout << array[i] << "  ";
    }
    cout << endl;
}

void test_InsertSort(){
    int array[] = { 2, 5, 4, 9, 3, 6, 8, 7, 1, 0 };
    Print(array, sizeof(array) / sizeof(array[0]));
    selectsort(array, sizeof(array) / sizeof(array[0]));
    Print(array, sizeof(array) / sizeof(array[0]));
}

int main(){

    test_InsertSort();
    system("pause");
    return 0;
}
程序运行结果:

这里写图片描述


2.2 优化选择排序(双向)


2.2.1 基本思路:

与上面的单向选择排序算法基本相同,不过这个是双向的。

也就是定义两个变量,一个标记最大值,一个标记最小值,算法与上述相同,不过是在数组右侧存放大值,左侧存放小值。

2.2.2 源码:

#include<stdio.h>
#include<Windows.h>
#include<iostream>

using namespace std;


void selectsort(int array[], int size){
    int start = 0;
    int end = size-1;
    while (start < end){
        int max = 0;
        int max_dex = 0;
        int min=array[start];
        int min_dex = start;
        for (size_t j = start; j <= end; ++j){
            if (array[j]>max){
                max = array[j];
                max_dex = j;
            }
            if (array[j] < min){
                min = array[j];
                min_dex = j;
            }

        }
        array[max_dex] = array[end];
        array[end] = max;
        if (min_dex == end)
            min_dex = max_dex;
        array[min_dex] = array[start];
        array[start] = min;
        start++;
        end--;
    }
}

void Print(int array[], size_t size){
    for (size_t i = 0; i < size; ++i){
        cout << array[i] << "  ";
    }
    cout << endl;
}

void test_InsertSort(){
    int array[] = { 2, 5, 4, 9, 3, 6, 8, 7, 1, 0 };
    Print(array, sizeof(array) / sizeof(array[0]));
    selectsort(array, sizeof(array) / sizeof(array[0]));
    Print(array, sizeof(array) / sizeof(array[0]));
}

int main(){

    test_InsertSort();
    system("pause");
    return 0;
}
程序运行结果:

这里写图片描述


2.3 堆排序

【数据结构】堆结构小根堆,大根堆,插入,删除等操作的实现

程序源码:

#include<stdio.h>
#include<Windows.h>
#include<iostream>

using namespace std;


void AdjustDown(int array[], int root,int size){
    int parent = root;
    //默认左孩子值大
    //如果parent是叶节点就不用进行调整 
    while (parent<(size>>1)){
        int max_child = (parent << 1) + 1;
        //调整左右子树的最大值
        if (max_child < (size-2) && array[max_child] < array[max_child + 1])
            ++max_child;
        //调整树
        if (array[parent] < array[max_child])
            swap(array[parent], array[max_child]);
        parent = max_child;
    }
}


void HeapSort(int array[], int size){
    int lastnleaf = (size >> 1) - 1;//最后一个非叶子节点的下标
    //构堆
    for (int i = lastnleaf; i >= 0; --i){
        AdjustDown(array, i,size);
    }
    //堆顶元素依次为最大值,从堆中拿出最大值调整最大值在数组中的位置
    for (size_t i = 0; i < size; ++i){
        swap(array[0], array[size - 1 - i]);
        AdjustDown(array, 0, size - i - 1);
    }
}

void Print(int array[], size_t size){
    for (size_t i = 0; i < size; ++i){
        cout << array[i] << "  ";
    }
    cout << endl;
}

void test_InsertSort(){
    int array[] = { 2, 5, 4, 9, 3, 6, 8, 7, 1, 0 };
    Print(array, sizeof(array) / sizeof(array[0]));
    HeapSort(array, sizeof(array) / sizeof(array[0]));
    Print(array, sizeof(array) / sizeof(array[0]));
}

int main(){

    test_InsertSort();
    system("pause");
    return 0;
}
程序运行结果:

这里写图片描述


3、交换排序


3.1 冒泡排序算法

程序源码:
#include<stdio.h>
#include<Windows.h>
#include<iostream>

using namespace std;

void bubble_sort(int arr[], int sz)
{
    int i = 0;
    int j = 0;
    for (i = 0; i<sz - 1; i++)
    {
        for (j = 0; j<sz - 1 - i; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                arr[j] ^= arr[j + 1];
                arr[j + 1] ^= arr[j];
                arr[j] ^= arr[j + 1];
            }
        }
    }
}

void Print(int array[], size_t size){
    for (size_t i = 0; i < size; ++i){
        cout << array[i] << "  ";
    }
    cout << endl;
}

void test_InsertSort(){
    int array[] = { 2, 5, 4, 9, 3, 6, 8, 7, 1, 0 };
    Print(array, sizeof(array) / sizeof(array[0]));
    bubble_sort(array, sizeof(array) / sizeof(array[0]));
    Print(array, sizeof(array) / sizeof(array[0]));
}

int main(){

    test_InsertSort();
    system("pause");
    return 0;
}
程序运行结果:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值