常见排序算法
中间函数
#include<stdio.h>
// 如果使用这种方式进行数据交换的话,在传入同一个元素地址进行元素交换时,
//会导致a=b=0,因为都是对同一个地址中的内容进行操作。
void swape(int* a,int* b)
{
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
void print(int* arr, int len)
{
for(int i = 0; i < len; i++)
printf("%d ", *(arr+i));
printf("\n");
}
1.冒泡排序
/*
*函数名:冒泡排序
*参数:数组名,数组长度
*思路:简单一点就是有几个数就进行几轮排序,在每轮排序中对所有数值进行前后比较,每一轮比较下来就会有一个数值的位置是可以确定的
*缺点:一般来说到了最后几轮的排序,数值基本上都是排好序了的,所以容易造成运行时间的浪费
*改进:可以在每一轮的比较排序中,增加标志位,如果在该轮的比较中进行了数值的交换,就将标志位置为1,否则就将标志位置为0,
*然后在进行新一轮比较时,检查标志位如果为1,则在进行新一轮比较,否则就break;
*/
/*
*
*函数名:冒泡排序
*参数:数组名,数组长度
*思路:简单一点就是有几个数就进行几轮排序,在每轮排序中对所有数值进行前后比较,每一轮比较下来就会有一个数值的位置是可以确定的
*缺点:一般来说到了最后几轮的排序,数值基本上都是排好序了的,所以容易造成运行时间的浪费
*改进:可以在每一轮的比较排序中,增加标志位,如果在该轮的比较中进行了数值的交换,就将标志位置为1,负责就为0,
*然后在进行新一轮比较时,检查标志位是否为1,如果是则在进行新一轮比较,负责就break;
*/
void Bubble_Sort(int* arr, int len)
{
int temp = 0;
int flag = 1;
for (int i = 1; i < len; i++)
{
if(flag)
{
flag = 0;
for (int j = 0; j < len - 1 -i; j++) {
if (arr[j]) > arr[j + 1]) {
swape(arr[j], arr[j + 1]);
flag = 1;
}
}
printf("第%d次排序:\n",i);
print(arr, len);
}
else
{
break;
}
}
printf("\n");
}
2.选择排序
/*
* 函数名:选择排序
* 函数参数:数组名arr,数组长度len
* 思路:进行len-1轮循环,每轮循环找出最大(最小)的值,放到已排序好的数组的末尾
*一开始也就是将找到的最大(小)的元素放到首位置,
*然后再将在第二轮找到的最大(小)值放到首位置的后面位置,以此类推.....
*/
void Select_Sort(int* arr, int len)
{
int index = 0;
for (int i = 0; i < len - 1; i++)
{
index = i;
for (int j = i + 1; j < len; j++)
{
if (arr[j]) < arr[index]) {
index = j; //记录此轮循环中最小值的下标
}
}
if(i != index)swape(arr[i]), (arr[index]); //将此轮循环的最小值放到已排序序列的末尾位置
printf("第%d次排序:\n", i+1);
print(arr, len);
}
printf("\n");
}
3.插入排序
/*
*函数名:插入排序
*函数参数:数组名arr,数组长度len
*思路:将无序数值,插入有序数值,从后往前扫描。
*(刚开始就将第一个元素看作的有序的,然后将第二元素与第一个元素进行比较排序,
*此时就可以得到一个由两个数值组成的有序数组了,
* 然后将第三个元素插入到有序数组中,以此类推.....)
*
*
*/
void Insert_Sort(int* arr, int len)
{
int i = 0, j = 0;
int temp = 0;
for (int i = 1; i < len; i++)
{
temp = arr[i];
j = i - 1;
while (j >= 0 && arr[j] > temp) {
arr[j + 1] = arr[j];
j--;
}
arr[j+1] = temp;
printf("第%d次排序:\n", i);
print(arr, len);
}
}
4.快速排序
/*
*函数名:寻找基准元素下标,在寻找的同时也会对传入的数组值,进行基于基准值的左右划分
*
*/
static int i = 0;
int Find_Pivot_Index(int* arr, int left, int right)
{
int L = left, R = right;
int pivot = arr[left]; //选择最左边的元素作为基准值
while (L != R) {
while (arr[R] >= pivot && L < R) { //从最右边开始扫描,如果比基准值大,就不断向左移动
R--;
}
arr[L] = arr[R]; //到了这里,说明在基准值右边碰到了一个比它小的,所以就把比基准值小的放到其左边
while (arr[L] <= pivot && L < R) { //到了这里,说明在从右往左扫描的时候,遇到了比基准值小的数值,所以开始从左向右扫描
L++;
}
arr[R] = arr[L]; // 到了这步,说明在左边遇到一个比基准值大的元素,所以要将其值放到右边
}
arr[L] = pivot; //此时L=R,所以将pivot放到基准位置,这样的话,0 ~ L-1 的元素都比pivot小, L+1 ~ right 的元素都比pivot大。
printf("第%d次排序:\n", i++);
print(arr, right-left);
return L;
}
/*
*函数名:快速排序
*函数参数:数组名arr,数组长度len
*思路:核心就是在算法中不断调用 寻找基准元素值下标 的函数,然后在根据 基准元素值下标值,将数组进行划分,再将划分之后的数组传入快速排序算法
* 在调用 寻找基准元素值下标 函数时,不仅会返回基准元素值下标,而且也会对数组中的元素进行划分,不断根据基准值进行数组划分,而且用的都是同一个数组,所以每次
* 快速排序的结果都会在同一个数组中体现,只不过每次传入的不是整个数组,而是数组的一部分,这就是分治思想。
*/
void Quick_Sort(int* arr, int left, int right)
{
if (left < right) {
int pivot_index = Find_Pivot_Index(arr, left, right);
Quick_Sort(arr, left, pivot_index - 1);
Quick_Sort(arr, pivot_index + 1, right);
}
}
测试
int main(void)
{
int arr[10] = { 2,96,8,5,6,4,3,1,7,25 };
printf("原始数组:\n");
print(arr, 10);
Bubble_Sort(arr, 10); //冒泡排序
//Select_Sort(arr, 10); //选择排序
//Insert_Sort(arr, 10);//插入排序
//Quick_Sort(arr, 0, 9);//快速排序
printf("排序结束:\n");
print(arr, 10);
return 0;
}
算法复杂度
| 时间复杂度 | 空间复杂度 | 稳定性 | 算法 | |
| 最情况 平均情况 最坏情况 |
O(n) O(n^2) O(n^2) | O(1) | 稳定 | 冒泡 |
|
O(n^2) O(n^2) O(n^2) | O(1) | 不稳定 | 选择 | |
|
O(n) O(n^2) O(n^2) | O(1) | 稳定 | 插入 | |
|
O(n *log n) O(n *log n) O(n^2) | O(log n) | 不稳定 | 快速 |
概念讲解:
时间复杂度:算法执行过程中总的基本操作次数
空间复杂度:算法执行过程所需要的额外存储空间
算法稳定性:排序前后两个相等的数相对位置不变,则算法稳定。
查找算法
1.顺序查找
/*
*函数名:顺序查找
* 思路:从前往后依次查找,需要查找的值,最后返回该值的下标
*/
int Sequential_Search(int* arr,int target_value,int len)
{
int i = 0;
while (i < len) {
if (arr[i] == target_value)return i + 1;
++i;
}
return 0;
}
2.折半查找
/*
*前提:所传入的数组必须是有序的
*非递归实现
*/
int Binary_Search(int* arr, int low, int high, int target_vale)
{
int mid;
while (low <= high) {
mid = low + (high - low) / 2;
if (arr[mid] == target_vale) return mid + 1;
else if (arr[mid] > target_vale) {
high = mid - 1;
}
else {
low = mid + 1;
}
}
}
/*
*递归实现
*/
int Binary_Search1(int* arr, int low, int high,int target_vale)
{
if (low > high)return -1;
int mid = low + (high - low) / 2;
if (arr[mid] == target_vale)return mid+1;
if (low <= high) {
if (arr[mid] > target_vale) {
high = mid - 1;
return Binary_Search(arr, low, high, target_vale);
}
else if (arr[mid] < target_vale) {
low = mid + 1;
return Binary_Search(arr, low, high, target_vale);
}
}
}
字符操作相关算法
1.复制字符串
//字符串复制函数
void Str_copy(char* DesStr, const char* SrcStr) {
while (*DesStr++ = *SrcStr++);
*DesStr = '\0';

11万+






