基础数据结构和算法6:简单排序算法
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. | 算法 | Algorithm | Time Complexity | Space Complexity | Stable |
---|---|---|---|---|---|
1 | 冒泡排序 | Bubble Sort | O(n^2) | O(1) | Yes |
2 | 插入排序 | Insertion Sort | O(n^2) | O(1) | Yes |
3 | 选择排序 | Selection Sort | O(n^2) | O(1) | No |