本质上是对一个数(例如5400)的每一位都进行排序
①所需要的n个队列,n是所有数字的范围
123,456,789,158
这四组数包含了9个数字,所以需要9个队列
②然后按升序或者降序依次入队,然后出队
即排列了一次,最高位是m位,则排m次。
核心思想是找到无序集合中的最小值的下标,然后与无序集合中的第一个位置进行一次交换。
因为没找到一次都要进行一次交换 ,所以只需要找n-1次即可。
①外层循环是枚举n-1次
②内层循环是[i,n),寻找最小值下标
③交换
建立一个flag 一旦一轮比较都没有进行交换 说明 已经有序
这个操作影响最优时间复杂度
①和选择排序一样外层只要n-1次
②[0,j-i) 飘上去 每i轮后面少i个元素
有序和无序的部分的思想比其他的排序更为直接。
一开始就是认为1号元素,因为只有一个元素,所以这1个元素是有序的,然后把后面的无序部分的元素一个一个的插入到有序的部分,这里的插入过程是从后面开始不断的覆盖的过程,直到找到位置,然后将a[0]插入。
简单来说就是有条件的覆盖,不是已知位置的覆盖
,边寻找位置 边覆盖。
①因为1视为有序部分,所以外层从2开始 [2,n)
②j=i为上界 当 目标元素a[0] < or > a[j-1] 时覆盖(因为i是目标元素,所以j也是目标元素,所以从j-1开始比较)
③当内层循环结束时会走到前一个位置,所以j+1赋值为a[0]
与直接插入有着大概一半的不同。
这个的覆盖是已知的,因为使用了二分法找到了需要插入的位置,然后才开始进行覆盖操作。
①第一个循环依旧是 从2开始 [2,N)
②二分法寻找插入位置(因为每一个元素都要寻找位置所以放在最外层循环里面)
我们所需要插入的地方是有序表,
所以 l=1 h=i-1
有序表在左边 low理所当然为0,h则是上界,上界则是i-1,因为i是目标元素的下标。
此外二分法的其他部分不需要改变
结束的时候可以使用h+1作为插入点 因为h在结束的时候【这一段不是很好解释 自己体会把】
③h+1当作是插入点 所以开始覆盖操作 然后插入完事
「我感觉更适合叫做pivot中心(中间枢纽)排序」 【 传的是low 和hight 存在两个数就是 low
②寻找pivot ,【默认key为low下标】
先保存key
找hight-- 比pivot小 放置low下标
找low 同理 放置hight下标
此时low空了,最后把pivot放置low位置
返回pivot位置 也就是 low
开始时刻:
快排:递归开始时------就开始一个一个的找pivot,再分区间,从第一个元素就开始
归并:回溯时才开始
设计方式:
先开辟一个相同的集合,复制一份为t,再把t分为两个部分, 然后按照 合并规则 插入 原集合。
合并规则:
设置三个变量, i.j.k, i控制前半部分,j控制后半部分,k控制将要插入的集合
然后 是跟合并有序表的操作类似。
(写变量的下表的时候最好不用-(减), 容易造成负数)
注意:(写游标移动的时候一定要记得加上 原游标的范围条件判断)
#include
#include
using namespace std;
/*
顺序查找
二分查找
基数排序
选择排序
冒泡
直接插入
二分插入
希尔排序
堆排序
快排
2路归并
*/
int a[11] = { 0,14,9,6,13,21,10,16,17,2,12 };
//int a[5] = {0,1,5,6,8};
//顺序查找
//return 0 查找失败
int ss(int key, int length) {
a[0] = key;
int i;
for (i = length; key != a[i]; i--);
return i;
}
//二分查找
int b_s(int key, int length) {
int l = 1, m, h = length;
while (l <= h) {
m = (l + h) / 2;
if (a[m] == key) {
return m;
}
else if (key < a[m]) {
h = m - 1;
}
else if (key > a[m]) {
l = m + 1;
}
}
return 0;
}
//基数 可分 数字范围 n 开辟n个队列 数字的位数m 依次顺序入队出队m次
//*******************************************
//希尔排序
void shell(int length) {
for (int dk = length / 2; dk >= 1; dk = dk / 2)
{
for (int i = dk + 1; i > 0; i++)
{
if (a[i] < a[i - dk])
{
a[0] = a[i];
int j;
for (j = i - dk; j > 0 && a[0] < a[j]; j -= dk)
{
a[j + dk] = a[j];
}
a[j + dk] = a[0];
}
}
}
}
void swap(int* a, int* b) {
int* t = a;
a = b;
b = t;
}
//调整堆
void adjust_heap(int key, int length) {
a[0] = a[key];
for (int i = key * 2; i <= length; i *= 2)
{
if (i < length && a[i] < a[i + 1])
{
i++;
}
if (a[0] >= a[i])
{
break;
}
else {
a[key] = a[i];
key = i;
}
}
a[key] = a[0];
}
//建堆
void build_heap(int length) {
for (int i = length / 2; i > 0; i--)
{
adjust_heap(i, length);
}
}
//堆排序
void heap_sort(int length) {
build_heap(length);
for (int i = length; i > 0; i--)
{
swap(a[1], a[i]);
adjust_heap(1, i - 1);
}
}
//选择排序
void select_sort(int length) {
for (int i = 1; i < length; i++) {
a[0] = a[i];
int minarr = i;
for (int j = i; j <= length; j++)
{
if (a[j] < a[0])
{
minarr = j;
a[0] = a[j];
}
}
swap(a[i], a[minarr]);
}
}
//冒泡排序
void bubble_sort(int length) {
for (int i = 1; i < length; i++)
{
bool flag = 1;
for (int j = 1; j <= length - i; j++)
{
if (a[j] < a[j + 1])
{
swap(a[j], a[j + 1]);
flag = 0;
}
}
if (flag) break;
}
}
//pivot
int portion(int l, int h) {
a[0] = a[l];
while (l < h)
{
while (l < h && a[h] >= a[0]) h--;
a[l] = a[h];
while (l < h && a[l] <= a[0]) l++;
a[h] = a[l];
}
a[h] = a[0];
return h;
}
//快排
void quick_sort(int l, int length) {
if (l < length) {
int pivot = portion(l, length);
quick_sort(l, pivot - 1);
quick_sort(pivot + 1, length);
}
}
//二分插入排序
void b_insert_sort(int length)
{
//1位置认为有序
for (int i = 2; i <= length; i++)
{
a[0] = a[i];
//对于每一个都使用二分法找到位置
int l = 1, m, h = i - 1;
while (l <= h)
{
m = (l + h) / 2;
if (a[0] < a[m]) {
h = m - 1;
}
else {
l = m + 1;
}
}
//位置为h+1 覆盖
for (int j = i; j > h + 1; j--)
{
a[j] = a[j - 1];
}
a[h + 1] = a[0];
}
}
//归并操作
void my_merge(int l, int h, int length) {
int* b = (int*)malloc(sizeof(int) * length);
for (int i = 1; i <= length; i++)
{
b[i] = a[i];
}
int m = (l + h) / 2;
int i, j, k;
for (i = l, j = m + 1, k = l; i <= m && j <= h; k++)
{
if (b[i] < b[j]) {
a[k] = b[i++];
}
else {
a[k] = b[j++];
}
}
while (i <= m)
{
a[k++] = b[i++];
}
while (j <= h)
{
a[k] = b[j++];
}
}
//归并排序
void merge_sort(int l, int h, int length) {
if (l < h) {
int m = (l + h) / 2;
merge_sort(l, m, length);
merge_sort(m + 1, h, length);
my_merge(l, h, length);
}
}
//int a[5] = { 10,6,2,8,1 }
int main()
{
bubble_sort(10);
for (int i = 1; i < 11; i++)
{
cout << a[i] << " ";
}
cout << endl;
return 0;
}
求点赞
原创不易,点赞容易。
您的鼓励就是我的最大动力!!!。
本篇博客到此结束,谢谢大家观看。