菜鸟的奋斗——从排序开始走进程序的世界

今天就写个归并排序吧,简单的功能,实现整数排序,没有苛刻的测试用例。表示博客今天开张了

陆陆续续的编写,并参考了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;  
  
} 



 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值