数据结构7 排序

0 复杂度总结

稳定:排序后相同关键字的相对位置不变
不稳:快些选堆
快 快速
些 希尔
选 简单选择
堆 堆排序

注意:
对于简单选择排序有两种版本:1交换板、2插入板
交换版 就是不稳的
插入版 就是稳定的(简单想想即知)

以下排序均默认升序

1 直接插入

思路:将每个元素插入已排好序的部分(前半部分)
有 for 和 while 两种形式,本质一样
代码第三行 cmp 控制升序 或降序

#include<bits/stdc++.h> 
#define num 100
#define cmp <
using namespace std;

typedef struct
{
	int data[num];
	int length;
}sqlist;

void init(sqlist &a)
{
	a.length = 0;
	cout << "初始化完成!" << endl << endl;
}

void creat(sqlist &a)
{
	int length = rand()%num;
	cout << "length = " << length << endl;
	int i;
	
	for(i = 0; i < length; i++)
	{
		a.data[i]= rand()%num;
	}
	a.length = length;
	cout << "创建完成" << endl << endl;
}

void print(sqlist a)
{
	int length = a.length;
	int i;
	cout << "输出:" << endl;
	if(length != 0) 
	{
		for(i = 0; i < length; i++)
		{ 
			printf("%-3d", a.data[i]); 
			if((i + 1)%20 == 0) 
				cout << endl;
		} 
		cout << endl << endl; 
	}
	else
		cout << "为空!" << endl << endl;
}

void insertSort(sqlist &a)
{
	int i, j, temp;
	cout << "直接插入排序(for):" << endl;
	for(i = 1; i < a.length; i++)
	{
		temp = a.data[i];
		for(j = i-1; j >= 0; j--)
		{
			if(temp cmp a.data[j])
				a.data[j + 1] = a.data[j];
			else
				break;
		}
		a.data[j + 1] = temp;
	}
	cout << "完成!" << endl << endl;
}

void insertSort2(sqlist &a)
{
	int i, j, temp;
	cout << "直接插入排序(while):" << endl;
	for(i = 1; i < a.length; i++)
	{
		temp = a.data[i];
		j = i - 1;
		while(j >= 0 && temp cmp a.data[j])
		{
			a.data[j + 1] = a.data[j];
			j--;
		}
		a.data[j + 1] = temp;
	}
	cout << "完成!" << endl << endl;
}

int main()
{
	sqlist a;
	srand(time(NULL));
	
	init(a);
	print(a);
	
	creat(a);
	print(a);
	insertSort(a);
	print(a);
	
	creat(a);
	print(a);
	insertSort2(a);
	print(a);
	
	return 0;
}

2 折半插入

思路
序列分为两部分,有序部分在前,无序部分在后,对于无序部分某元素 在 有序部分总以折半查找的方式找到对应位置,然后插入

#include<bits/stdc++.h> 
#define num 100
#define cmp <=   // >= 或 <= 保证排序稳定 
using namespace std;

typedef struct
{
	int data[num];
	int length;
}sqlist;

void init(sqlist &a)
{
	a.length = 0;
	cout << "初始化完成!" << endl << endl;
}

void creat(sqlist &a)
{
	int length = rand()%num;
	cout << "length = " << length << endl;
	int i;
	
	for(i = 0; i < length; i++)
	{
		a.data[i]= rand()%num;
	}
	a.length = length;
	cout << "创建完成" << endl << endl;
}

void print(sqlist a)
{
	int length = a.length;
	int i;
	cout << "输出:" << endl;
	if(length != 0) 
	{
		for(i = 0; i < length; i++)
		{ 
			printf("%-3d", a.data[i]); 
			if((i + 1)%20 == 0) 
				cout << endl;
		} 
		cout << endl << endl; 
	}
	else
		cout << "为空!" << endl << endl;
}

int search(sqlist a, int low, int high, int temp)
{
	int mid;
	while(low <= high)
	{
		mid = (low + high)/2;
		if(a.data[mid] cmp temp) 
			low = mid + 1;
		else
			high = mid - 1;
	}
	return low; 
}

void ensqlist(sqlist &a, int p, int high, int temp)
{
	int i;
	for(i = high; i >= p; i--)
		a.data[i+1] = a.data[i];
	a.data[p] = temp;
}

void BinsertSort(sqlist &a)
{
	int i, j, p, temp;
	cout << "折半插入排序:" << endl;
	for(i = 1; i < a.length; i++)
	{
		temp = a.data[i];
		p = search(a, 0, i - 1, temp);
		ensqlist(a, p, i-1, temp);
	}
	cout << "完成!" << endl << endl;
}

int main()
{
	sqlist a;
	srand(time(NULL));
	
	init(a);
	print(a);
	
	creat(a);
	print(a);
	BinsertSort(a);
	print(a);
	
	return 0;
}

3 冒泡插入

思路
升序:两两交换,大数会浮到最右边,依次进行

#include<bits/stdc++.h> 
#define num 100
#define cmp >   // > 或 < 保证排序稳定 
using namespace std;

typedef struct
{
	int data[num];
	int length;
}sqlist;

void init(sqlist &a)
{
	a.length = 0;
	cout << "初始化完成!" << endl << endl;
}

void creat(sqlist &a)
{
	int length = rand()%num;
	cout << "length = " << length << endl;
	int i;
	
	for(i = 0; i < length; i++)
	{
		a.data[i]= rand()%num;
	}
	a.length = length;
	cout << "创建完成" << endl << endl;
}

void print(sqlist a)
{
	int length = a.length;
	int i;
	cout << "输出:" << endl;
	if(length != 0) 
	{
		for(i = 0; i < length; i++)
		{ 
			printf("%-3d", a.data[i]); 
			if((i + 1)%20 == 0) 
				cout << endl;
		} 
		cout << endl << endl; 
	}
	else
		cout << "为空!" << endl << endl;
}

void exchange(int &a, int &b)
{
	int c;
	c = a;a = b;b = c;
}

void bSort(sqlist &a)
{
	int i, j, temp, flag;
	cout << "冒泡排序:" << endl;
	for(i = a.length-1; i > 0; i--)
	{
		flag = 0;
		for(j = 0; j < i; j++) 
		{
			if(a.data[j] cmp a.data[j+1])
			{
				exchange(a.data[j], a.data[j+1]);
				flag = 1;
			}
		}
		if(flag == 0)
			break;
	}
	cout << "完成!" << endl << endl;
}

int main()
{
	sqlist a;
	srand(time(NULL));
	
	init(a);
	print(a);
	
	creat(a);
	print(a);
	bSort(a);
	print(a);
	
	return 0;
}

4 快速排序

其中cmp1 和 cmp2控制升序 和 降序

其中很重要的操作可以写成一个划分子函数 partition()

思路(升序):
以第 i=1个元素为参考点a,t=a值,从后面 j=high 向前(j- -)查看,若后面一元素 b 比 t 小,则 b 赋值给 i 位置元素,i++,
从 i位置元素向后(i++)查看,若比 t 大,则i位置值赋值给 j 位置值,j- -
循环,直到 i < j 不成立为止
但没结束!
把 t 值赋值给现在的i位置的元素
并将low - (i-1) 和 (i + 1) - high 这两部分再次递归快速排序一下
end

#include<bits/stdc++.h> 
#define num 100
#define cmp1 <=   // <= 或 >= 保证排序稳定 
#define cmp2 <   // < 或 > 保证排序稳定 
//其中 cmp1,不带等号,会影响排序稳定性,但不影响升序或降序效果 
//cmp1 和 cmp2 的组合只有{<=, <}、{>=, >}
using namespace std;

typedef struct
{
	int data[num];
	int length;
}sqlist;

void init(sqlist &a)
{
	a.length = 0;
	cout << "初始化完成!" << endl << endl;
}

void creat(sqlist &a)
{
	int length = rand()%num;
	cout << "length = " << length << endl;
	int i;
	
	for(i = 0; i < length; i++)
	{
		a.data[i]= rand()%num;
	}
	a.length = length;
	cout << "创建完成" << endl << endl;
}

void print(sqlist a)
{
	int length = a.length;
	int i;
	cout << "输出:" << endl;
	if(length != 0) 
	{
		for(i = 0; i < length; i++)
		{ 
			printf("%-3d", a.data[i]); 
			if((i + 1)%20 == 0) 
				cout << endl;
		} 
		cout << endl << endl; 
	}
	else
		cout << "为空!" << endl << endl;
}

void qSort(sqlist &a, int low, int high)
{
	int i = low, j = high, temp;
	if(i < j)
	{
		temp = a.data[i];
		while(i < j)
		{
		
			while(i < j && temp cmp1 a.data[j])
				j--;
			if(i < j)
			{
				a.data[i] = a.data[j];
				i++;
			}
			
			while(i < j && a.data[i] cmp2 temp)
				i++;
			if(i < j)
			{
				a.data[j] = a.data[i];
				j--;
			}
		} 
		a.data[i]  = temp;
		qSort(a, low, i - 1);
		qSort(a, i + 1, high);
	}
}

int main()
{
	sqlist a;
	srand(time(NULL));
	
	init(a);
	print(a);
	
	creat(a);
	print(a);
	
	cout << "快速排序:" << endl;
	qSort(a, 0, a.length - 1);
	print(a);
	
	return 0;
}

5 简单选择

思路:
每次选最小的放在前面

有交换版 和 插入板
交换版,不稳定
插入版稳定

cmp1 控制 交换版的升降序
cmp2 控制 插入版的升降序

#include<bits/stdc++.h> 
#define num 100
#define cmp1 <   // 交换版,无论 < 或 <=均不能保证算法稳定,<降序, >升序 
#define cmp2 <   // 插入版,能保证算法稳定,<降序, >升序 
using namespace std;

typedef struct
{
	int data[num];
	int length;
}sqlist;

void init(sqlist &a)
{
	a.length = 0;
	cout << "初始化完成!" << endl << endl;
}

void creat(sqlist &a)
{
	int length = rand()%num;
	cout << "length = " << length << endl;
	int i;
	
	for(i = 0; i < length; i++)
	{
		a.data[i]= rand()%num;
	}
	a.length = length;
	cout << "创建完成" << endl << endl;
}

void print(sqlist a)
{
	int length = a.length;
	int i;
	cout << "输出:" << endl;
	if(length != 0) 
	{
		for(i = 0; i < length; i++)
		{ 
			printf("%-3d", a.data[i]); 
			if((i + 1)%20 == 0) 
				cout << endl;
		} 
		cout << endl << endl; 
	}
	else
		cout << "为空!" << endl << endl;
}

void exchange(int &a, int &b)
{
	int c;
	c = a;a = b;b = c;
}

void selectSort1(sqlist &a) //交换 
{
	int i, j, temp;
	cout << "简单选择排序(交换版):" << endl;
	for(i = 0; i < a.length; i++) 
	{
		temp = i;
		for(j = i + 1; j < a.length; j++)
		{
			if(a.data[temp] cmp1 a.data[j])
				temp = j;
		}
		exchange(a.data[i], a.data[temp]);
	}
	cout << "完成!" << endl << endl; 
}

void endata(sqlist &a, int low, int high)
{
	int temp = a.data[high];
	--high;
	for(; high >= low; high--)
	{
		a.data[high + 1] = a.data[high];
	}
	a.data[low] = temp;
}

void selectSort2(sqlist &a) // 插入 
{
	int i, j, temp;
	cout << "简单选择排序(插入版):" << endl;
	for(i = 0; i < a.length; i++)
	{
		temp = i;
		for(j = i + 1; j < a.length; j++)
		{
			if(a.data[temp] cmp2 a.data[j])
				temp = j;
		}
		endata(a, i, temp);
	}
	cout << "完成!" << endl << endl;
}

int main()
{
	sqlist a;
	srand(time(NULL));
	
	init(a);
	print(a);
	
	creat(a);
	print(a);
	
	selectSort1(a); //交换 
	print(a);
	
	creat(a);
	print(a);
	
	selectSort2(a); // 插入 
	print(a);
	
	return 0;
}

6 堆排序

大顶堆:父亲 > 孩子
小顶堆:父亲 < 孩子

建堆思路(升序):
i = n/2
i ~ n 建堆
(i- -) ~ n 建堆

直到
0 ~ n 建堆
end

排序:
i = n
对顶堆 i 就是最大元素,和堆尾交换调整
0 - (i- -)建堆,循环,直到 i == 1 成立(下标从0开始的!)

该排序不稳定
其中 cmp 控制升降序 , < 升序, > 降序

该算法综合性能很好,和下面的二路归并一样,因为最坏情况的复杂度比其他排序要好
但要比二路归并的 空间复杂度强,它是O(1),二路归并是O(n)
代码可能看起来有点陌生,用多了就好了吧
代码:

#include<bits/stdc++.h> 
#define num 100
#define c(x) (x + 1)*2 - 1
#define cmp < // 排序不稳定, <升序, >降序 
using namespace std;

typedef struct
{
	int data[num];
	int length;
}sqlist;

void init(sqlist &a)
{
	a.length = 0;
	cout << "初始化完成!" << endl << endl;
}

void creat(sqlist &a)
{
	int length = rand()%num;
	cout << "length = " << length << endl;
	int i;
	
	for(i = 0; i < length; i++)
	{
		a.data[i]= rand()%num;
	}
	a.length = length;
	cout << "创建完成" << endl << endl;
}

void print(sqlist a)
{
	int length = a.length;
	int i;
	cout << "输出:" << endl;
	if(length != 0) 
	{
		for(i = 0; i < length; i++)
		{ 
			printf("%-3d", a.data[i]); 
			if((i + 1)%20 == 0) 
				cout << endl;
		} 
		cout << endl << endl; 
	}
	else
		cout << "为空!" << endl << endl;
}

void sift(sqlist &a, int low, int high) // 一趟建堆
{
	int i = low, j = c(i), temp = a.data[i];
	while(j <= high)
	{
		if(j < high && a.data[j] cmp a.data[j+1])
			j++;
		if(temp cmp a.data[j])
		{
			a.data[i] = a.data[j];
			i = j;
			j = c(i);
		}
		else
			break;
	}
	a.data[i] = temp;
}

void heapSort(sqlist &a)
{
	int i, j, temp;
	cout << "堆排序:" << endl;
	for(i = a.length/2; i >= 0; i--) // 建堆 
		sift(a, i, a.length - 1); 
	for(i = a.length-1; i > 0; i--) 
	{
		temp = a.data[0];
		a.data[0] = a.data[i];
		a.data[i] = temp;
		sift(a, 0, i-1);
	}
	cout << "完成" << endl << endl;
}


int main()
{
	sqlist a;
	srand(time(NULL));
	
	init(a);
	print(a);
	
	creat(a);
	print(a);
	
	heapSort(a);
	print(a);
	
	return 0;
}

7 归并排序

二路归并思路(来源)

注意:
其中子函数merge,的循环条件要特别注意!很容易出错
我这里用的是插入法,设计时费了些心思

还有种方法很简单:就是新建一个新的数组,依次把前后两有序部分从小到大取元素,放进新数组,再把该数组赋值给sqlist中的数组(参考合并两个链表的函数)

#include<bits/stdc++.h> 
#define num 100
#define c(x) (x + 1)*2 - 1
#define cmp < // 排序不稳定, <升序, >降序 
using namespace std;

typedef struct
{
	int data[num];
	int length;
}sqlist;

void init(sqlist &a)
{
	a.length = 0;
	cout << "初始化完成!" << endl << endl;
}

void creat(sqlist &a)
{
	int length = rand()%num;
	cout << "length = " << length << endl;
	int i;
	
	for(i = 0; i < length; i++)
	{
		a.data[i]= rand()%num;
	}
	a.length = length;
	cout << "创建完成" << endl << endl;
}

void print(sqlist a)
{
	int length = a.length;
	int i;
	cout << "输出:" << endl;
	if(length != 0) 
	{
		for(i = 0; i < length; i++)
		{ 
			printf("%-3d", a.data[i]); 
			if((i + 1)%20 == 0) 
				cout << endl;
		} 
		cout << endl << endl; 
	}
	else
		cout << "为空!" << endl << endl;
}

void endata(sqlist &a, int low, int high)
{
	int i = high - 1, temp = a.data[high];
	for(; i >= low; i-- )
		a.data[i+1] = a.data[i];
	a.data[low] = temp;
}

void merge(sqlist &a, int low, int mid, int high)
{
	int i = low, j = mid + 1;
	while(i <= mid && j <= high)
	{
		while(a.data[i] <= a.data[j] && i <= mid)
			i++;
		if(a.data[i] > a.data[j] )
		{	
			endata(a, i, j); // 插入操作,j位置插入i位置,中间元素均后移一位
			mid++;
			i++;
			j++;
		}
	}
} 

void mergeSort(sqlist &a, int low, int high) //递归 
{
	if(low < high)
	{
		int mid = (low + high)/2;
		mergeSort(a, low, mid);
		mergeSort(a, mid + 1, high);
		merge(a, low, mid , high);
	}
}


int main()
{
	sqlist a;
	srand(time(NULL));
	
	init(a);
	print(a);
	
	creat(a);
	print(a);
	
	cout << "二路归并排序:" << endl;
	mergeSort(a, 0, a.length - 1);
	cout << "完成" << endl << endl;
	print(a);
	
	return 0;
}

8 基数排序(LSD / MSD)

参考于文章:
https://www.cnblogs.com/Braveliu/archive/2013/01/21/2870201.html

LSD - 数值的最右边(低位)开始
MSD - 数值的最左边(高位)开始

LSD - 适用 位数 的数列
MSD - 适用 位数 的数列

8.1 LSD

来源):

思路:
低数位 向着 高位 依次在 ‘桶里’ 排序
依次 就是 循环

	for(i = 1; i < 10; i++) // 不可省略,让对应元素是在其对应位置
		b[i] += b[i-1];
		
	for(i = a.length-1; i >= 0; i--) //从后向前排序,不可换方向! 
	{
		output[ b[(a.data[i]/exp)%10] - 1 ] = a.data[i];
		b[(a.data[i]/exp)%10]--;
	}

上面代码在做的事:

白色部分 无元素
淡黄色部分 元素数为1
淡蓝色部分 元素数大于1

#include<bits/stdc++.h> 
#define num 100
using namespace std;

typedef struct
{
	int data[num];
	int length;
}sqlist;

void init(sqlist &a)
{
	a.length = 0;
	cout << "初始化完成!" << endl << endl;
}

void creat(sqlist &a)
{
	int length = rand()%num;
	cout << "length = " << length << endl;
	int i;
	
	for(i = 0; i < length; i++)
	{
		a.data[i]= rand()%num;
	}
	a.length = length;
	cout << "创建完成" << endl << endl;
}

void print(sqlist a)
{
	int length = a.length;
	int i;
	cout << "输出:" << endl;
	if(length != 0) 
	{
		for(i = 0; i < length; i++)
		{ 
			printf("%-3d", a.data[i]); 
			if((i + 1)%20 == 0) 
				cout << endl;
		} 
		cout << endl << endl; 
	}
	else
		cout << "为空!" << endl << endl;
}

int getmax(sqlist a)
{
	int i, max = a.data[0];
	for(i = 1; i < a.length; i++)
	{
		if(max < a.data[i])
			max = a.data[i];
	}
	return max;
}

void countSort(sqlist &a, int exp)
{
	int b[10] = {0}, output[a.length] = {0}; 
	int i;
	for(i = 0; i < a.length; i++) //对应位置的个数 
		b[ (a.data[i]/exp)%10 ]++; 
	
	for(i = 1; i < 10; i++) // 不可省略,让对应元素是在其对应位置
		b[i] += b[i-1];
		
	for(i = a.length-1; i >= 0; i--) //从后向前排序,不可换方向! 
	{
		output[ b[(a.data[i]/exp)%10] - 1 ] = a.data[i];
		b[(a.data[i]/exp)%10]--;
	}
	
	for(i = 0; i < a.length; i++) 
		a.data[i] = output[i];
}

void radixSort(sqlist &a) 
{
	int exp, max;
	cout << "基数归并排序:" << endl;
	max = getmax(a); //获取数组中最大值 
	for(exp = 1; max/exp > 0; exp *= 10) // 循环次数 = max的数字位数, 如2351就有4次 
		countSort(a, exp);
	cout << "完成" << endl << endl;
}


int main()
{
	sqlist a;
	srand(time(NULL));
	
	init(a);
	print(a);
	
	creat(a);
	print(a);
	
	radixSort(a);
	print(a);
	
	system("pause");
	return 0;
}

8.2 MSD

图解:https://blog.csdn.net/xgf415/article/details/76595887

思路
1 先来一次最高位的 桶排(与LSD的前半部分基本一样,但注意此时排序的范围是:low - high,不是 0 - a.length)
2 此时 数组b[10]中的详细情况:( 0 <= i < 10)
2.1 若该位置 i 无元素,那么b[ i - 1 ] == b[ i ] 成立;
2.2.1 若有元素,个数为1,那么 b[ i - 1 ] == b[ i ] 也成立;
2.2.2 若个数 大于 1,那么就需要 MSD排序一下了!

2 的核心代码

for(i = 0; i < 10; i++)
	{
		p1 = low + b[i];
		if(i < 9)
			p2 = low + b[i + 1] - 1;
		else
			p2 = high;
		if(p1 < p2 && (exp/10 > 0))
			MSDradixSort(a, p1, p2, exp/10);
	}

范围是p1 ~ p2
p1 = low + b[ i ]
p2 = high + b[ i + 1] - 1

i 位置元素个数等于0时,p1 > p2成立
i 位置元素个数小于等于1时,p1 == 2成立,不需要去MSD排序,MSD在此时只排序2个以上的元素!
i 位置元素个数大于1时,p1 < p2,要MSD,所以p1 < p2作为MSD的执行条件

下图为最高位排序后b[10]的情况

白色部分 无元素
淡黄色部分 元素数为1
淡蓝色部分 元素数大于1!这部分是我想去MSD的

此时low = 0
b[2]无元素
p1 = low + b[2] = 0 + 1 = 1
p2 = low + b[3] - 1 = 0 + 1 - 1= 0,p1 < p2 不成立

b[3]两个元素
p1 = low + b[3] = 0 + 1 = 1
p2 = low + b[4] - 1= 0 + 3 - 1= 2
所以在i = (2 - 1)的位置进行MSD

代码:
费了很多时间才改完一大堆bug…

#include<bits/stdc++.h> 
#define num 100
using namespace std;

typedef struct
{
	int data[num];
	int length;
}sqlist;

void init(sqlist &a)
{
	a.length = 0;
	cout << "初始化完成!" << endl << endl;
}

void creat(sqlist &a)
{
	int length = rand()%num;
	cout << "length = " << length << endl;
	int i;
	
	for(i = 0; i < length; i++)
	{
		a.data[i]= rand();
	}
	a.length = length;
	cout << "创建完成" << endl << endl;
}

void print(sqlist a)
{
	int length = a.length;
	int i;
	cout << "输出:" << endl;
	if(length != 0) 
	{
		for(i = 0; i < length; i++)
		{ 
			printf("%-6d ", a.data[i]); 
			if((i + 1)%10 == 0) 
				cout << endl;
		} 
		cout << endl << endl; 
	}
	else
		cout << "为空!" << endl << endl;
}

int getmax(sqlist a)
{
	int i, max = a.data[0];
	for(i = 1; i < a.length; i++)
	{
		if(max < a.data[i])
			max = a.data[i];
	}
	return max;
}

int getexp(int max)
{
	int exp;
	for(exp = 1; max/exp > 0; exp *= 10);
	return exp/10;
}

void countSort(sqlist &a, int b[], int low, int high, int exp)
{
	int *output = (int *)malloc((high - low + 1)*sizeof(int)); 
	int i;
	for(i = low; i <= high; i++) //对应位置的个数 
		b[ (a.data[i]/exp)%10 ]++; 
	
	for(i = 1; i < 10; i++) // 不可省略,让对应元素是在其对应位置
		b[i] += b[i - 1];
		
	for(i = high; i >= low; i--) //从后向前排序,不可换方向! 
	{
		output[ b[(a.data[i]/exp)%10] - 1 ] = a.data[i];
		b[(a.data[i]/exp)%10]--;
	}
	
	for(i = low; i <= high; i++) 
		a.data[i] = output[i - low];
}

void MSDradixSort(sqlist &a, int low, int high, int exp) 
{
	int i;
	int p1, p2;
	int b[10] = {0}; 
	countSort(a, b, low, high, exp); // 一次 按最高位在桶里排序,参考 LSD 
	// 数组b[]存放各元素一次排序后的位置 
	for(i = 0; i < 10; i++)
	{
		p1 = low + b[i];
		if(i < 9)
			p2 = low + b[i + 1] - 1;
		else
			p2 = high;
		if(p1 < p2 && (exp/10 > 0))
			MSDradixSort(a, p1, p2, exp/10);
	}
}

void MSD(sqlist &a) 
{
	int max, exp;
	cout << "基数归并排序:" << endl;
	max = getmax(a); //获取数组中最大值 
	exp = getexp(max); // exp指的是 最大值最高位的整数,如 32324的exp=10000 
	MSDradixSort(a, 0, a.length - 1, exp); // 开始真正的基数排序 
	cout << "完成" << endl << endl;
}


int main()
{
	sqlist a;
	srand(time(NULL));
	
	init(a);
	print(a);
	
	creat(a);
	print(a);
	
	MSD(a);
	print(a);
	
	system("pause");
	return 0;
}

9 希尔排序

动态图来源

代码:

#include<bits/stdc++.h> 
#define num 100
#define cmp > // 排序不稳定, <降序, >升序
using namespace std;

typedef struct
{
	int data[num];
	int length;
}sqlist;

void init(sqlist &a)
{
	a.length = 0;
	cout << "初始化完成!" << endl << endl;
}

void creat(sqlist &a)
{
	int length = rand()%num;
	cout << "length = " << length << endl;
	int i;
	
	for(i = 0; i < length; i++)
	{
		a.data[i]= rand()%num;
	}
	a.length = length;
	cout << "创建完成" << endl << endl;
}

void print(sqlist a)
{
	int length = a.length;
	int i;
	cout << "输出:" << endl;
	if(length != 0) 
	{
		for(i = 0; i < length; i++)
		{ 
			printf("%-3d", a.data[i]); 
			if((i + 1)%20 == 0) 
				cout << endl;
		} 
		cout << endl << endl; 
	}
	else
		cout << "为空!" << endl << endl;
}

void make(int k[], int length)
{
	int i = 0;
	for(; length > 0; length /= 2)
	{
		k[i++] = length;
	}
}

void insertSort(sqlist &a, int length) //思想:和直接插入排序 一样,形式有点不同而已  
{                                      //多与  直接插入排序 比较比较 
	int i, j, temp;
	
	for(i = length; i < a.length ; i++) 
	{
		temp = a.data[i];
		for(j = i - length; j >= 0 && a.data[j] cmp temp; j -= length)
			a.data[j + length] = a.data[j]; // 向后移动,步长为 length 
		a.data[j + length] = temp;
	}
}

void ShellSort(sqlist &a)
{
	int i, k[num]={0};
	make(k, a.length/2); // 设计步长 
	cout << "希尔排序:" << endl;
	for(i = 0; k[i] > 0; i++)
		insertSort(a, k[i]); // k[i]是步长,直接插入排序 
	cout << "完成" << endl << endl;
}


int main()
{
	sqlist a;
	srand(time(NULL));
	
	init(a);
	print(a);
	
	creat(a);
	print(a);
	
	
	ShellSort(a);
	print(a);
	
	system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_1403034144

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值