排序算法学习

目录

一、排序算法的一些辅助函数

1、输出函数两个

2、两数交换函数

二、排序算法的分类

1、简单选择排序

2、冒泡排序

3、直接插入排序

4、希尔排序

三、总程序


一、排序算法的一些辅助函数

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');

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值