今天就写个归并排序吧,简单的功能,实现整数排序,没有苛刻的测试用例。表示博客今天开张了
陆陆续续的编写,并参考了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;
}