排序算法之选择、插入、希尔、基数、箱排序

排序算法

时间复杂度:单位数据 消耗的时间比例 O(n)
空间复杂度:单位数据 消耗的固定空间 和临时空间
稳定性:数据变化是否导致 时间复杂度变化

选择排序

选择排序法是在要排序的一组数中,选出最小(或最大)的一个数与第一个位置的数交换;在剩下的数当中找最小的与第二个位置的数交换,即顺序放在已排好序的数列的最后,如此循环,直到全部数据元素排完为止。

在这里插入图片描述

代码

#include <iostream>
using namespace std;

int main()
{
	int a[10] = { 3,21,5,32,65,43,7,11,89,4 };
	int temp = 0;
	for (int i = 0; i < 9; i++)
	{
		temp = i;
		//从下标为1开始,找最小的往前排
		for (int j = i + 1; j < 10; j++)
		{
			//将小的值赋值给temp
			temp =(a[temp] > a[j] ? j : temp);
		}
		if(a[temp]<a[i])
		{
			int x = a[temp];
			a[temp] = a[i];
			a[i] = x;
		}
	}
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	while (1);
	return 0;
}

插入排序

插入排序是指在待排序的元素中,假设前面n-1(其中n>=2)个数已经是排好顺序的,现将第n个数插到前面已经排好的序列中,然后找到合适自己的位置,使得插入第n个数的这个序列也是排好顺序的。按照此法对所有元素进行插入,直到整个序列排为有序的过程,称为插入排序

在这里插入图片描述

代码

#include <iostream>
using namespace std;

int main()
{
	int a[10] = { 3,21,5,32,65,43,7,11,89,4 };
	int j = 0;
	int temp = 0;
	for (int i = 1; i < 10; i++)
	{
		temp = a[i];
		j = i - 1;
		while (j >= 0 && temp < a[j])
		{
			a[j + 1] = a[j];
			j--;
		}
		a[j + 1] = temp;
	}
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	while (1);
	return 0;
}

希尔排序

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

1、插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
2、但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。

基本思想

#include<iostream>
#include <string>
using namespace std;

int main()
{
	int a[10] = { 34,4,56,2,75,43,5,7,34,9 };
	int len = sizeof(a) / sizeof(int);
	int step = 0;
	int temp;
	int j = 0;
	step =len >> 1;
	//以步长分类,对半
	while (step)
	{
		for (int i = 1; i < 10; )
		{
			temp = a[i];
			j = i - 1;
			while (j >= 0 && temp < a[j])
			{
				a[j + 1] = a[j];
				j--;
			}
			a[j + 1] = temp;
			i = i + step;
		}
		step >>= 1;
	}
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	system("pause");
	return 0;
}

基数排序

将对应的数组大小变为新数组的序号对应存入。
在这里插入图片描述

#include <stdio.h>
#include <windows.h>
int main()
{
	int a[10] = { 3,21,5,32,65,43,7,11,89,4 };
	int Max = 89;
	int k = 0;
	int* temp = new int[Max+1];
	for (int i = 0; i <=Max; i++)
	{
		temp[i] = -1;
	}
	for (int i = 0; i < 10; i++)
	{
		temp[a[i]] = a[i];
	}
	for (int i = 0; i <=Max; i++)
	{
		if (temp[i] != -1)
		{
			a[k++] = temp[i];
		}
	}
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	system("pause");
	return 0;
}

箱排序(也称桶排序)

以位数来进行排序

以个位分
在这里插入图片描述排完后
在这里插入图片描述

以十位分

在这里插入图片描述排完后
在这里插入图片描述

以百位分
在这里插入图片描述排完后在这里插入图片描述

数据结构设计:链表可以采用很多种方式实现,通常的方法是动态申请内存建立结点,但是针对这个算法,桶里面的链表结果每次扫描后都不同,就有很多链表的分离和重建。如果使用动态分配内存,则由于指针的使用,安全性低。所以,笔者设计时使用了数组来模拟链表(当然牺牲了部分的空间,但是操作却是简单了很多,稳定性也大大提高了)。共十个桶,所以建立一个二维数组,行向量的下标0—9代表了10个桶,每个行形成的一维数组则是桶的空间。

#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <time.h>
void srandN(int* a,int num,int max)
{
	int x = 0;
	for (int i = 0; i < num;i++ )
	{
		a[i] = rand() % max;
	}
}
void xiangz(int*& a,int size,int Max)
{
	int k = 0;
	int index = 0;
	//按位数分类
	for (int i = 1; i < Max; i *= 10)
	{
		//开辟十个桶,并初始化为-1(保证不会出出现的)
		int* temp = new int[10 * size];
		for (int j = 0; j < 10 * size; j++)
		{
			temp[j] = -1;
		}
		//按为分配
		for (int j = 0; j < size; j++)
		{
			index = a[j] / i % 10;
			*(temp + j +  10 *  index) = a[j];
		}
		k = 0;
		for (int j = 0; j < size*10; j++)
		{
			if (temp[j] != -1)
			{
				a[k] = temp[j];
				k++;
			}
		}
		delete[]temp;
	}
}
int main()
{
	//个数
	int num = 10;
	//最大值
	int max = 1000;
	int* a = new int[num];
	srand((unsigned)time(NULL));
	srandN(a, num,max);
	xiangz(a, 10, 1000);
	for (int i = 0; i < num; i++)
	{
		printf("%d ",a[i]);
	}
	system("pause");
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值