基础数据结构和算法6:简单排序算法

本文详细介绍了三种基础排序算法:冒泡排序、选择排序和插入排序。包括每种排序的步骤、参考代码、时间复杂度和空间复杂度分析。所有排序算法的时间复杂度均为O(n^2),空间复杂度为O(1)。对于冒泡排序和选择排序,还提出了优化方案。最后,简要讨论了排序的稳定性概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、简单练习

1.1 测试框架

简单的数组抓取,打印。

#include <stdio.h>
#include <algorithm>

void print_array(int arr[],int n){
    for(int i=0;i<n;++i){
        printf("%d ",arr[i]);
    }
    printf("\n");
}
int* scanf_array(int arr[],int n){
    for(int i=0;i<n;++i){
        scanf("%d",&arr[i]);
    }
    return arr;
}
void swap(int* a,int* b){
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main(){
    int n;
    scanf("%d",&n);
    int arr[n];
    scanf_array(arr,n);
    sort(arr,arr+n);
    print_array(arr,n);
}

1.2 随即生成数组

数组随即生成,判断是否是有序数列,1是有序,0是无序。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
int *CreateRandArry(int n){
    int *arr = malloc(sizeof(int)*n);
    srand(time(NULL));
    for(int i=0;i<n;i++){
        arr[i] = rand()%100+1;
    }
    return arr;
}

//打印函数
void PrintArry(int *arr,int n){
    for(int i=0;i<n;i++){
        printf("%d ",arr[i]);
    }
    printf("\n");
}

bool IsOrder(int *arr,int n){
    for(int i=1;i<n;i++){
        if(arr[i] >= arr[i-1]){
	    continue;
	}else{
	    return false;
	}
    }
    return true;
}

int main(){
    int n;
    scanf("%d",&n);
    int *arr = CreateRandArry(n);
    PrintArry(arr,n);
    printf("Order Arry:%d\n",IsOrder(arr,n));

}

1.3 c++内置函数排序

#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
void print_array(int arr[],int n){
    for(int i=0;i<n;++i){
        printf("%d ",arr[i]);
    }
    printf("\n");
}
int* scanf_array(int arr[],int n){
    for(int i=0;i<n;++i){
        scanf("%d",&arr[i]);
    }
    return arr;
}
void swap(int* a,int* b){
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main(){
    int n;
    scanf("%d",&n);
    int arr[n];
    scanf_array(arr,n);
    sort(arr,arr+n);
    print_array(arr,n);
}

2、冒泡排序

2.1 步骤

(1)首先实现一趟冒泡

void bubble(int arr[],int n);

(2)再实现多趟冒泡

void bubble_sort(int arr[],int n);

2.2 参考代码

(1) bubble.c

#include "util.h"
bool bubble(int *arr, int n){
    bool sorted = true;
    for(int i=0;i<n-1;i++){
        if(arr[i]>arr[i+1]){
	    SWAP(arr[i],arr[i+1]);//这里是把小的数字一直往前放
	    sorted = false;
	}
    }
    return sorted;
}


void bubble_sort(int *arr,int n){
    for(int i=0;i<n-1;i++){
        if(bubble(arr,n-i))  break;
    }
}
int main(){
    int n;
    scanf("%d",&n);
    int *arr = CreateRandArry(n);
    PrintArry(arr,n);
    printf("Order Arry:%d\n",IsOrder(arr,n));
    
    bubble_sort(arr,n);
   // selection_sort(arr,n);
    PrintArry(arr,n);
    printf("Order Arry:%d\n",IsOrder(arr,n));
    free(arr);
    arr=NULL;
}

(2) util.c

#include "util.h"


int find_max(int *arr,int n){
    int maxVal = arr[0];
    int maxIndex = 0;
    for(int i=1;i<n;i++){
        if(arr[i] > maxVal){
	    maxVal = arr[i];
	    maxIndex = i;
	}
    }
    return maxIndex;
}

int selection_sort(int *arr,int n){
    for(int i=0;i<n-1;i++){
        int maxIndex = find_max(arr,n-i);
	SWAP(arr[maxIndex],arr[n-i-1]);
    }

}

int *CreateRandArry(int n){
    int *arr = malloc(sizeof(int)*n);
    srand(time(NULL));
    for(int i=0;i<n;i++){
        arr[i] = rand()%100+1;
    }
    return arr;
}

//打印函数
void PrintArry(int *arr,int n){
    for(int i=0;i<n;i++){
        printf("%d ",arr[i]);
    }
    printf("\n");
}

bool IsOrder(int *arr,int n){
    for(int i=0;i<n-1;i++){
        if(arr[i] > arr[i+1]){
	    return false;
	}
    }
    return true;
}

(3) util.h

#pragma once

#include <stdio.h>
#include <time.h>
#include <stdbool.h>
#include <stdlib.h>

#define SWAP(a,b){\
	int t = a;\
	a = b;\
	b = t;\
}
int *CreateRandArry(int n);

void PrintArry(int *arr,int n);
bool IsOrder(int *arr,int n);
/*bool bubble(int *arr, int n);
void bubble_sort(int *arr,int n);*/
int find_max(int *arr,int n);
int selection_sort(int *arr,int n);

2.3 时间复杂度

一共比较n-1+n-2+…+2次,即\sum_{i=2}^{n-1}i = \frac{(2+n-1)\times(n-2)}{2} = \frac{n^2-n-2}{2} = O(n^2)

2.4 空间复杂度

随着n的增长,排序不需要增加额外空间,空间复杂度为O(1)。

3、选择排序

3.1 步骤

(1)最大数字的下标

首先实现一趟,找出最大数字的下标

int find_max_index(int arr[],int n);

(2)交换

实现多趟将最大数字与最后数字交换

int selection_sort(int arr[],int n);

3.2 参考代码

(1)selection.c

#include "util.h"
int find_max(int *arr,int n){
    int maxVal = arr[0];
    int maxIndex = 0;
    for(int i=1;i<n;i++){
        if(arr[i] > maxVal){
	    maxVal = arr[i];
	    maxIndex = i;
	}
    }
    return maxIndex;
}

int selection_sort(int *arr,int n){
    for(int i=0;i<n-1;i++){
        int maxIndex = find_max(arr,n-i);
	SWAP(arr[maxIndex],arr[n-i-1]);
    }

}
int main(){
    int n;
    scanf("%d",&n);
    int *arr = CreateRandArry(n);
    PrintArry(arr,n);
    printf("Order Arry:%d\n",IsOrder(arr,n));
    
    bubble_sort(arr,n);
   // selection_sort(arr,n);
    PrintArry(arr,n);
    printf("Order Arry:%d\n",IsOrder(arr,n));
    free(arr);
    arr=NULL;
}

(2)util.c

#include "util.h"

bool bubble(int *arr, int n){
    bool sorted = true;
    for(int i=0;i<n-1;i++){
        if(arr[i]>arr[i+1]){
	    SWAP(arr[i],arr[i+1]);
	    sorted = false;
	}
    }
    return sorted;
}


void bubble_sort(int *arr,int n){
    for(int i=0;i<n-1;i++){
        if(bubble(arr,n-i))  break;
    }
}


int *CreateRandArry(int n){
    int *arr = malloc(sizeof(int)*n);
    srand(time(NULL));
    for(int i=0;i<n;i++){
        arr[i] = rand()%100+1;
    }
    return arr;
}

//打印函数
void PrintArry(int *arr,int n){
    for(int i=0;i<n;i++){
        printf("%d ",arr[i]);
    }
    printf("\n");
}

bool IsOrder(int *arr,int n){
    for(int i=0;i<n-1;i++){
        if(arr[i] > arr[i+1]){
	    return false;
	}
    }
    return true;
}

(3)util.h

#pragma once

#include <stdio.h>
#include <time.h>
#include <stdbool.h>
#include <stdlib.h>

#define SWAP(a,b){\
	int t = a;\
	a = b;\
	b = t;\
}
int *CreateRandArry(int n);

void PrintArry(int *arr,int n);
bool IsOrder(int *arr,int n);
bool bubble(int *arr, int n);
void bubble_sort(int *arr,int n);
/*int find_max(int *arr,int n);
int selection_sort(int *arr,int n);*/

3.3 时间复杂度

一共比较n-1+n-2+…+2次,即\sum_{i=2}^{n-1}i = \frac{(2+n-1)\times(n-2)}{2} = \frac{n^2-n-2}{2} = O(n^2)

3.4 空间复杂度

随着n的增长,排序不需要增加额外空间,空间复杂度为O(1)。

3.5 优化

同时选择最大值和最小值

4、插入排序

4.1 步骤

(1)实现插入一个数字

void insert(int arr[],int n);

(2)实现插入多个数字

void insertion_sort(int arr[],int n);

4.2 参考代码

#include <stdio.h>
#include <string.h>
void Print_arry(int *arr ,int n){
    for(int i=0;i<n;i++){
        printf("%d ",arr[i]);
    }
}

void insert1(int *arr,int n){
    int t = arr[n-1];
    int i;
    for(i=0;i<n-1;i++){
        if(t < arr[i]){
	    break;
	}
    }
    //直接拷贝内存
    memcpy(arr+i+1,arr+i,sizeof(int)*(n-i-1));
    
    //用前面的覆盖后面的数字
/*    for(int j=n-1;i>i;j--){
        arr[j] = arr[j-1];
    }
*/

    arr[i] = t;
    
}
int main(){
    int arr[] = {1,2,3,4,5,8,9,10,11,6};
    insert1(arr,10);
    Print_arry(arr,10);
}

4.3 时间复杂度

一共比较n-1+n-2+…+2次,即\sum_{i=2}^{n-1}i = \frac{(2+n-1)\times(n-2)}{2} = \frac{n^2-n-2}{2} = O(n^2)

4.4 空间复杂度

随着n的增长,排序不需要增加额外空间,空间复杂度为O(1)。

4.5 优化

用移动代替交换

5、小结

排序的稳定性
在待排序的序列中,存在多个相同的关键字记录,经过排序这些记录相对位置保持不变,则这种排序称为稳定的,否则称为不稳定的。

No.算法AlgorithmTime ComplexitySpace ComplexityStable
1冒泡排序Bubble SortO(n^2)O(1)Yes
2插入排序Insertion SortO(n^2)O(1)Yes
3选择排序Selection SortO(n^2)O(1)No
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值