数组-排序和查找-C语言-数据结构与算法

1-冒泡排序
2-选择排序
3-插入排序
4-快速排序(递归实现)
5-快速排序(迭代实现)
6-归并排序(递归实现)
7-归并排序(迭代实现)
8-二分查找(递归实现)
9-二分查找(迭代实现)
10-顺序查找

//****************************************
//数据结构:数组
//算法:常用排序和查找
//首次编辑时间:2020/05/12
//最后修改时间:2020/05/25
//****************************************
#include<stdio.h>
#include<stdlib.h>

void show_array();//打印显示数组
void swap();//交换数组某两个值
void bubble_sort();//冒泡排序
void selection_sort();//选择排序
void insertion_sort();//插入排序
void quick_sort_recurrence();//快速排序(递归实现)
void quick_sort_iteration();//快速排序(迭代实现)
void merge_sort_recurrence();//归并排序(递归实现)
void merge_sort_iteration();//归并排序(迭代实现)
void binary_search_recurrence();//二分查找(递归实现)
void binary_search_iteration();//二分查找(迭代实现)
void sequence_search();//顺序查找
int main()
{
	while (1)
	{
		int a[10] = { 4,1,2,9,6,7,5,8,10,3 };
		int action, value_search;
		printf("*****************************\n");
		printf("选择:\n");
		printf("0-结束退出 ");
		printf("1-冒泡排序\n");
		printf("2-选择排序 ");
		printf("3-插入排序\n");
		printf("4-快速排序(递归实现)\n");
		printf("5-快速排序(迭代实现)\n");
		printf("6-归并排序(递归实现)\n");
		printf("7-归并排序(迭代实现)\n");
		printf("8-二分查找(递归实现)\n");
		printf("9-二分查找(迭代实现)\n");
		printf("10-顺序查找\n");
		printf("-----------------------------\n");
		printf("原数组:");
		show_array(a);
		printf("-----------------------------\n");
		printf("输入选择序号:");
		scanf("%d", &action);
		if ((action >= 8) && (action <= 10))//8-10为查找算法
		{
			printf("输入要查找值:");
			scanf("%d", &value_search);
		}
		printf("-----------------------------\n");
		switch (action)
		{
		case 0:return 0;
		case 1:bubble_sort(a);break;
		case 2:selection_sort(a);break;
		case 3:insertion_sort(a);break;
		case 4:quick_sort_recurrence(a, 0, sizeof(a) / sizeof(int) - 1);break;
		case 5:quick_sort_iteration(a, 0, sizeof(a) / sizeof(int) - 1);break;
		case 6:merge_sort_recurrence(a, 0, sizeof(a) / sizeof(int) - 1);break;
		case 7:merge_sort_iteration(a, 0, sizeof(a) / sizeof(int) - 1);break;
		case 8:bubble_sort(a);binary_search_recurrence(a, value_search, 0, 9);break;
		case 9:bubble_sort(a);binary_search_iteration(a, value_search, 0, 9);break;
		case 10:sequence_search(a, value_search);break;
		default:printf("无效序号!");
		}
		if (action < 10)//顺序查找不需要显示排序后数组
		{
			printf("新数组:");
			show_array(a);
		}
	}
}

void show_array(int a[10])//打印显示数组
{
	int i;
	for (i = 0;i < 10;i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}

void swap(int *a, int i, int j)//交换数组某两个值
{
	int temp = a[i];
	a[i] = a[j];
	a[j] = temp;
}

//冒泡排序
// 最差时间复杂度 ---- O(n^2)
// 最优时间复杂度 ---- 如果能在内部循环第一次运行时,使用一个标志来表示有无需要交换的可能,可以把最优时间复杂度降低到O(n)
// 平均时间复杂度 ---- O(n^2)
// 所需辅助空间 ------ O(1)
// 稳定性 ------------ 稳定
void bubble_sort(int *a)
{
	int i,j;
	for (i = 9;i > 0;i--)
	{
		for (j = 1;j <= i;j++)
		{
			if (a[j - 1] > a[j])
				swap(a,j,j-1);
		}
	}
}

//选择排序
// 数据结构 ---------- 数组
// 最差时间复杂度 ---- O(n^2)
// 最优时间复杂度 ---- O(n^2)
// 平均时间复杂度 ---- O(n^2)
// 所需辅助空间 ------ O(1)
// 稳定性 ------------ 不稳定
void selection_sort(int *a)
{
	int i, j,min;
	for (i = 0;i < 10;i++)
	{
		min = i;
		for (j = i;j < 10;j++)
			if (a[j] < a[min])
				min = j;
		if (min != i)
			swap(a,min,i);
	}
}

//插入排序
// 最差时间复杂度 ---- 最坏情况为输入序列是降序排列的,此时时间复杂度O(n^2)
// 最优时间复杂度 ---- 最好情况为输入序列是升序排列的,此时时间复杂度O(n)
// 平均时间复杂度 ---- O(n^2)
// 所需辅助空间 ------ O(1)
// 稳定性 ------------ 稳定
void insertion_sort(int *a)
{
	int i, j,get;
	for (i = 1;i < 10;i++)
	{
		get = a[i];
		for (j = i - 1;j >= 0;j--)
			if (get < a[j])
				a[j + 1] = a[j];
			else
				break;
		a[j + 1] = get;
	}
}

//快速排序
// 最差时间复杂度 ---- 每次选取的基准都是最大(或最小)的元素,导致每次只划分出了一个分区,需要进行n-1次划分才能结束递归,时间复杂度为O(n^2)
// 最优时间复杂度 ---- 每次选取的基准都是中位数,这样每次都均匀的划分出两个分区,只需要logn次划分就能结束递归,时间复杂度为O(nlogn)
// 平均时间复杂度 ---- O(nlogn)
// 所需辅助空间 ------ 主要是递归造成的栈空间的使用(用来保存left和right等局部变量),取决于递归的深度,一般为O(logn),最差为O(n)       
// 稳定性 ------------ 不稳定
void quick_sort_recurrence(int a[], int left, int right)//(递归实现)
{
	int i, pivot_index = left;
	if (left >= right)
		return;
	for (i = left;i < right;i++)
	{
		if (a[i] <= a[right])
			swap(a, pivot_index++, i);
	}
	swap(a, pivot_index, right);

	quick_sort_recurrence(a,left, pivot_index -1);
	quick_sort_recurrence(a, pivot_index +1, right);
}

void quick_sort_iteration(int a[], int left, int right)//(迭代实现)
{
	int i, pivot_index, last = 0;//last用来记录未划分的区域个数。划分一次st长度++,进入划分一次st长度--,减到-1结束。
	struct st//用于保存每次划分的范围
	{
		int left;
		int right;
	}st[10];
	st[last].left = left;
	st[last].right = right;
	while (last > -1)
	{
		left = st[last].left;
		right = st[last--].right;
		if (left < right)
		{
			pivot_index = left;
			for (i = left;i < right;i++)
			{
				if (a[i] <= a[right])
					swap(a, pivot_index++, i);
			}
			swap(a, pivot_index, right);
			st[++last].left = left;
			st[last].right = pivot_index-1;
			st[++last].left = pivot_index + 1;
			st[last].right = right;
		}
	}
}

//归并排序
// 最差时间复杂度 ---- O(nlogn)
// 最优时间复杂度 ---- O(nlogn)
// 平均时间复杂度 ---- O(nlogn)
// 所需辅助空间 ------ O(n)
// 稳定性 ------------ 稳定
void merge_sort_recurrence(int *a, int left, int right)//(递归实现)
{
	int i = 0, mid = (left + right) / 2, len = right - left + 1;
	int a1 = left, a2 = mid + 1;
	int *temp = (int*)malloc(sizeof(int)*len);
	if (left == right)
		return;
	merge_sort_recurrence(a, left, mid);
	merge_sort_recurrence(a, mid + 1, right);

	while ((a1 <= mid) || (a2 <= right))
	{
		if ((a1 <= mid) && (a2 <= right))
			temp[i++] = a[a1] <= a[a2] ? a[a1++] : a[a2++];
		else if((a1 <= mid) && (a2 > right))
			temp[i++] = a[a1++];
		else if ((a1 > mid) && (a2 <= right))
			temp[i++] = a[a2++];
	}
	for (i = 0;i < len;i++)
		a[left++] = temp[i];
	free(temp);
}

void merge_sort_iteration(int *a, int left, int right)//(迭代实现)
{
	int i, mid, a1, a2, j, len= right - left + 1;
	int *temp;

	for (j = 1;j < len;j *= 2)
	{
		for (left = 0;left < len - j;left = right+1)
		{
			mid = left + j - 1;
			right = mid + j;
			if (right > len - 1)
				right = len - 1;
			a1 = left;
			a2 = mid + 1;
			i = 0;
			temp = (int*)malloc(sizeof(int)*(right - left + 1));
			while ((a1 <= mid) || (a2 <= right))
			{
				if ((a1 <= mid) && (a2 <= right))
					temp[i++] = a[a1] <= a[a2] ? a[a1++] : a[a2++];
				else if ((a1 <= mid) && (a2 > right))
					temp[i++] = a[a1++];
				else if ((a1 > mid) && (a2 <= right))
					temp[i++] = a[a2++];
			}
			for (i = 0;i < (right - left + 1);i++)
				a[left + i] = temp[i];
			free(temp);
		}
	}
}

//顺序查找
//时间复杂度为O(n)
void sequence_search(int* a, int value_search)
{
	int i;
	for (i = 0;i < 10;i++)
		if (a[i] == value_search)
			printf("该值在数组的第%d个!\n",i+1);
}

//二分查找
//时间复杂度可为O(log2 n)
void binary_search_recurrence(int *a, int value_search, int left, int right)//(递归实现)
{
	int mid;
	while (left <= right)
	{
		mid = left + (right - left) / 2;
		if (a[mid] == value_search)
		{
			printf("该值在排序后新数组的第%d个!\n",mid+1);
			return;
		}
		else if (a[mid] > value_search)
			right = mid - 1;
		else if (a[mid] < value_search)
			left = mid + 1;
	}
}

void binary_search_iteration(int *a, int value_search, int left, int right)//(迭代实现)
{
	int mid;
	if (left <= right)
	{
		mid = left + (right - left) / 2;
		if (a[mid] == value_search)
		{
			printf("该值在排序后新数组的第%d个!\n", mid + 1);
			return;
		}
		else if (a[mid] > value_search)
			binary_search_iteration(a, value_search, left, mid);
		else if (a[mid] < value_search)
			binary_search_iteration(a, value_search, mid, right);
	}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值