**因为这边九个函数我都是写在一个文件里边的所以有main1()、main2()、main3(),你想执行那个就把那个的主函数改成main(),因为一个程序只能有一个main()函数;
#include <stdio.h>
//交换函数;
void swap(int a[],int i,int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
//打印函数
void printA(int *a,int len)
{
int i;
for(i = 0;i < len; i++)
{
printf("%4d",a[i]);
}
printf("\n");
}
//1、冒泡排序
//核心思想:依次比较相邻的两个数,将小数放在前面,大数放在后面。即首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。重复以上过程,仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再大于第2个数),将小数放前,大数放后,一直比较到最小数前的一对相邻数,将小数放前,大数放后,第二趟结束,在倒数第二个数中得到一个新的最小数。如此下去,直至最终完成排序。
int main1()
{
int a[10] = {0,1,2,3,4,5,6,7,8,9};
int len = sizeof(a)/sizeof(a[0]);
int i,j;
for(i = 0;i < len-1;i++)
{
for(j = 0;j < len-1-j;j++)
{
if(a[j] > a[j+1])
{
swap(a,j,j+1);
}
}
}
printA(a,len);
return 0;
}
//2、鸡尾酒排序(基于冒泡)
//核心思想:因为是基于冒泡排序的,所以核心思想和冒泡排序差不多,但是与冒泡排序的不同处在于排序时是以双向在序列中进行排序,从低到高然后从高到低
int main9()
{
int a[10] = {0,1,2,3,4,5,6,7,8,9};
int len = sizeof(a)/sizeof(a[0]);
int left =0;
int rigtt = len-1;
int i;
while(left < rigtt)
{
for(i = left;i < rigtt;i++)
{
if(a[i] > a[i+1])
{
swap(a,i,i+1);
}
}
rigtt --;
for(i = rigtt;i > left;i--)
{
if(a[i-1] > a[i])
{
swap(a,i-1,i);
}
}
left++;
}
printA(a,len);
return 0;
}
//3、选择排序
//核心思想:每一趟排序从序列中未排好序的那些元素中选择一个值最小的元素,然后将其与这些未排好序的元素的第一个元素交换位置。
int main2()
{
int i,j;
int min;
int a[10] = {0,1,2,3,4,5,6,7,8,9};
int len = sizeof(a)/sizeof(a[0]);
for(i = 0;i < len-1;i++)
{
min = i;
for(j = i+1;j < len;j++)
{
if(a[min] > a[j])
{
min = j; //找到的下标为j的元素的值比下标为i的元素的值小,所以把下标j赋给min;
}
}
if(a[min] < a[i])//也可写成if(min != i);
{
swap(a,min,i);
}
}
printA(a,len);
return 0;
}
//4、插入排序
//核心思想:每次将一个待排序的数据元素(下标为i),插入到前面已经排好序的数列中的适当位置,使数列依然有序;直到待排序数据元素全部插入完为止。
int main3()
{
int get;
int i,j;
int a[10] = {9,8,7,6,5,4,3,2,1,0};
int len =sizeof(a)/sizeof(a[0]);
for(i = 1;i < len;i++)
{
get = a[i];//获取一个元素;
j = i-1; //往前遍历找到比他get小的元素;
while(j >= 0 && a[j] > get)
{
a[j+1] = a[j]; //get插入到比他小的元素之后,那数组的中此时get之后的数据往后移动一位
j--;
}
a[j+1] = get; //找到之后把get放在比他小的元素后面;
}
printA(a,len);
return 0;
}
//5、二分插入排序
//核心思想:基于插入排序,每次插入时都在一个已经已排序的序列中进行插入,每次将一个待排序的数据元素,插入到前面已经排好序的数列中的适当位置,使数列依然有序;直到待排序数据元素全部插入完为止。
int main4()
{
int a[10] = {0,9,8,7,6,5,4,3,2,1};
int len = sizeof(a)/sizeof(a[0]);
int i,j,left,right,mid,get;
for(i = 1;i < len;i++)
{
left = 0;
right = i-1;
get = a[i];
while(left <= right)
{
mid = (left+right)/2;
if(a[mid] > get)
{
right = mid - 1; //get小于下标mid元素,所以插入到下标mid元素左边
}
else
left = mid + 1;
} //这个循环结束的时候已经找到了需要插入元素的位置;
for(j = i-1;j >= left;j--)
{
a[j+1] = a[j]; //插入之后,他之后的元素需要往后移动;
}
a[left] = get;
}
printA(a,len);
return 0;
}
//6、希尔排序
//核心思想: 核心:先将序列分成较多个子序列分别进行排序,再分成较少个子序列分别进行排序,直到最后为一个序列排序。形象的说:比如先分成8个子序分别排序,再4个子序,再 2 个子序,最后 1 个(1个也就是全部序列啦)。
int main5()
{
int a[10] = {0,9,8,7,6,5,4,3,2,1};
int len = sizeof(a)/sizeof(a[0]);
int i,j,get;
int d = len;
do
{
d = d/3 + 1;
for( i = d;i < len;i++ )
{
get = a[i];
j = i - d;
while(j >= 0 && a[j] > get)
{
a[j + d] = a[j];
j = j - d;
}
a[j + d] = get;
}
//a[j + d] = get;
}while(d > 1);
//a[j + d] = get;
printA(a,len);
return 0;
}
//7、堆排序
//核心思想:堆可以视为一颗完全二叉树,本质上他还是数组,知识根据一定的逻辑关系把他视为完全二叉树,堆排序的方法就是建成最大堆,将最大元素也就是根节点(数组第一个元素)和最后一个元素进行交换,最后一个元素在二叉树就可以去掉(二叉树长度len--);对剩余的元素再进行最大堆,再按照上面进行交换;
void heapify(int *a,int i,int len)//建最大堆函数
{
int left = 2 * i + 1;
int right = 2 * i + 2;
int max = i;
if(left < len && a[left] > a[max])
max = left;
if(right < len && a[right] > a[max])
max = right;
if(max != i)
{
swap(a,i,max);
heapify(a,max,len); //调整被交换的节点;
}
}
int main6()
{
int a[10] = {0,9,8,7,6,5,4,3,2,1};
int len = sizeof(a)/sizeof(a[0]);
int i;
for(i = len/2-1;i >= 0;i--) //调用建堆
{
heapify(a,i,len);
}
for(i = len - 1;i > 0;i--) //排序;
{
swap(a,0,i);
len--;
heapify(a,0,len);
}
printA(a,10);
return 0;
}
//8、归并排序
//核心思想:
第一, 分解: 把待排序的 n 个元素的序列分解成两个子序列, 每个子序列包括 n/2 个元素.
第二, 治理: 对每个子序列分别调用归并排序MergeSort, 进行递归操作
第三, 合并: 合并两个排好序的子序列,生成排序结果.
//(1)、归并函数
void merge(int *a,int left,int mid,int right,int *tmp)
{
int i = left;
int j = mid + 1;
int k = 0;
while(i <= mid&& j<= right)
{
if(a[i] < a[j])
tmp[k++] = a[i++];
else
tmp[k++] = a[j++];
}
while(i <= mid)
tmp[k++] = a[i++];
while(j <= right)
tmp[k++] = a[j++];
//从tmp 传回来
k = 0;
for(i = left;i <= right;i++)
{
a[i] = tmp[k++];
}
}
//(2)、排序
void mergeSort(int *a,int left,int right,int *tmp)
{
if(left >= right)
return ;
int mid = (left+right)/2;
mergeSort(a,left,mid,tmp);//左边部分排序
mergeSort(a,mid+1,right,tmp);//右边部分
merge(a,left,mid,right,tmp);
}
int main7()
{
int a[10] = {0,9,8,7,6,5,4,3,2,1};
int len = sizeof(a)/sizeof(a[0]);
int tmp[10];
mergeSort(a,0,len-1,tmp);
printA(a,len);
return 0;
}
//9、快速排序
//核心思想:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
//(1)、分区操作(找到基准值的下标)
int partition(int *a,int left,int right)
{
int pivot = a[right];
int index = left;
int i;
for(i = left;i < right;i++)
{
if(a[i] < pivot)
{
swap(a,i,index);
index++;
}
}
swap(a,index,right);
return index;
}
//(2)、排序
void qsort(int *a,int left ,int right)
{
if(left < right)
{
int pivot = partition(a,left,right);
qsort(a,left,pivot-1);
qsort(a,pivot+1,right);
}
}
int main()
{
int a[10] = {0,9,8,7,6,5,4,3,2,1};
int len = sizeof(a)/sizeof(a[0]);
qsort(a,0,len-1);
printA(a,len);
return 0;
}