一、排序算法
1、冒泡排序
- 思路:按照约定的排序顺序,两两比较相邻的数据,如果反序则交换,直到没有反序的记录为止。
- 算法复杂度:O(n^2)
- 比较次数:(1 + 2 + 3 +…+ n-1) = n * (n – 1) / 2 次
/*************************************************************************
> File Name: bubble.c
> Author: mrhjlong
> Mail: mrhjlong@163.com
> Created Time: 2016年04月16日 星期六 09时21分25秒
************************************************************************/
#include<stdio.h>
#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))
//冒泡排序
void bubbleSort(int a[], int len)
{
int i, j;
int temp;
int flag = 1;
#if 1
//从前往后排
for(i = 0; i < len - 1; i++)
{
flag = 1;
for(j = 0; j < len - 1 - i; j++)
{
if(a[j] > a[j + 1])
{
flag = 0;
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
if(1 == flag)
{
break;
}
}
#else
//从后往前排
for(i = 0; i < len - 1; i++)
{
flag = 1;
for(j = len - 1; j > i; j--)
{
if(a[j] < a[j - 1])
{
flag = 0;
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
if(1 == flag)
{
break;
}
}
#endif
}
int main()
{
int a[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
int i;
//冒泡排序
bubbleSort(a, ARRAYSIZE(a));
for(i = 0; i < ARRAYSIZE(a); i++)
{
printf("%d\n", a[i]);
}
return 0;
}
2、归并排序
- 思路:假设初始序列含有n 个记录,则可以看成是n 个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2 个长度为2 或1 的有序序列;再两两归并,…,如此重复,直至得到一个长度为n 的有序序列,操作步骤如下:
1、将所要进行排序的序列分为左右两部分,如果如果要进行排序的序列起始元素下标为left,最后一个元素的下标为right,那么左右两部分的临界点下标为mid = (left + right) /2。
2、将上面所得的两部分序列继续按照步骤1 进行划分,直到划分的区间长度为1。
3、将划分结束后的序列进行归并排序,排序方法为对所分的n 个子序列进行两两合并,得到 n/2 或n/2+1个含有两个元素的子序列,再对得到的子序列进行合并,直至得到 一个长度为n 的有序序列。 - 算法复杂度:O(nlogn)
- 分析:每一次排序,都要将n 个数据扫描一遍,耗费O(n)的时间,由于归并一共要进行log2(n)次,所以最终时间为nlogn。
/*************************************************************************
> File Name: mergeSort.c
> Author: mrhjlong
> Mail: mrhjlong@163.com
> Created Time: 2016年04月16日 星期六 10时31分06秒
************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))
static void merge(int a[], int left, int right)
{
int mid = (left + right) / 2;
int i = left;
int j = mid + 1;
int k = 0;
int *temp = (int *)malloc(sizeof(int) * (right - left + 2));
assert(temp);
while(i < mid + 1 || j < right + 1)
{
if(i < mid + 1 && j < right + 1)
{
if(a[i] < a[j])
{
temp[k] = a[i];
k++;
i++;
}
else
{
temp[k] = a[j];
k++;
j++;
}
}
else if(i < mid + 1)
{
temp[k] = a[i];
k++;
i++;
}
else
{
temp[k] = a[j];
k++;
j++;
}
}
i = 0;
for(j = left; j < right + 1; j++)
{
a[j] = temp[i];
i++;
}
free(temp);
}
void mergeSort(int a[], int left, int right)
{
int mid = 0;
if(left == right)
{
return;
}
else
{
mid = (left + right) / 2;
mergeSort(a, left, mid);
mergeSort(a, mid + 1, right);
merge(a, left, right);
}
}
int main()
{
int a[] = {1, 34, 95, 74, 6, 24, 4, 36, 83, 10};
int i = 0;
//归并排序
mergeSort(a, 0, ARRAYSIZE(a) - 1);
for(i = 0; i < ARRAYSIZE(a); i++)
{
printf("%d\n", a[i]);
}
return 0;
}
3、选择排序
- 思路:每次从数据中选出一个最大值或最小值放在序列的起始位置,直到全部待排序的数据元素排序完。
- 算法特点:交换移动数据的次数少,节约时间。
- 算法复杂度:O(n^2)
- 比较次数:无论最好最坏,都需要比较(1 + 2 + 3 +…+ n-1) = n * (n – 1) / 2 次
/*************************************************************************
> File Name: selectSort.c
> Author: mrhjlong
> Mail: mrhjlong@163.com
> Created Time: 2016年04月16日 星期六 10时11分14秒
************************************************************************/
#include<stdio.h>
#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))
void selectSort(int a[], int len)
{
int i, j;
int min, temp;
for(i = 0; i < len - 1; i++)
{
min = i;
for(j = i + 1; j < len; j++)
{
if(a[j] < a[min])
{
min = j;
}
}
if(min != i)
{
temp = a[min];
a[min] = a[i];
a[i] = temp;
}
}
}
int main()
{
int a[] = {1, 3 ,5, 7, 9, 2, 4, 6, 8, 10};
int i;
//选择排序
selectSort(a, ARRAYSIZE(a));
for(i = 0; i < ARRAYSIZE(a); i++)
{
printf("%d\n", a[i]);
}
return 0;
}
4、插入排序
- 思路:每次从数据中选出一个数据插入到已经排好序的有序表中,从而得到一个新的,记录数增加1 的有序表(类比打扑克中一边摸牌,一边理牌的过程)。
- 算法复杂度:O(n^2)
- 比较次数:最好时,比较n-1 次;最坏时,比较2 + 3 +…+n = (n + 2)(n - 1)/2 次
/*************************************************************************
> File Name: insertSort.c
> Author: mrhjlong
> Mail: mrhjlong@163.com
> Created Time: 2016年04月16日 星期六 10时31分06秒
************************************************************************/
#include<stdio.h>
#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))
void insertSort(int a[], int len)
{
int i, j;
int temp, point;
for(i = 1; i < len; i++)
{
point = i;
for(j = i - 1; j >= 0; j--)
{
if(a[j] > a[point])
{
temp = a[j];
a[j] = a[point];
a[point] = temp;
point = j;
continue;
}
break;
}
}
}
int main()
{
int a[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
int i;
//插入排序
insertSort(a, ARRAYSIZE(a));
for(i = 0; i < ARRAYSIZE(a); i++)
{
printf("%d\n", a[i]);
}
return 0;
}
5、简单排序
- 思路:按照(从小到大或从大到小)的排序顺序,两两比较所有的数据,如果反序则交换 位置,直到比较完所有的数据。
- 算法复杂度:O(n^2)
- 比较次数:(1 + 2 + 3 +…+ n-1) = n * (n – 1) / 2
/*************************************************************************
> File Name: simpleSort.c
> Author: mrhjlong
> Mail: mrhjlong@163.com
> Created Time: 2016年04月16日 星期六 17时01分46秒
************************************************************************/
#include<stdio.h>
void simpleSort(int a[], int len)
{
int i, j;
int temp;
for(i = 0; i < len; i++)
{
for(j = i + 1; j < len; j++)
{
if(a[i] > a[j])
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
int main()
{
int a[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
int i = 0;
//简单排序
simpleSort(a, 10);
for(i = 0; i < 10; i++)
{
printf("%d\n", a[i]);
}
return 0;
}
二、查找算法
1、二分查找(循环、递归)
二分查找也称折半查找,其优点是速度快,缺点是要求数据必须是有序列序列。
/*************************************************************************
> File Name: binarySearch.c
> Author: mrhjlong
> Mail: mrhjlong@163.com
> Created Time: 2016年04月16日 星期六 14时27分57秒
************************************************************************/
#include<stdio.h>
//循环形式的二分查找
//int binarySearchByLoop(int a[], int n, int key)
//{
// int low = 0;
// int high = n - 1;
//
// while(low <= high)
// {
// int mid = (low + high) / 2;
//
// if(a[mid] == key)
// {
// return mid;
// }
// else if(a[mid] < key)
// {
// low = mid + 1;
// }
// else
// {
// high = mid - 1;
// }
// }
// return -1;
//}
//递归形式的二分查找
int binarySearch(int a[], int left, int right, int key)
{
if(left > right)
return -1;
int mid = (left + right) / 2;
if(a[mid] > key)
{
return binarySearch(a, left, mid - 1, key);
}
else if(a[mid] < key)
{
return binarySearch(a, mid + 1, right, key);
}
else
{
return mid;
}
}
int main()
{
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int i = binarySearch(a, 0, 9, 9);
printf("%d\n", i);
return 0;
}
2、简单查找
/*************************************************************************
> File Name: simpleSearch.c
> Author: mrhjlong
> Mail: mrhjlong@163.com
> Created Time: 2016年04月16日 星期六 17时19分47秒
************************************************************************/
#include<stdio.h>
int simpleSearch(int a[], int left, int right,int key)
{
int i;
for(i = left; i < right + 1; i++)
{
if(a[i] == key)
{
return i;
}
}
return -1;
}
int main()
{
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int i = simpleSearch(a, 0, 9, 10);
printf("%d\n", i);
return 0;
}