以前自己博客里留了一些java代码实现的排序算法代码,很丑陋,现在看不惯了,刚好最近买了一本《算法 第4版》。索性就一边看看这本书,一边改过去代码,顺便练习C++、python。
所以说,醉翁之意不在酒,《算法》里那些排序算法有什么意思?都是前人留下的东西,后者(现在那些大学生)学这些算法就像古代读书人读四书五经一样。所以我看重的真不是这些个算法。我看重的是编程的练习。
练习什么?
1,练习编程语言。为了以后更高逼格地黑C++,得把C++学好。
2,练习怎样构建可读性更强、更优雅、可扩展性更强的项目。从这个角度讲,完全可以借此来练习重构技术、设计模式。
例如排序算法,各种排序算法每一个算法一个类的话,就需要用面向对象思想提取其中公用的代码。 再用抽象方法的方式来要求 某些子类必须实现的方法sort。
另外,要排序就要排序一切可以比较的类,如果只能排序int类型或double类型,那不叫可扩展性,怎样可扩展?那就要泛型的思 想。此外,要排序的实体类要写方法来定义如何比较,java的comparable,C++的操作符重载。
所以第一回合(本章),是先写一个大框架,之后(从第二回合开始)再不断向这个框架里添加各种排序算法,和其它算法。
最后要声明这是很简单的程序,java用了半个小时,C++用了一天(第一次使用),python用了一个小时(一边写一边查阅python用法)。目的只在于练习和玩耍。
java实现(代码主要参考《算法第4版》,我在其中加入抽象类的基类):
Date.java(Comparable接口用来比较,重写toString是每个实体类必须的,记得华为编程规范要求过):
package cn.data;
/**
* @ClassName: Date
* @Description: 日期
* @author 无名
* @date 2016-6-9 下午1:26:25
* @version 1.0
*/
public class Date implements Comparable<Date>
{
/**天*/
private final int day;
/**月*/
private final int month;
/**年*/
private final int year;
public Date(int d, int m, int y)
{
day = d;
month = m;
year = y;
}
public int compareTo(Date that)
{
if(this.year > that.year)
{
return +1;
}
if(this.year < that.year)
{
return -1;
}
if(this.month > that.month)
{
return +1;
}
if(this.month < that.month)
{
return -1;
}
if(this.day > that.day)
{
return +1;
}
if(this.day < that.day)
{
return -1;
}
return 0;
}
public String toString()
{
return month + "/" + day + "/" + year;
}
}
Base.java(一些必要的排序类方法,抽象方法sort是子类必须实现的):
package cn.sort;
/**
* @ClassName: Base
* @Description: 排序类基类
* @author 无名
* @date 2016-6-9 下午1:06:52
* @version 1.0
*/
public abstract class Base
{
public abstract void sort(Comparable[] arr);
public boolean less(Comparable v, Comparable w)
{
return v.compareTo(w) < 0;
}
public void exch(Comparable[] arr, int i, int j)
{
Comparable t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
public void printArr(Comparable[] arr)
{
for(int i = 0; i < arr.length - 1; i++)
{
System.out.print(arr[i] + " ");
}
System.out.print(arr[arr.length - 1]);
}
}
Selection.java:
package cn.sort;
/**
* @ClassName: Selection
* @Description: 选择排序类
* @author 无名
* @date 2016-6-9 下午7:23:59
* @version 1.0
*/
public class Selection extends Base
{
@Override
public void sort(Comparable[] arr)
{
int arrLength = arr.length;
for (int i = 0; i < arrLength; i++)
{
int min = i;
for(int j = i + 1; j < arrLength; j++)
{
if(less(arr[j], arr[min]))
{
min = j;
}
}
exch(arr, i, min);
}
}
}
AlgorithmTest.java:
package cn.test;
import org.junit.Test;
import cn.data.Date;
import cn.sort.Selection;
/**
* @ClassName: Test
* @Description: 测试类
* @author 无名
* @date 2016-6-9 下午7:26:08
* @version 1.0
*/
public class AlgorithmTest
{
private Date[] getTestData()
{
Date[] dateArr = {new Date(11,3,2001),new Date(11,7,1992),
new Date(10,12,1884),new Date(12,3,2001)};
return dateArr;
}
@Test
public void testSelection()
{
Selection selection = new Selection();
Date[] arr = getTestData();
selection.sort(arr);
selection.printArr(arr);
}
}
C++实现(代码主要参考java实现,重载操作符代替java的comparable接口,另外,使用模板类来实现泛型,使用STL vector容器作为数组,C++的文件不知道该怎么组织,本以为类的实现和声明要分开,结果发现inline成员函数不能分开、模板类的实现不能分开。太搞笑了,那就都放.h文件吧)
代码命名规范,参考这篇名为googleC++命名规范的文章:http://blog.csdn.net/u012333003/article/details/20282277?utm_source=tuicool&utm_medium=referral
entity_class.h(C++没有java的toString()就只好自己写,输出时必须自己调用):
/*************************************************
Copyright:bupt
Author:无名
Date:2010-06-10
Description:实体类
**************************************************/
#ifndef ENTITY_H_
#define ENTITY_H_
#include <string>
using std::string;
class Date
{
private:
int day_;
int month_;
int year_;
public:
Date(int d, int m, int y);
string ToString();
inline bool operator< (const Date &date) const;
inline bool operator> (const Date &date) const;
inline bool operator== (const Date &date) const;
};
Date::Date(int d, int m, int y)
{
this->day_ = d;
this->month_ = m;
this->year_ = y;
}
string Date::ToString()
{
char ch_tmp_arr[10];
string final_str;
_itoa_s(this->year_, ch_tmp_arr, 10);
final_str.append(ch_tmp_arr);
final_str.append("-");
_itoa_s(this->month_, ch_tmp_arr, 10);
final_str.append(ch_tmp_arr);
final_str.append("-");
_itoa_s(this->day_, ch_tmp_arr, 10);
final_str.append(ch_tmp_arr);
return final_str;
}
inline bool Date::operator>(const Date &date) const
{
if (this->year_ > date.year_)
{
return true;
}
if (this->year_ < date.year_)
{
return false;
}
if (this->month_ > date.month_)
{
return true;
}
if (this->month_ < date.month_)
{
return false;
}
if (this->day_ > date.day_)
{
return true;
}
if (this->day_ < date.day_)
{
return false;
}
return 0;
}
inline bool Date::operator<(const Date &date) const
{
if (this->year_ > date.year_)
{
return false;
}
if (this->year_ < date.year_)
{
return true;
}
if (this->month_ > date.month_)
{
return false;
}
if (this->month_ < date.month_)
{
return true;
}
if (this->day_ > date.day_)
{
return false;
}
if (this->day_ < date.day_)
{
return true;
}
return 0;
}
inline bool Date::operator==(const Date &date) const
{
if (this->year_ == date.year_ && this->month_ == date.month_
&& this->day_ == date.day_)
return true;
return false;
}
#endif
sort_class.h(来看看C++坑爹的蠢乎乎的泛型吧):
/*************************************************
Copyright:bupt
Author:无名
Date:2010-06-10
Description:与排序相关的类
**************************************************/
#ifndef SORT_H_
#define SORT_H_
#include<iostream>
#include<string>
#include<vector>
using std::vector;
using std::cin;
using std::cout;
using std::endl;
template <class T>
class SortBase
{
public:
virtual void Sort(vector<T> & arr) = 0;
void Exch(vector<T> & arr, int i, int j);
void PrintArr(vector<T> & arr);
};
template <class T1, class T2>
class Selection :public SortBase<T1>
{
public:
void Sort(vector<T2> & arr);
};
template <class T>
void SortBase<T>::Exch(vector<T> & arr, int i, int j)
{
T t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
template <class T>
void SortBase<T>::PrintArr(vector<T> & arr)
{
int length = arr.size();
for (int i = 0; i < length - 1; i++)
{
cout << arr[i].ToString() << " ";
}
cout << arr[length - 1].ToString() << endl;
}
template <class T1, class T2>
void Selection<T1, T2>::Sort(vector<T2> & arr)
{
int arr_length = arr.size();
for (int i = 0; i < arr_length; i++)
{
int min = i;
for (int j = i + 1; j < arr_length; j++)
{
if (arr[j] < arr[min])
{
min = j;
}
}
Exch(arr, i, min);
}
}
#endif
algorithm_test.cpp:
/*************************************************
Copyright:bupt
Author:无名
Date:2010-06-10
Description:测试
**************************************************/
#include "sort_class.h"
#include "entity_class.h"
vector<Date> getTestData()
{
Date d1 = Date(11, 7, 1992);
Date d2 = Date(3, 2, 2001);
Date d3 = Date(10, 10, 1888);
Date d4 = Date(23, 7, 1992);
vector<Date> vec;
vec.push_back(d1);
vec.push_back(d2);
vec.push_back(d3);
vec.push_back(d4);
return vec;
}
void main()
{
vector<Date> vec = getTestData();
Selection<Date,Date> selection;
selection.Sort(vec);
selection.PrintArr(vec);
cin.get();
}
python实现(代码主要参考java,IDE eclipse,人生苦短,我用python你可以看到这些代码中,python的是最简洁的C++是最丑):
Date.py:
‘‘‘
Created on 2016-6-11
@author: sonn
‘‘‘
class Date:
def __init__(self,year,month,day):
self.__day = day
self.__month = month
self.__year = year
def compareTo(self,that):
if self.__year > that.__year:
return 1
if self.__year < that.__year:
return -1
if self.__month > that.__month:
return 1
if self.__month < that.__month:
return -1
if self.__day > that.__day:
return 1
if self.__day < that.__day:
return -1
return 0
def __repr__(self):
return str(self.__year) + "-" + str(self.__month) + "-" + str(self.__day)
Base.py:
‘‘‘
Created on 2016-6-11
@author: sonn
‘‘‘
from abc import ABCMeta, abstractmethod
class Base:
__metaclass__ = ABCMeta
@abstractmethod
def sort(self):pass
def less(self,v,w):
return v.compareTo(w)
def exch(self,arr,i,j):
tmp = arr[i]
arr[i] = arr[j]
arr[j] = tmp
def printArr(self,arr):
for date in arr:
print(date)
Selection.py:
‘‘‘
Created on 2016-6-11
@author: sonn
‘‘‘
from cn.sort.Base import Base
class Selection(Base):
def sort(self,arr):
arrLen = len(arr)
for i in range(0,arrLen-1):
min = i
for j in range(i + 1, arrLen - 1):
if(self.less(arr[j], arr[min]) < 0):
min = j
self.exch(arr, i, min)
Test.py:
‘‘‘
Created on 2016-6-11
@author: sonn
‘‘‘
from cn.data.Date import Date
from cn.sort.Selection import Selection
def getArrForSortTest():
date1 = Date(1992,7,11)
date2 = Date(2001,7,12)
date3 = Date(1777,6,13)
date4 = Date(2001,7,11)
arr = [date1,date2,date3,date4]
return arr
if __name__ == ‘__main__‘:
arr = getArrForSortTest()
selection = Selection()
selection.sort(arr)
selection.printArr(arr)