排序算法(二)

来源:互联网 发布:java生成uml类图 编辑:程序博客网 时间:2024/05/20 13:15

归并排序

基本思想:

归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

归并排序示例:



算法实现

void merge(int *arr,int *store,int start,int mid,int end){int i,j,k;for(i = start,k = start,j = mid +1; i <= mid && j <= end;k++)if(arr[i] < arr[j])store[k] = arr[i++];elsestore[k] = arr[j++];while(i <= mid)store[k++] = arr[i++];while(j <= end)store[k++] = arr[j++];}void merge_sort(int *arr, int *store, int size){int *temp,*src = arr;int i=0,len=1,mid,flag = 0;printf("merge sort before:\n");print(arr,size);printf("merge sort after:\n");while(len < size){mid = len;len = 2 * mid;i = 0;while(i + len < size){  //等长子表合并merge(src,store,i,i + mid - 1,i + len -1);i = i + len;}if(i + mid < size){  //不等长子表合并merge(src,store,i,i + mid - 1, size -1);}temp = src;// 将src指针指向store数组,src = store;//下次排序就将store数组作为了要排序的数组,store = temp;//arr数组就作为存储结果的数组。 //这样就可以避免不停地重复赋值数组,提高排序效率flag++;//记录归并的次数,若是为偶数次,则说明结果//存储在arr数组里面,这时应该将结果赋值到store数组里。}printf("flag = %d\n",flag);if(flag % 2 == 0){for( i = 0; i < size; i++)store[i] = arr[i];print(store,size);}}




快速排序

基本思想:

1)选择一个基准元素,通常选择第一个元素或者最后一个元素,

2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。

3)此时基准元素在其排好序后的正确位置

4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。

快速排序的示例:




算法实现

int partition(int *arr, int start, int end){int value = arr[start];while(start < end){while(start < end && arr[end] >= value)end--;arr[start] = arr[end];while(start < end && arr[start] <= value)start++;arr[end] = arr[start];}arr[start] = value;return start;}



递归实现

void quick_sort(int *arr, int start, int end){int pos;if(start < end){pos = partition(arr,start,end);quick_sort(arr,start,pos - 1);quick_sort(arr,pos + 1,end);}}



非递归实现

void quick_sort(int *arr, int start, int end){int mystack[32];//自定义一个栈int top = -1;mystack[++top] = start;//起始点入栈mystack[++top] = end;//终止点入栈int  i,j,value;while(top > 0){j = end = mystack[top--];i = start = mystack[top--];value = arr[start];//选取第一个元素为哨兵while( i < j){while(i<j && arr[j] >= value)j--;arr[i] = arr[j];while(i<j && arr[i] <= value)i++;arr[j] = arr[i];}arr[i] = value;//得到哨兵的位置if(end - i > 1){//哨兵位置右侧多于一个元素,则说明还需要排序mystack[++top] = i + 1;//起始点、终止点入栈mystack[++top] = end;}if(i - start > 1){//同理mystack[++top] = start;mystack[++top] = i - 1;}}}








0 0