排序算法(数组实现)

目录

辅助函数

冒泡排序

插入排序

折半插入排序

2-路插入排序 

选择排序

希尔排序

Hibbard增量序列

Sedgewick增量序列

基于堆的选择排序

分而治之递归算法

分而治之非递归算法

快速排序

测试函数

表排序

基数排序与桶排序



辅助函数

​
//针对数组结构的算法
#include"c1.h"
#include "bo6堆.h"

#define MAX_NUM 20
#define cutoff 5 //阈值
typedef int ElementType;


int InputData(ElementType A[])
{//数据的读入
	int i,len;
	char s;
	printf("请输入数据数量:\n");
	scanf("%d",&len);
	for (i = 0;i < len;i++)
	{
		printf("请输入第%d个数据:\n",i+1);
		scanf("%d",&A[i]);
		getchar(s);
	}
	return len;
	
}

void OutputData(ElementType A[],int len)
{//数据的输出
	int i;
	for (i = 0;i < len;i++)
		printf("%3d",A[i]);
	printf("\n");
	
}

void copyData(ElementType Source[],ElementType Target[],int n)
{//将source数组copy到target数组
	int i;
	for (i = 0;i < n;i++)
	{
		Target[i] = Source[i];
	}
}

void swapElement(ElementType A[],int v,int w)
{//将A数组中下标为v和w的元素交换位置
	ElementType temp;
	temp = A[v];
	A[v] = A[w];
	A[w] = temp;
	
}

​

冒泡排序

void BubbleSort(ElementType A[],int n)
{//冒泡排序算法
	int i,j;
	bool key = true;
	ElementType temp;
	for (i = n;i > 0;i--)
	{
		for (j = 0;j < i-1;j++)
		{
			if (A[j] > A[j+1])
			{
				temp = A[j];
				A[j] = A[j+1];
				A[j+1] = temp;
				key = false;
			}
		}
		if (key)
			break;
	}
	
}

插入排序

void InsertSort(ElementType A[],int n)
{//插入排序算法(简单)
	int i,j;
	ElementType temp;
	for (i = 1;i < n;i++)
	{
		temp = A[i];
		for (j = i;j > 0;j--)
		{
			if (A[j-1] > temp)
				A[j] = A[j-1];
			else
				break;
		}
		A[j] = temp;
	}
}

折半插入排序

void BInsertSort(ElementType A[],int n)
{//折半插入排序算法
	int i,j;
	ElementType insertdata;
	for (i = 1;i < n;i++)
	{
		insertdata = A[i];
		if (insertdata < A[i-1])
		{
			int left = 0;
			int right = i-1;
			int center = (left+right)/2;
			if (insertdata < A[0])
			{
				for (j = i;j > 0;j--)
					A[j] = A[j-1];
				A[0] = insertdata;
			}
			else
			{
				while (!(A[center] < insertdata && A[center+1] > insertdata))
				{
					if (insertdata > A[center])
					{
						left = center;
						center = (left+right)/2;
					}
					else if (insertdata < A[center])
					{
						right = center;
						center = (left+right)/2;
					}
				}
				for (j = n;j > center+1;j--)
					A[j] = A[j-1];
				A[center+1] = insertdata;
			}
		}
	}
	
}

2-路插入排序 

void P2_InsertSort(ElementType A[],int n)
{//2-路插入排序
	ElementType temp[MAX_NUM];
	int i,k,first,final;

	temp[0] = A[0];//初始化将A数组中的第一个元素取出来作为辅助数组的第一个参考元素
	first = final = 0;//初始化i,j第一个元素即为最大元素,也为最小元素

	for (i = 1;i < n;i++)
	{
		if (A[i] <= A[first])
		{//比最小元素还小
			first = (first - 1 + n)%n;
			temp[first] = A[i];
		}
		else if (A[i] >= A[final])
		{//比最大元素还大
			final = (final + 1 + n)%n;
			temp[final] = A[i];
		}
		else 
		{//介于最小元素和最大元素之间
			k = (final + 1 + n)%n;
			while (temp[(k - 1 + n)%n] > A[i])
			{
				temp[(k + n)%n] = temp[(k - 1 + n)%n];
				k = (k - 1 + n)%n;

			}
			temp[(k + n)%n] = A[i];
			final = (final + 1 + n)%n;
		}
	}

	for (i = 0;i < n;i++)
		A[i] = temp[(first + i + n)%n];
	
}

选择排序

void chooseSort(ElementType A[],int n)
{//选择排序算法(简单)
	int i,j,minindex;
	ElementType mindata;
	for (i = 0;i < n-1;i++)
	{
		mindata = A[i];
		minindex = i;
		for (j = i;j < n;j++)
		{
			if (A[j] < mindata)
			{
				mindata = A[j];
				minindex = j;
			}
		}
		A[minindex] = A[i];
		A[i] = mindata;
	}
}

希尔排序

void shellSort(ElementType A[],int n)
{//希尔排序算法(原始序列)
	int D,p,k;
	int temp;
	for (D = n/2;D > 0;D = D/2)
	{
		for (p = D;p < n;p++)
		{
			temp = A[p];
			for (k = p;k >= D && A[k-D] > temp;k -= D)
				A[k] = A[k-D];
			A[k] = temp;
		}
	}
	
}

Hibbard增量序列

void shellHibbardSort(ElementType A[],int n)
{//希尔排序算法(Hibbard增量序列)
	int i,D,p,k;
	int temp,begin;
	begin = 1;
	while ((int)pow(2,begin) - 1 < n)
		begin++;
	begin--;
	for (i = begin;i > 0;i--)
	{
		D = (int)pow(2,i) - 1;
		for (p = D;p < n;p++)
		{
			temp = A[p];
			for (k = p;k >= D && A[k-D] > temp;k -= D)
				A[k] = A[k-D];
			A[k] = temp;
		}
	}
	
}

Sedgewick增量序列

基于堆的选择排序

void chooseHeapSort(ElementType A[],int n)
{//基于堆的选择排序算法
	BiTree T;
	int i;
	ElementType e;
	T = (BiTNode*)malloc(sizeof(BiTNode));
	CreateHeap(T);
	for (i = 0;i < n;i++)
		InsertTree(T,A[i]);
	for (i = 0;i < n;i++)
	{
		DeleteTree(T,&e);
		A[n-1-i] = e;
		
	}

	
}

分而治之递归算法

void Merge(ElementType A[],ElementType TempA[],int L,int R,int RightEnd)
{//有序子列的归并
 //L左边起始位置,R右边起始位置,RightEnd右边结束位置
	int i,j,k = L;
	int LeftEnd = R-1;//左边结束位置
	i = L;
	j = R;
	while (i <= LeftEnd && j <= RightEnd)
	{
		if (A[i] < A[j])
		{
			TempA[k] = A[i];
			i++;
			k++;
		}
		else if (A[i] > A[j])
		{
			TempA[k] = A[j];
			j++;
			k++;
		}
	}
	while (i <= LeftEnd)
	{
		TempA[k] = A[i];
		i++;
		k++;
	}
	while (j <= RightEnd)
	{
		TempA[k] = A[j];
		j++;
		k++;
	}
	//归并到TempA之后还要复制回去
	for (i = RightEnd;i >= L;i--)
		A[i] = TempA[i];

}


void Msort(ElementType A[],ElementType TempA[],int L,int RightEnd)
{//分而治之递归算法(基于有序子列的归并)
	int center = (L + RightEnd)/2;
	if (L < RightEnd)
	{
		Msort(A,TempA,L,center);
		Msort(A,TempA,center+1,RightEnd);
		Merge(A,TempA,L,center+1,RightEnd);
	}
	
}

void Merge_sort(ElementType A[],int n)
{//统一函数接口
	ElementType TempA[MAX_NUM];
	int L = 0,RightEnd = n-1;
	Msort(A,TempA,L,RightEnd);
}

分而治之非递归算法

void Merge1(ElementType A[],ElementType TempA[],int L,int R,int RightEnd)
{//有序子列的归并(针对非递归算法)
 //L左边起始位置,R右边起始位置,RightEnd右边结束位置
 //归并完之后,不把TempA复制给A,下一次从TempA归并到A上。
	int i,j,k = L;
	int LeftEnd = R-1;//左边结束位置
	i = L;
	j = R;
	while (i <= LeftEnd && j <= RightEnd)
	{
		if (A[i] < A[j])
		{
			TempA[k] = A[i];
			i++;
			k++;
		}
		else if (A[i] > A[j])
		{
			TempA[k] = A[j];
			j++;
			k++;
		}
	}
	while (i <= LeftEnd)
	{
		TempA[k] = A[i];
		i++;
		k++;
	}
	while (j <= RightEnd)
	{
		TempA[k] = A[j];
		j++;
		k++;
	}

}


void Merge_pass(ElementType A[],ElementType TempA[],int n,int length)
{//length为当前有序子列的长度
	int i,j;
	for (i = 0;i <= n - 2*length;i += length*2)
		Merge1(A,TempA,i,i+length,i+2*length-1);
	if (i + length < n)
		Merge1(A,TempA,i,i+length,n-1);
	else
	{
		for (j = i;j < n;j++)
			TempA[j] = A[j];
	}
	
}

void Merge_sort_two(ElementType A[],int n)
{//分而治之非递归算法
	int length = 1;
	ElementType TempA[MAX_NUM];
	while (length < n)
	{
		Merge_pass(A,TempA,n,length);
		length *= 2;
		Merge_pass(TempA,A,n,length);
		length *= 2;
	}
}

快速排序


ElementType Median3(ElementType A[],int left,int right)
{
	int center = (left + right)/2;
	if (A[left] > A[center])
		swapElement(A,left,center);
	if (A[left] > A[right])
		swapElement(A,left,right);
	if (A[center] > A[right])
		swapElement(A,center,right);
	swapElement(A,center,right-1);//把pivot存储到right-1位置
	return A[right-1];
}

void QuickSort(ElementType A[],int left,int right)
{
	if (cutoff <= right-left)
	{//阈值需自己求出
		int pivot;
		int i = left,j = right-1;
		
		pivot = Median3(A,left,right);
		printf("pivot = %d\n",pivot);
		while (true)
		{
			while (A[++i] < pivot) {}
			while (A[--j] > pivot) {}
			if (i < j)
				swapElement(A,i,j);
			else 
				break;
		}
		swapElement(A,i,right-1);//此时i位置左边的元素都比pivot小,把pivot换到i位置上
		QuickSort(A,left,i-1);//为什么是i-1
		QuickSort(A,i+1,right);//为什么是i+1
	}
	else
		chooseSort(A,right-left+1);
}

void Quick_sort(ElementType A[],int n)
{//统一函数接口
	QuickSort(A,0,n-1);
	
}

测试函数

void main()
{//对同一组数据进行多次算法测试
	ElementType A[MAX_NUM];
	ElementType B[MAX_NUM];
	int num;
	char option,handle;
	int keynum;
	bool key = true;
	num = InputData(A);
	OutputData(A,num);
	while (key)
	{
		printf("选择算法名称:\n");
		printf("a :冒泡排序 b :插入排序 c :折半插入排序 d: 2-路插入排序 \
				e :选择排序 f :希尔排序 g :Hibbard增量序列 h: Sedgewick增量序列\
				i :基于堆的选择排序 j :分而治之递归算法 k :分而治之非递归算法\
				l :快速排序\n");
		scanf("%c",&option);
		copyData(A,B,num);
		printf("这是原始序列:\n");
		OutputData(B,num);
		switch(option)
		{
			case 'a':
			case 'A':
				BubbleSort(B,num);//冒泡排序算法
				break;
			case 'b':
			case 'B':
				InsertSort(B,num);//插入排序算法
				break;
			case 'c':
			case 'C':
				BInsertSort(B,num);//折半插入排序算法
				break;
			case 'D':
			case 'd':
				P2_InsertSort(B,num);//2-路插入排序算法
				break;
			case 'E':
			case 'e':
				chooseSort(B,num);//选择排序算法
				break;
			case 'F':
			case 'f':
				shellSort(B,num);//希尔排序算法
				break;
			case 'G':
			case 'g':
				shellHibbardSort(B,num);//希尔排序算法(Hibbard增量序列)
				break;
			case 'H':
			case 'h':
				shellSedgewickSort(B,num);//希尔排序算法(Sedgewick增量序列)
				break;
			case 'I':
			case 'i':
				chooseHeapSort(B,num);//基于堆的选择排序算法
				break;
			case 'J':
			case 'j':
				Merge_sort(B,num);//分而治之递归算法(基于有序子列的归并)
				break;
			case 'K':
			case 'k':
				Merge_sort_two(B,num);//分而治之非递归算法(基于有序子列的归并)
				break;
			case 'L':
			case 'l':
				Quick_sort(B,num);//快速排序算法
				break;
			default:
				break;
		}
		printf("这是排序之后的序列:\n");
		OutputData(B,num);
		printf("是否继续进行算法检测(1 :yes 0:no):\n");
		scanf("%d%c",&keynum,&handle);
		if (keynum == 0)
			key = false;
	}

}

表排序

数据本身较庞大,移动起来比较费时

  • 间接排序

对指针进行排序

  • 物理排序

必须对数据进行移动的时候

基数排序与桶排序

  • 若数据范围M和待排数据数量N接近,直接进行桶排序
  • 若数据范围M远大于待排数据数量N,则需进行基数排序。
  • 若待排数据并非数字,那么需看情况选取关键字。

 小白一枚,若有错误,还望各位多多批评指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值