前言:
常见的4种算法也是笔试、面试之中最常问的问题,甚至有些笔试题其实就是这4算法的变种题目:重要的是看清题目本质;
1.冒泡排序:平均复杂度:O(n^2) n~n^2
void maopao( int *list,int n) //list 为传入数组,n为数组中的个数
{
int i,j,temp;
for(i = 0; i<n-1; i++) // n-1的目的,防止排序时越界会出现未知数字进入排序,导致排序结果出问题
for(j = 0; j<n-i-1 ; j++) ///-1目的如上,n-i目的减少多余的排序
{
if(list[j]>list[j+1])
{
temp = list[j]; //交换位置
list[j] = list[j+1];
list[j+1] = temp;
}
}
printf("maopao finish!\n");
}
2.快速排序:平均复杂度:O(nlog n) nlog n~n^2 空间:log n ,以下是使用函数的递归法实现:
int Partition(int *arr,int low,int high)
{
int i = low;
int j = high;
int temp; //用于i和j交换的容器;
int pivotKey = arr[i]; //用于存放基准值的容器;
while(i < j)
{
while( i < j && arr[j] >= pivotKey) //j寻找小于基准值的数
{
j--;
}
while( i < j && arr[i] <= pivotKey) //i寻找大于基准值的数
{
i++;
}
if(i < j) //将i 和 j所找到的数进行交换
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
} // 当i和j相遇时,就是基准的位置;
arr[low] = arr[i];
arr[i] = pivotKey;
return i; //返回基准的位置
}
void QuickSort(int arr[], int low,int high)
{
int pivotpos;
int i;
if(low < high)
{
pivotpos = Partition(arr,low,high); //获得划分区域的基准值
QuickSort(arr,low,pivotpos-1); //将小于基准的左侧区域进行排序
QuickSort(arr,pivotpos+1,high); 将大于基准的左侧区域进行排序
}
}
注:
在本程序中,必须先执行寻小的值,也就是先进行while(.....){j--},否则会导致排序失败,原因是i和j相遇时,如果i指向的值大于基准值,由于先遍历的是i,所以会导致错误的交换.举个例子:13 38 27 -----> 38 13 27
3.选择排序:平均时间复杂度O(n^2) 好坏都是O(n^2) 空间复杂度为O(1)
void selectionSort(int arr[],int length)
{
int i,j;
int minIndex;
int temp;
if( length <= 0 )
{
printf("Error:arr size is NULL\n");
return ;
}
for( i = 0; i < length; i++ ) //遍历整个数组,并且用minIndex容器存放
{
minIndex = i;
for( j = i; j < length ;j++ ) //在i的基础上也遍历整个数组,找比min容器更小的值,并更新容器
{
if( arr[j] < arr[minIndex] )
{
minIndex = j;
}
}
temp = arr[minIndex]; //结束一次j循环后进行交换;
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
4.插入排序:平均时间复杂度:O(n^2) n~n^2 空间复杂度(O(1))
void insertionSort(int arr[],int length)
{
int i;
int current;
int preIndex;
if(length <= 0)
{
printf("Error input length size :%d\n",length);
return ;
}
for( i = 0; i < length -1; i++) //length -1 的目的,由于current是在i的前提加1,因此防止越界
{
current = arr[i+1];
preIndex = i;
while(preIndex >= 0 && current < arr[preIndex]) //跳出条件,preIndex 小于0和找到大于arr[preIndex]的值
{
arr[preIndex + 1] = arr[preIndex]; //交换前半部;
preIndex--;//向后寻找
}
arr[preIndex + 1] = current; //2各功能,1个是自己给自己赋值(右相邻的值比自己大),一个是交换(右值你自己小,进行交换,完成交换后半部)
}
return;
}
以上是4种排序函数体的实现以下是main函数体:
int main (int argc, char **argv)
{
int a[8] = {88,37,97,28,27,45,56,92};
int i=0;
#if 1
QuickSort(a,0,7);
#endif
#if 0
maopao(a,8);
#endif
#if 0
selectionSort(a,8);
#endif
#if 0
insertionSort(a,8);
#endif
for(i = 0;i<8;i++)
{
printf("%d\n",a[i]);
}
return 0;
} /* ----- End of main() ----- */