排序整理

来源:互联网 发布:同济大学软件学院电话 编辑:程序博客网 时间:2024/06/10 00:33

**因为这边九个函数我都是写在一个文件里边的所以有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;

}

原创粉丝点击