目录
一、排序算法的一些辅助函数
1、输出函数两个
//输出函数一(b站)
void print(int *arr)
{
int i;
for(i=0;i<maxsize;i++)
{
printf("%d ",arr[i]);
}
putchar('\n');
}
//输出函数二(大话)
void printD(int *a)
{
int i;
for(i=1;i<maxsize;i++)
{
printf("%d ",a[i]);
}
putchar('\n');
}
2、两数交换函数
//交换函数,作为辅助函数,用于数组中两数的交换
void swap(int *arr,int i,int j)//数组名,下标,下标
{
int temp;
if(!arr || i<0 || j<0)return;
if(i==j)return;
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
二、排序算法的分类
1、简单选择排序
打擂台的方式,多次打擂台,每次选一个擂主,剩余的作为挑战者上台比大小,最后确定每次打擂台的擂主,形成从小到大的排序或者从大到小的排序
代码:
void choice(int *arr)
{
int i,j;
if(!arr || maxsize<=1)return;
for(i=0;i<maxsize-1;i++)//每轮擂主的编号i,最后一个不用做擂主,没有挑战者了
{
for(j=i+1;j<maxsize;j++)//擂台战,挑战者j标号
{
if(arr[i]>arr[j])
{
swap(arr,i,j);
}
}
}
}
2、冒泡排序
每一轮冒泡都是将一个最值固定,同时对数据有一定的排序
下面的两个程序都可以运行,主要是对数组越界的问题处理不一样,数组的越界问题(j+1)要特别注意
void bubbling(int *arr)
{
int i,j;
if(!arr || maxsize<=1)return;
for(i=1;i<maxsize;i++)//需要冒泡maxsize-1轮,即1至maxsize
{
for(j=0;j<maxsize-i;j++)//后面的排好序了不用比了
{
if(arr[j]<arr[j+1])
swap(arr,j,j+1);
}
}
}
或者
void bubbling(int *arr)
{
int i,j;
if(!arr || maxsize<=1)return;
for(i=0;i<maxsize-1;i++)//需要冒泡maxsize-1轮,即1至maxsize
{
for(j=0;j<maxsize-i-1;j++)//后面的排好序了不用比了
{
if(arr[j]<arr[j+1])
swap(arr,j,j+1);
}
}
}
3、直接插入排序
分为两种,其实殊途同归,只是key的选择不一样
//插入排序(b站方法)
void inter(int *arr)
{
int i=0,j=0,key=0;
if(!arr || maxsize<=1)return;
for(i=1;i<maxsize;i++)//默认数组下标0的数是有序的
{
key=arr[i];//先保存无序要插入的数
for(j=i;j>=0;j--)//实则就是从后往前的打擂台排序
{
if(key<arr[j-1])swap(arr,j,j-1);
else break;
}
}
}
//插入排序(大话数据),先对数组处理,数组下标为0的元素不存放数据,用于哨兵位置
//思路与b站的方法雷同,但是用数组的头元素作为key
void Inter(int *a)
{
int i=0,j=0;
if(!a || maxsize<=1)return;
for(i=2;i<maxsize;i++)//默认数组下标为1的元素有序,无序要待插入的元素从2开始
{
if(a[i]<a[i-1])
{
a[0]=a[i];//保存
for(j=i-1;a[0]<a[j];j--)
{
a[j+1]=a[j];//后移
}
a[j+1]=a[0];
}
}
}
4、希尔排序
分为两种,其实殊途同归,只是key的选择不一样
//希尔排序(b站版本)
void Shellsort(int *arr)
{
int inc;//增量
int i,j;//i是无序要插入的,j是指针
int key;
for(inc=maxsize/2;inc>0;inc/=2)
{
for(i=inc;i<maxsize;i++)
{
key=arr[i];
for(j=i;(j-inc)>=0 && key<arr[j-inc];j=j-inc)//j-inc>=0是对j=j-inc的约束,防止数组在j=j-inc后使得arr[j-inc]越位,就是不能少于0
{
arr[j]=arr[j-inc];//移位的功能
}
arr[j]=key;
}
}
}
//希尔排序(大话版本)
void Shell_sort(int *a)
{
int i,j;
int inc;
for(inc=maxsize/2;inc>0;inc=inc/2)
{
for(i=inc+1;i<maxsize;i++)
{
a[0]=a[i];
for(j=i;j>=inc && a[0]<a[j-inc];j-=inc)
{
a[j]=a[j-inc];
}
a[j]=a[0];
}
}
}
三、总程序
#include<stdio.h>
#include<stdlib.h>
#define maxsize 9
//输出函数一(b站)
void print(int *arr)
{
int i;
for(i=0;i<maxsize;i++)
{
printf("%d ",arr[i]);
}
putchar('\n');
}
//输出函数二(大话)
void printD(int *a)
{
int i;
for(i=1;i<maxsize;i++)
{
printf("%d ",a[i]);
}
putchar('\n');
}
//交换函数,作为辅助函数,用于数组中两数的交换
void swap(int *arr,int i,int j)//数组名,下标,下标
{
int temp;
if(!arr || i<0 || j<0)return;
if(i==j)return;
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
//选择排序
void choice(int *arr)
{
int i,j;
if(!arr || maxsize<=1)return;
for(i=0;i<maxsize-1;i++)//从数组的0到下标的maxsize-1
{
for(j=i+1;j<maxsize;j++)//擂台战,选一个擂主i,挑战者j多次比对
{
if(arr[i]>arr[j])
{
swap(arr,i,j);
}
}
}
}
//冒泡排序,从大到小
void bubbling(int *arr)
{
int i,j;
if(!arr || maxsize<=1)return;
for(i=1;i<maxsize;i++)//需要冒泡maxsize-1轮,即1至maxsize
{
for(j=0;j<maxsize-i;j++)
{
if(arr[j]<arr[j+1])
swap(arr,j,j+1);
}
}
}
//插入排序(b站方法)
void inter(int *arr)
{
int i=0,j=0,key=0;
if(!arr || maxsize<=1)return;
for(i=1;i<maxsize;i++)//默认数组下标0的数是有序的
{
key=arr[i];//先保存无序要插入的数
/*for(j=i;j>=0;j--)//方法一
{
if(key<arr[j-1])swap(arr,j,j-1);
else break;
}*/
for(j=i;(j>=0 && key<arr[j-1]);j--)//方法二,要插入的数在前一个有序数的左边,那么就
{
arr[j]=arr[j-1];//将前一个有序数后移一位,循环后空出的位置就是真确的位置
}
arr[j]=key;//放入正确的位置
}
}
//插入排序(大话数据),先对数组处理,数组下标为0的元素不存放数据,用于哨兵位置
//思路与b站的方法雷同,但是用数组的头元素作为key
void Inter(int *a)
{
int i=0,j=0;
if(!a || maxsize<=1)return;
for(i=2;i<maxsize;i++)//默认数组下标为1的元素有序,无序要待插入的元素从2开始
{
if(a[i]<a[i-1])
{
a[0]=a[i];//保存
for(j=i-1;a[0]<a[j];j--)
{
a[j+1]=a[j];//后移
}
a[j+1]=a[0];
}
}
}
//希尔排序(b站版本)
void Shellsort(int *arr)
{
int inc;//增量
int i,j;//i是无序要插入的,j是指针
int key;
for(inc=maxsize/2;inc>0;inc/=2)
{
for(i=inc;i<maxsize;i++)
{
key=arr[i];
for(j=i;(j-inc)>=0 && key<arr[j-inc];j=j-inc)//j-inc>=0是对j=j-inc的约束,防止数组在j=j-inc后使得arr[j-inc]越位,就是不能少于0
{
arr[j]=arr[j-inc];//移位的功能
}
arr[j]=key;
}
}
}
//希尔排序(大话版本)
void Shell_sort(int *a)
{
int i,j;
int inc;
for(inc=maxsize/2;inc>0;inc=inc/2)
{
for(i=inc+1;i<maxsize;i++)
{
a[0]=a[i];
for(j=i;j>=inc && a[0]<a[j-inc];j-=inc)
{
a[j]=a[j-inc];
}
a[j]=a[0];
}
}
}
//主函数
void main()
{
int i;
//int arr[maxsize]={0};
int a[maxsize]={0,3,1,2,5,88,66,12,45};//大话使用*********************************************************************
for(i=0;i<maxsize;i++)//取随机数
{
arr[i]=rand()%100;
}
printf("排序前:\n");
print(arr);//调用输出函数
putchar('\n');
choice(arr);//调用选择排序函数
bubbling(arr);//调用冒泡排序
inter(arr);//调用插入排序(b站方法)
Shellsort(arr);//调用希尔排序(b站方法)
printf("排序后:\n");
print(arr);//调用输出函数
putchar('\n');
//*************************************************************************************************************
//因为大话的方法是先对数组做一些处理,所以要另外的方式
//printf("排序前:\n");
//printD(a);//调用输出函数
//putchar('\n');
//Inter(a);//调用插入排序(大话数据)
//Shell_sort(a);//调用希尔排序(大话数据)
//printf("排序后:\n");
//printD(a);//调用输出函数
//putchar('\n');
}