王道计算机数据结构+插入排序、冒泡排序、希尔排序、快速排序、简单选择排序

本内容是基于王道计算机数据结构的插入排序、冒泡排序、希尔排序、快速排序、简单选择排序整理。

文章目录

插入排序

算法

算法思想:每次将一个待排序的记录按其关键字大小插入到前面已排好序的子序列中,直到全部记录插入完成。

性能

  • 空间复杂度:O(1)
  • 时间复杂度:
    • 最好:原本就有序;O(n)
    • 最坏:原本为逆序;O(n2);
    • 平均:O(n2);
  • 稳定性:稳定;

代码



#include <iostream>
using namespace std;

void InsertSort(int a[],int n) {
    int i, j, temp;
    for(i = 1; i < n; i++) {
        if (a[i] < a[i - 1]) {
            temp = a[i];
            for (j = i - 1; j >= 0 && a[j] > temp; j--) {
                a[j + 1] = a[j];
            }
            a[j + 1] = temp;
        }
    }
}

void printfarray(int a[], int n) {
    for (int i = 0; i < n; i++) {
        cout << a[i] << " ";
    }
    cout << endl;
}

int main() {
    int a[8] = {38, 49, 65, 97, 76, 13, 27, 49};
    int n = 8;
    cout << "插入排序前的数组为: ";
    printfarray(a, n);
    cout << endl;

    InsertSort(a,n);
    cout << "插入排序后的数组为: ";
    printfarray(a, n);
    cout << endl;
}

冒泡排序

算法

  • 从后往前(或从前往后)两两比较相邻元素的值,若为逆序(即A[i-1]>A[i]),则交换它们,直到序列比较完。称这样过程为"一趟"冒泡排序。
  • 第一趟排序使关键字值最小的一个元素"冒"到最前面;
  • 每一趟排序都可以使一个元素移动到最终位置,已经确定最终位置的元素在之后的处理中无需再对比;
  • 若某一趟排序没有发生"交换",说明此时已经整体有序。

性能

  • 空间复杂度:O(1)
  • 时间复杂度:
    • 最好:原本就有序;O(n)
    • 最坏:原本为逆序;O(n2);
    • 平均:O(n2);
  • 稳定性:稳定;

代码

#include <iostream>
using namespace std;

void swap(int &a, int &b){
    int temp = a;
    a = b;
    b = temp;
}

void BubbleSort(int a[],int n) {
    for(int i = 0; i < n-1; i++) {
        bool flag = false; // 表示本趟冒泡是否发生交换的标志
        for (int j = n - 1; j > i; j--) {
            if (a[j-1] > a[j]) {
                swap(a[j-1],a[j]);
                flag = true;
            }
        }
        if (flag == false) {
            return;
        }
    }
}

void printfarray(int a[], int n) {
    for (int i = 0; i < n; i++) {
        cout << a[i] << " ";
    }
    cout << endl;
}

int main() {
    int a[8] = {38, 49, 65, 97, 76, 13, 27, 49};
    int n = 8;
    cout << "冒泡排序前的数组为: ";
    printfarray(a, n);
    cout << endl;

    BubbleSort(a,n);
    cout << "冒泡排序后的数组为: ";
    printfarray(a, n);
    cout << endl;
}

希尔排序

算法

  • 先将待排序表分割成若干形如L[i, i+d, i+2d, ... ,i + kd]的"特殊"子表,对各个子表分别进行直接插入排序。缩小增量d,重复上述过程,直到d=1为止。
  • 先追求表中元素部分有序,再逐渐逼近全局有序。

性能

  • 空间复杂度:O(1)
  • 时间复杂度:未知,但优于直接插入排序
  • 稳定性:不稳定;

代码




#include <iostream>
using namespace std;

void ShellSort(int a[],int n) {
    int i, j, d, temp;
    for (d = n / 2; d >= 1; d = d / 2) {
        for(i = d; i < n; i++) {
            if(a[i] < a[i-d]) {
                temp = a[i];
                for(j = i - d; j >= 0 && a[j] > temp; j-=d) {
                    a[j + d] = a[j];
                }
                a[j + d] = temp;
            }
        }
    }
}

void printfarray(int a[], int n) {
    for (int i = 0; i < n; i++) {
        cout << a[i] << " ";
    }
    cout << endl;
}

int main() {
    int a[11] = {38, 6, 9, 3, 49, 65, 97, 76, 13, 27, 49};
    int n = 11;
    cout << "希尔排序前的数组为: ";
    printfarray(a, n);
    cout << endl;

    ShellSort(a,n);
    cout << "希尔排序后的数组为: ";
    printfarray(a, n);
    cout << endl;
}

快速排序

算法

算法思想:在待排序表L[1 ... n]中任取一个元素pivot作为枢轴(或基准,通常取首元素),通过一趟排序将待排序表划分为独立的两部分L[1 ... k-1]和L[k+1 ... n],使得L[1 ... k-1]中的所有元素小于pivot,L[k+1 ... n]中的所有元素大于等于pivot,则pivot放在了其最终位置L(k) 上,这个过程称为一次"划分"。然后分别递归地对两个子表重复上述过程,直至每部分内只有一个元素或空为止,即所有元素放在了其最终位置上。

算法表现主要取决于递归深度,若每次"划分"越均匀,则递归深度越低。"划分"越不均匀,递归深度越深。

性能

  • 空间复杂度:
    • 最好:O(n)
    • 最坏:O(log(n))
  • 时间复杂度:
    • 最好:每次划分很均匀;O(n2)
    • 最坏:原本为正序或逆序;O(n log(n));
    • 平均:O(n log(n));
  • 稳定性:不稳定;

代码


#include <iostream>
using namespace std;

int Partition(int a[],int low, int high) {
    int pivot = a[low];
    while (low < high) {
        while(low < high && a[high] >= pivot) high--;
        a[low] = a[high];
        while(low < high && a[low] <= pivot) low++;
        a[high] = a[low];
    }
    a[low] = pivot;
    return low;
}

void QuickSort(int a[],int low, int high) {
    if (low < high) {
        int pivotpos = Partition(a,low,high); // 划分
        QuickSort(a, low, pivotpos-1); // 划分左子表
        QuickSort(a, pivotpos + 1, high); // 划分右子表
    }
}

void printfarray(int a[], int n) {
    for (int i = 0; i < n; i++) {
        cout << a[i] << " ";
    }
    cout << endl;
}

int main() {
    int a[11] = {38, 6, 9, 3, 49, 65, 97, 76, 13, 27, 49};
    int n = 11;
    cout << "快速排序前的数组为: ";
    printfarray(a, n);
    cout << endl;

    QuickSort(a,0,n-1);
    cout << "快速排序后的数组为: ";
    printfarray(a, n);
    cout << endl;
}

简单选择排序

算法

  • 每一趟在待排序元素中选取关键字最小的元素加入有序子序列
  • 必须进行总共 n - 1 趟处理;

性能

  • 空间复杂度:O(1)
  • 时间复杂度:O(n2)
  • 稳定性:不稳定;

代码

#include <iostream>
using namespace std;

void swap(int &a, int &b){
    int temp = a;
    a = b;
    b = temp;
}

void SelectSort(int a[],int n) {
   for (int i = 0; i < n-1; i++) {
       int min = i;
       for(int j = i + 1; j < n; j++) {
           if (a[j] < a[min])
                min = j;
       }
       if (min != i) {
           swap(a[i],a[min]);
       }
   }
}

void printfarray(int a[], int n) {
    for (int i = 0; i < n; i++) {
        cout << a[i] << " ";
    }
    cout << endl;
}

int main() {
    int a[11] = {38, 6, 9, 3, 49, 65, 97, 76, 13, 27, 49};
    int n = 11;
    cout << "选择排序前的数组为: ";
    printfarray(a, n);
    cout << endl;

    SelectSort(a,n);
    cout << "选择排序后的数组为: ";
    printfarray(a, n);
    cout << endl;
}
相关推荐
别NULL4 小时前
机试题——疯长的草
数据结构·c++·算法
ZSYP-S5 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
唐叔在学习6 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA6 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
武昌库里写JAVA9 小时前
浅谈怎样系统的准备前端面试
数据结构·vue.js·spring boot·算法·课程设计
S-X-S9 小时前
代码随想录刷题-数组
数据结构·算法
l138494274519 小时前
每日一题(4)
java·数据结构·算法
kyrie_sakura9 小时前
c++数据结构算法复习基础--13--基数算法
数据结构·c++·算法
XWXnb69 小时前
数据结构:顺序表
数据结构·算法
橘颂TA10 小时前
【C++】数据结构 顺序表的实现(详解)
开发语言·数据结构·c++·算法