刚接触排序时感觉排序非常的复杂,排序所用到的循环嵌套、函数递归调用都不容易理解,所以我把以前写过的排序程序做的总结,写在一个程序中,便于比较和以后温习。
算法描述:下面是我对每一种算法的理解(从小到大排序)
(1)冒泡排序:
n个数进行排序,从第一个数开始两两比较,较大的数在后面,n-1比较后最大的数就到了最后一位,排除最后一位,重复这个过程。
(2)选择排序:
n个数进行排序,选择第一个数与后面的数依次比较,较小的数放在第一个位置上,比较n-1次后,第一个位置上是最小的数,排除第一个数,重复该过程。
(3)插入排序:
从第一个元素开始,这个元素可以认为已经被排序,取出下一个元素,在已经排序的元素序列中从后向前扫描,如果该元素(已排序)大于新元素,将该元素移到下一位置,直到找到一个位置使序列有序,重复上述步骤。
(4)希尔排序:
希尔排序是插入排序的进化版,适合大量数据的排序。首先取一个整数增量d1,将要排序的数分为d1个组,所以距离为d1的数放在同一组中,组内进行插入排序。再取第二个增量d2小于d1,重复上述分组排序步骤,知道增量为1,再进行插入排序。
(5)堆排序:
堆排序是对选择排序的改进,使用树结构记录选择排序的过程,其中的关键是构造大顶堆。首先将所有元素构造成一个大顶堆,将第一个元素与最后一个元素调换,排除最后一个元素,再次构造大顶堆,重复该过程。
(6)归并排序:
递归实现:把长度为n的输入序列分成两个长度为n/2的子序列,对这两个子序列分别采用归并排序,将两个排序好的子序列合并成一个最终的排序序列。
非递归实现:首先进行是两两归并,然后四四归并,然后是八八归并,一直下去直到归并了整个数组。
(7)快速排序:
从数列中挑出一个元素,称为 “基准”(pivot),重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面,递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。
代码实现:
#include <stdio.h>
#include <time.h>
#define MAX 10
typedef char ElementType;
typedef ElementType ARR[MAX]; //ARR = ElementType [MAX]
int len = sizeof(ARR) / sizeof(ElementType);
void swap(ARR arr,int i,int j);
void print(ARR arr);
void bubble1(ARR arr);//冒泡排序
void bubble2(ARR arr);//冒泡排序改进
void select (ARR arr);//选择排序
void insert (ARR arr);//插入排序
void shell (ARR arr);//希尔排序
void heap (ARR arr);//堆排序
void heapadjust(ARR arr,int i,int m);
void Merging1(ARR arr,int left,int right);//归并排序
void Merging2(ARR arr,int left,int right);
void Merge(ARR arr,int left,int mid,int right);
void Quick (ARR arr,int low,int high); //快速排序
int pivotkey1(ARR arr,int low,int high);
int pivotkey2(ARR arr,int low,int high);
ElementType getpivot(ARR arr,int low,int high);
void Qsort(ARR arr,int low,int high);
int main()
{
ARR arr1={10,9,8,7,6,5,4,3,2,1};
ARR arr2={10,1,2,3,4,5,6,7,8,9};
ARR arr3={0,9,8,5,3,1,4,7,2,6};
// printf("bubble1 :\n");
// bubble1(arr1);
//
// printf("bubble1 :\n");
// bubble2(arr1);
//
// printf("select :\n");
// select(arr1);
//
// printf("insert :\n");
// insert(arr3);
//
// printf("shell :\n");
// shell(arr3);
//
// printf("heap :\n");
// heap(arr3);
// printf("Merging1 :\n");
// Merging1(arr1,0,9);
// printf("Merging2 :\n");
// Merging2(arr1,0,9);
printf("Quick :\n");
Quick(arr1,0,9);
return 0;
}
void swap(ARR arr,int i,int j)
{
ElementType temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void print(ARR arr)
{
int i;
for(i = 0;i < len;i++)
{
printf("%3d",arr[i]);
}
printf("\n");
}
void bubble1(ARR arr)
{
int i,j;
for(i = 0;i < len-1;i++)
{
print(arr);
for(j = 0;j < len-1-i;j++)
{
if(arr[j] > arr[j+1])
{
swap(arr,j,j+1);
}
}
}
}
void bubble2(ARR arr)
{
int i,j;
int flag;
for(i = 0;i < len-1;i++)
{
flag = 0;
print(arr);
for(j = 0;j < len-1-i;j++)
{
if(arr[j] > arr[j+1])
{
flag = 1;
swap(arr,j,j+1);
}
}
if(flag == 0)
{
break;
}
}
}
void select (ARR arr)
{
int i,j;
int min;
for(i = 0;i < len-1;i++)
{
min = i;
print(arr);
for(j = i+1;j < len;j++)
{
if(arr[j] < arr[min])
{
min = j;
}
}
if(min != i)
{
swap(arr,i,min);
}
}
}
void insert (ARR arr)
{
int i,j;
ElementType temp;
for(i = 1;i < len;i++)
{
temp = arr[i];
if(arr[i-1] > arr[i])
{
for(j = i-1;j >= 0;j--)
{
if(arr[j] > temp)
{
arr[j+1] = arr[j];
}
else
break;
}
}
arr[j+1] = temp;
print(arr);
}
}
void shell (ARR arr)
{
int i,j;
int increment = len;//定义一个增量;
ElementType temp;
while(increment > 1)
{
increment = increment / 3 + 1;//如此改变增量,最后一个增量一定是1;
printf("%d:\n",increment);
for(i = increment;i < len;i++)
{
if(arr[i] < arr[i - increment])
{
temp = arr[i];
for(j = i - increment;j >= 0 && arr[j] > temp;j -= increment)
{
arr[j + increment] = arr[j]; //这个for循环是用来交换位置的,终止循环时j会
//停在要插入的数处,插入时插向下一个位置;
}
arr[j+increment] = temp;
}
}
print(arr);
}
}
//堆排序
void heap (ARR arr)
{
int i;
ElementType temp;
for(i = len/2;i > 0;i--)
{
heapadjust(arr,i,len);//开始时数组并无顺序,排len/2个结点;
}
for(i = len;i > 1;i--)
{
temp = arr[i];
arr[i] = arr[1]; //交换第一个和排序的最后一个;
arr[1] = temp;
heapadjust(arr,1,i-1);//最后一个脱离排序;
}
print(arr);
}
void heapadjust(ARR arr,int i,int m)
{
int j;
ElementType temp;
temp = arr[i];
for(j = i * 2;j <= m;j *= 2)
{
if(j < m && arr[j] < arr[j+1])
{
++j;
}
if(temp >= arr[j])
break;
arr[i] = arr[j];
i = j;
}
arr[i] = temp;
}
//递归的归并排序
void Merging1(ARR arr,int left,int right)
{
int mid;
if(left == right)
{
return;
}
mid = (left + right) / 2;
Merging1(arr,left,mid);
Merging1(arr,mid+1,right);
Merge(arr,left,mid,right);
}
//非递归的归并排序
void Merging2(ARR arr,int left,int right)
{
int i;
int k = 1;
int len = (right - left + 1);
int mid;
while(k <= len)
{
i = left;
while(i < right -2*k + 1)//why????
{
mid = i + k - 1 ;
Merge(arr,i,mid,i+2*k-1);
i = i + 2*k;
}
if(i < right - k + 1)
Merge(arr,i,i+k-1,right);
k = 2 * k;
print(arr);
}
return;
}
void Merge(ARR arr,int left,int mid,int right)
{
int i = left;
int j = mid + 1;
int len = right - left + 1;
ElementType temp[len];
int k = 0;
while(i <= mid && j <= right)
{
if(arr[i] > arr[j])
temp[k++] = arr[j++];
else
temp[k++] = arr[i++];
}
while(i <= mid)
{
temp[k++] = arr[i++];
}
while(j <= right)
{
temp[k++] = arr[j++];
}
for(i = 0;i < len;i++)
{
arr[i+left] = temp[i];
}
}
//快速排序
void Quick (ARR arr,int low,int high)
{
int pivot;
if(low < high)
{
pivot = pivotkey1(arr,low,high);//pivot = pivotkey2(arr,low,high);
Quick(arr,low,pivot-1);
Quick(arr,pivot+1,high); //pivot处不再参与排序
}
print(arr);
}
int pivotkey1(ARR arr,int low,int high)
{
ElementType pivot;
pivot = getpivot(arr,low,high);
while(low < high)
{
while(low < high && arr[high] > pivot)
{
high--;
}
swap(arr,low,high);
while(low < high && arr[low] < pivot)
{
low++;
}
swap(arr,low,high);
}
return low;
}
int pivotkey2(ARR arr,int low,int high)
{
ElementType pivot;
pivot = arr[low]; //pivot = getpivot(arr,low,high);
int i;
int tail = low + 1;
for(i = low + 1;i <= high;i++)
{
if(arr[i] <= pivot)
swap(arr,i,tail++);
}
swap(arr,low,tail-1);
return tail-1;
}
ElementType getpivot(ARR arr,int low,int high)
{
int mid = (low + high) / 2;
if(arr[low] > arr[high])
swap(arr,low,high);
if(arr[mid] > arr[high])
swap(arr,mid,high);
if(arr[mid] > arr[low])
swap(arr,mid,low);
return arr[low];
}
void Qsort(ARR arr,int low,int high) //改进了Quick函数
{
int pivot;
while(low < high)
{
pivot = pivotkey1(arr,low,high);//pivot = pivotkey2(arr,low,high);
Quick(arr,low,pivot-1);
low = pivot - 1;
}
print(arr);
}