各种排序算法

void shellsort(int a[],int n) { for(int d=n/2;d>=1;d=d/2) { for(int i=d;i<n;i++) //将a[i]插入到所属组的有序列段中 { int temp = a[i]; int j=i-d; while( j>=0 && temp<a[j]) { a[j+d]=a[j]; j=j-d; } a[j+d]=temp; } } }

以上是shell排序

void BubbleSort(int a[],int n) { for (int i=n-1;i>=1;i--)//这么写for比较易理解 //for (int i=1;i<n;i++) { // for (int j=0;j<=i-1;j++) for (int j=i-1;j>=0;j--)//这么写for更好理解 if(a[j] >a [j+1]) { int temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; } } }

以上是冒泡排序

执行过程:
假设一个数组有n个元素,从数组的最左边开始,比较0号位置和1号位置元素的大小。如果0号元素大,就让两个元素交换。如果1号元素大,就什么也不做。然后右移一位,比较1号位置和2号位置元素的大小,和刚才一样,如果1号元素大,则交换。照这样依次比较下去,一直到数组的最右端。最大的元素已经被排在最右边了。因为在算法执行的时候,最大的数据项总是“冒泡”到数组的顶端,所以叫做冒泡排序。现在重新回到数组的最左端开始第二趟排序,过程与第一趟一样,只是不需要比较最后一个元素,它已经是最大的了。不断执行这个过程,知道所有的元素都排定。

void BubbleSort (int* a,int n) { for (int i=n;i>1;i--) { int exchange=0; for (int j=0;j<=i-1;j++) { if (a[j]>a[j+1]) { int temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; exchange=1; } if (exchange==0) break; } } }

以上是改进后的冒泡排序算法

void insertsort (int a[], int n) { for (i=1; i<n; i++) //需要n-1趟,此时数组其实是从1开始而不是0, { int temp = a[i]; int j=i; while (temp<a[j-1]) //搜索插入位置 { a[j]=a[j-1]; j--; } a[j]=temp; // 将原a[i]中的记录放入第j+1个位置 } }

以上是直接插入法排序

插入排序仍然需要O(N*N)的时间,但是在一般情况下,它要比冒泡排序快一倍,比选择排序还要快一点。

其过程是这样的:
假设数组有一部分元素已经排好了,此时有一个标记元素,在这个元素左边的所有元素已经是局部有序的了。这就是说这个元素的左边的那些数据项是按顺序排列的。然而这些数据项在数组中最终的位置并没有确定,因为当没有被排过序的元素要插入到他们中间时,他们的位置还要发生变动。局部有序在冒泡排序和选择排序中是不会出现的。现在将局部有序中最大的元素移动到标记元素所在的位置,次大的元素移动到原来最大元素所在的位置,依次类推。当把最后一个比标记元素还大的元素移动之后,移动过程停止,此时移位空出的位置,就是标记元素应该插入的位置。然后将标记右移一个位置,重复前面的过程,知道所有未排序的元素插入到局部有序列中合适的位置。

void QuickSort(int a[],int first,int end ) { int i=first; int j=end; int temp=a[i]; //初始化 while(i<j) { while (i<j && temp<= a[j]) j--; a[i]=a[j]; while (i<j && a[i]<=temp) i++; a[j]=a[i]; } a[i]=temp; if (first<i-1) QuickSort(a, first, i-1); //对左侧分区域进行快速排序 if (i+1<end) QuickSort(a, i+1, end); //对右侧分区域进行快速排序 }

以上是快速排序

快速排序是最流行的排序算法,在大多数情况下,快速排序都是最快的,执行时间为O(N*logN)级。快速排序在本质上通过把一个数组划分为两个子数组,然后递归地调用自身为每一个子数组进行快速排序来实现的。
划分数组需要选择一个数据项作为枢纽,使得划分后左边子数组的数据项都小于枢纽,右边子数组的数据项都大于枢纽。为了简便可以选择数组最右端的数据项作为枢纽,划分完成之后,枢纽被插入到左右子数组之间的分界处,那么枢纽就落在排序之后的最终位置上了。选择最右端的数据项作为枢纽有时会使排序的效率低下,“三数据项取中”即选择第一个,最后一个以及中间位置数据项的中值作为枢纽更合适一些。

void SelectSort(int a[],int n) { for(int i=0;i<n;i++) { int min=i; for(int j=i+1;j<n;j++) { if(a[j]<a[min]) min=j; if(min!=i) { int temp =a[i]; a[i]=a[min]; a[min]=temp; } } } }

以这是简单选择法排序


选择排序改进了冒泡排序,将必要的交换次数从O(N*N)减少到O(N)。不过比较次数还是O(N*N)。然而,选择排序仍然为大记录量的排序提出了一个非常重要的改进,因为这些大量的记录需要在内存中移动,这就使得交换时间比起比较时间来更为重要。

其过程如下:
将数组中所有的数据项扫描一趟,从中选出最小的一个。最小的和数组的0号元素交换位置。现在最左端的数据项就是有序的了。再次扫描数组,从1号位置开始,还是找最小的,然后和1号位置的元素交换。这个过程持续到所有数据项排定。

void merge(int array[], int p, int q, int r) { int i,k; int begin1,end1,begin2,end2; int* temp = new int [r-p+1]; //申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 ,因长度事先未定,由函数参数r p定,故不能从栈分配,只能用new。 begin1= p; end1 = q; //设定两个指针,最初位置分别为两个已经排序序列的起始位置 begin2 = q+1; end2 = r; k = 0; while((begin1 <= end1)&&( begin2 <= end2)) //比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 { if(array[begin1]<array[begin2]) { temp[k] = array[begin1]; begin1++; } else { temp[k] = array[begin2]; begin2++; } k++; } while(begin1<=end1) //若第一个序列有剩余,直接拷贝出来粘到合并序列尾 { temp[k++] = array[begin1++]; } while(begin2<=end2) //若第二个序列有剩余,直接拷贝出来粘到合并序列尾 { temp[k++] = array[begin2++]; } for (i = 0; i < (r - p +1); i++) //将排序好的序列拷贝回数组中 array[p+i] = temp[i]; delete[] temp; } void MergeSort(int array[], unsigned int first, unsigned int last) { int mid = 0; if(first<last) { mid = (first+last)/2; MergeSort(array, first, mid); MergeSort(array, mid+1,last); merge(array,first,mid,last); } }

以上是归并排序。

#include <stdlib.h> #include <time.h> #define MAX 10 #define SWAP(x,y){int t; t = x; x = y; y = t;} void CreateHeap(int[]); void HeapSort(int[]); int main(void) { int number[MAX+1] = {-1}; int i, num; srand(time(NULL)); printf("排序前:"); for(i = 1; i <= MAX; i++) { number[i] = rand() % 100; printf("%d ", number[i]); } printf("/n建立堆積樹:"); CreateHeap(number); for(i = 1; i <= MAX; i++) printf("%d ", number[i]); printf("/n"); HeapSort(number); printf("/n"); return 0; } void CreateHeap(int number[]) { int i, s, p; int heap[MAX+1] = {-1}; for(i = 1; i <= MAX; i++) { heap[i] = number[i]; s = i; p = i / 2; while(s >= 2 && heap[p] > heap[s]) { SWAP(heap[p], heap[s]); s = p; p = s / 2; } } for(i = 1; i <= MAX; i++) number[i] = heap[i]; } void HeapSort(int number[]) { int i, m, p, s; m = MAX; while(m > 1) { SWAP(number[1], number[m]); m--; p = 1; s = 2 * p; while(s <= m) { if(s < m && number[s+1] < number[s]) s++; if(number[p] <= number[s]) break; SWAP(number[p], number[s]); p = s; s = 2 * p; } printf("/n排序中:"); for(i = MAX; i > 0; i--) printf("%d ", number[i]); } }

以上为堆排序的非递归算法。

int parent(int i) //父結點 { return (int)floor(i/2); } int left(int i) //左子結點 { return 2*i; } int right(int i)//右子結點 { return 2*i+1; } //單一子結點最大堆積樹調整 void MaxHeapify(int A[],int i,int n) { int l=left(i); int r=right(i); int largest; int temp; if(l<n&&A[l]>A[i]) { largest=l; } else { largest=i; } if(r<n&&A[r]>A[largest]) { largest=r; } if(largest!=i) { temp=A[i]; A[i]=A[largest]; A[largest]=temp; MaxHeapify(A,largest,n); } } //建立最大堆積樹 void BuildMaxHeap(int A[],int n) { for(int i=n;i>=0;i--) { MaxHeapify(A,i,n); } } //堆積排序程式碼 void HeapSort(int A[],int n) { BuildMaxHeap(A,n); int temp; for(int i=n-1;i>=1;i--) { temp=A[0]; A[0]=A[i]; A[i]=temp; n--; MaxHeapify(A,0,n); } }

以上为堆排序的递归算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值