今天就写个归并排序吧,简单的功能,实现整数排序,没有苛刻的测试用例。表示博客今天开张了
陆陆续续的编写,并参考了shan9liang的文章(http://blog.csdn.net/shan9liang/article/details/7533466)
#include "iostream" using namespace std; #define MAX 2147483647 void merge(int vec[],int low,int mid,int high) { int n1 = mid -low +1; int n2 = high - mid; int* a = new int[n1+1]; int* b = new int[n2+1]; int i,j; for(i=0;i<n1;i++) a[i] = vec[low+i]; for(j=0;j<n2;j++) b[j] = vec[mid+j+1]; a[n1] = MAX; b[n2] = MAX; i = 0; j = 0; for(int k=low;k<=high;k++) { if(a[i]<b[j]) { vec[k] = a[i]; i++; } else { vec[k] = b[j]; j++; } } } void MergeSort(int vec[], int low,int high) { if(low < high) { int mid = (high +low)/2; MergeSort(vec,low,mid); MergeSort(vec,mid+1,high); merge(vec,low,mid,high); } } int main() { int vec[] = {1,3,5,2,4,6}; MergeSort(vec,0,5); for(int i=0;i<6;i++) cout<<vec[i]<<' '; return 0; }
关于排序的大体分类如下图所示:
冒泡排序
(1)基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
(2)实例:
#include "iostream" using namespace std; void BubbleSort(int vec[],int n) { bool Flag = true; for(int i=n-1; i>=1 && Flag; i--) { Flag = false; for(int j=0;j<i;j++) { if(vec[j]>vec[j+1]) { Flag = true; vec[j] = vec[j] ^ vec[j+1]; vec[j+1] = vec[j+1] ^ vec[j]; vec[j] = vec[j] ^ vec[j+1]; } } } } int main() { int a[] = {6,12,5,3,4,18}; BubbleSort(a,6); for(int i=0;i<=5;i++) cout<<a[i]<<' '; cout<<endl; return 0; }
简单选择排序
(1)基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;
然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。
(2)实例:
#include <iostream> using namespace std; void SelectSort(int vec[],int n) { for(int i=0; i<n-1; i++) for(int j=i+1; j<n;j++) if(vec[i] > vec[j]) { vec[i] = vec[i] ^ vec[j]; vec[j] = vec[j] ^ vec[i]; vec[i] = vec[i] ^ vec[j]; } } void Print(int vec[], int n) { for(int i=0; i<n; i++) cout<< vec[i]<<' '; cout<<endl; } int main() { int a[] = {12,4,5,8,21,1,3}; Print(a,7); SelectSort(a,7); Print(a,7); system("pause"); return 0; }
上述代码中可以发现,只要出现逆置的情况就会发生一次交换,这样的作法效率是很低的,因此可以首先检测出最小值的下标,最后进行交换。
void SelectSort(int vec[],int n) { for(int i=0; i<n-1; i++) { \ int Min = i; for(int j=i+1; j<n;j++) if(vec[Min] > vec[j]) Min = j; if(Min != i){ vec[i] = vec[i] ^ vec[Min]; vec[Min] = vec[Min] ^ vec[i]; vec[i] = vec[i] ^ vec[Min]; } } }
直接插入排序
(一直对插入排序的印象极为深刻,因为在读《算法导论》的开篇就是用摸扑克牌的方法介绍插入排序,自认为很经典,举例也极为恰当)
(1)基本思想:在要排序的一组数中,假设前面(n-1) [n>=2] 个数已经是排
好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数
也是排好顺序的。如此反复循环,直到全部排好顺序。
(2)实例
#include <iostream> using namespace std; void InsertSort(int vec[],int n) { for(int i=1; i<=n-1; i++) { int temp = vec[i];//摸到一张扑克牌 int j = i-1; while(j>=0 && vec[j]>temp) {//寻找插入位置 vec[j+1] = vec[j]; j--; } vec[j+1] = temp;//插入扑克牌 } } void Print(int vec[], int n) { for(int i=0; i<n; i++) cout<< vec[i]<<' '; cout<<endl; } int main() { int a[] = {12,4,5,8,21,1,3}; Print(a,7); InsertSort(a,7); Print(a,7); system("pause"); return 0; }
快速排序
基本思想:选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。
#include <iostream>
using namespace std;
int QuickPartation(int vec[], int low, int high) {
if(low < high) {
int i = low - 1;
int temp = vec[high];
for(int j=low; j<=high-1; j++) {
if(vec[j] <= temp) {
i = i + 1;
int m = vec[i];
vec[i] = vec[j];
vec[j] = m;
}
}
vec[high] = vec[i+1];
vec[i+1] = temp;
return i+1;
}
}
void QuickSort(int vec[], int low, int high) {
if(low < high) {
int mid = QuickPartation(vec,low,high);
QuickSort(vec,low,mid-1);
QuickSort(vec,mid+1, high);
}
}
void Print(int vec[], int n) {
for(int i=0; i<n; i++)
cout<<vec[i]<<' ';
cout<<endl;
}
int main() {
int a[] = {12,4,5,8,21,1,13};
Print(a,7);
QuickSort(a,0,6);
Print(a,7);
system("pause");
return 0;
}