写几个基础的算法,虽然很基础,但要是让我毫无准备立马写下还真写不顺畅,加上面试时候的紧张气氛,立马嗝屁。
1.插入排序
基本思想是将一个为排序元素插入到已排序的一系列元素中,关键点:1.找到元素应该处在的位置 2.插入元素
sorted1 sorted2 sorted3 ........ undeter
用链表实现会好一些,因为使用数组需要先移动一堆元素再插入,而链表直接插入即可,不过在C语言里使用链表得自己定义其实现和操作,比较麻烦(其实是我不大会),为了保护自己脆弱的自信心,这里就先简单用数组实现看看(实现递增排序)。
void insertion_sort( int a[], int length ) /*length为数组长度*/
{
int i, j, key;
for( i = 1; i < length; i++ ) /*将第一个元素a[0]视为已排序,因此从a[1]开始插入*/
{
key = a[i]; /*a[i]为待插入的元素*/
j = i - 1;
while( j >= 0 && a[j] > key ) /*向左找到第一个小于a[i]元素的位置*/
{
a[ j + 1 ] = a[j]; /*将大于a[i]的元素都向右移一位*/
j--;
}
a[ j + 1 ] = key; /*将a[i]的值插入到正确位置,位置j为第一个小于a[i]的元素*/
}
}
时间复杂度:O(n^2)
2.冒泡排序
基本思路是:每次比较相邻的两个数,小的在左,大的在右,最终每轮比较都得到一个最大的数。
假设数组长度为len,那么最大的数就要放在a[len - 1], 第二大的数放在a[len - 2],以此类推。因此外层循环就是要从len-1~0,每次循环都得到一个最大的数。
void bubble_sort( int a[], int length )
{
int i, j;
for( i = length - 1; i > 0; i-- )
{
for( j = 0; j < i; j++ ) /*内循环比较相邻的两个数*/
{
if( a[j + 1] < a[j] )
swap( a, j, j + 1 ); /*自己定义一个元素交换函数*/
}
}
}
时间复杂度:O(n^2)
3.归并排序
基本思想:每个递归过程都对已排序的两个数组进行合并,在合并的过程中完成排序操作。
具体实现:
void merge( int a[], int start, int mid, int end ) /*先定义合并函数,作用是将数组中已排序的左右两部分按顺序合并*/
{
int n1 = mid - start + 1;
int n2 = end - mid;
int left[100], right[100]; /*这里如果用left[n1], right[n2]定义的话会报错,所以就用了固定长度的数组*/
int i, j, k;
for( i = 0; i < n1; i++ )
left[i] = a[start + i];
for( j = 0; j < n2; j++ )
right[j] = a[mid + 1 + j];
i = 0;
j = 0;
for( k = start; i < n1 && j < n2; ++k )
{
if( left[i] < right[j] )
{
a[k] = left[i];
++i;
}
else
{
a[k] = right[j];
++j;
}
}
if( i < n1 )
for( ; i < n1; i++ )
{
a[k] = left[i];
++k;
}
if( j < n2 )
for( ; j < n2; ++j )
{
a[k] = right[j];
++k;
}
}
void merge_sort( int a[], int start, int end ) /*start与end分别为起始和终止位置*/
{
int mid;
if( start < end )
{
mid = ( start + end ) / 2;
merge_sort( a, start, mid ); /*对左半部分进行排序*/
merge_sort( a, mid + 1, end ); /*对右半部分进行排序*/
merge( a, start, mid, end ); /*合并两个排序的部分*/
}
}
时间复杂度为O(nlogn)