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);
}
}