这几天闲来无事,,愤懑至极。。。
以前不太认真,看看了事,每次都搞不清谁是谁。。。今天总结一下,顺便实现。
1、冒泡排序
public class Mpsort implements SortArray{
/**
* @param args
*/
public static void main(String[] args) {
List list= new ArrayList();
list.add(8);
list.add(1);
list.add(-5);
list.add(6);
list.add(1);
list.add(3);
SortArray sort = new Qucksort();
list = sort.sort(list);
for(int i = 0;i<list.size();i++)
System.out.print(list.get(i)+" ");
}
@Override
public List sort(List list) {
int n1;
int n2;
for(int i = list.size()-1;i> 0;i--){
for(int j = 0;j<= i;j++){
n1 = (Integer)list.get(j);
n2 = (Integer)list.get(j+1);
if(n1>n2){
list.set(j, n2);
list.set(j+1,n1);
}
}
}
return list;
}
}
2、直接插入排序
public class Insertsort implements SortArray{
/**
* @param args
*/
public static void main(String[] args) {
List list= new LinkedList();
list.add(8);
list.add(1);
list.add(-5);
list.add(6);
list.add(1);
list.add(3);
SortArray sort = new Qucksort();
list = sort.sort(list);
for(int i = 0;i<list.size();i++)
System.out.print(list.get(i)+" ");
}
@Override
public List sort(List list) {
/*
* 从前往后,每个元素轮流查询已排好序的队列
* 并找到合适的位置(有序),插入队列中
* 本方式,在插入之后,会将该元素之后的所有元素后移一位,以挪出空位。
* 故选择数据结构的时候,尽量选择链表等,提高效率
*/
for(int i = 1;i<list.size();i++){
for(int j = 0;j<=i;j++)
{
int current = (Integer)list.get(i);
int num = (Integer)list.get(j);
if(current>num){
list.add(j, current);
list.remove(i);
}
}
}
return list;
}
}
3、选择排序
public class Selectsort implements SortArray {
/**
* @param args
*/
public static void main(String[] args) {
List list= new LinkedList();
list.add(8);
list.add(1);
list.add(-5);
list.add(6);
list.add(1);
list.add(3);
SortArray sort = new Qucksort();
list = sort.sort(list);
for(int i = 0;i<list.size();i++)
System.out.print(list.get(i)+" ");
}
@Override
public List sort(List list) {
/*
* 从带排序的(乱序部分)选择最大/小的,
* 放在带排序部分(乱序部分)的最前面位置
* 在此之前的元素都是顺序的。
*
* 在放数据时,会将该元素之后的所有元素后移一位,以挪出空位。
* 故选择数据结构的时候,尽量选择链表等,提高效率
*/
for(int i = 0;i< list.size()-1;i++){//最后一个就不用管了
int min = (Integer)list.get(i);
int minNum = i;
for(int j = i+1;j<list.size();j++){//依然要比到最后一个
int current = (Integer)list.get(j);
if(current<min){
min = current;
}
}
list.add(i, min);
list.remove(minNum);
}
return list;
}
}
4、堆排序
关键是建立大/小顶堆
public class Heapsort implements SortArray {
/**
* @param args
*/
public static void main(String[] args) {
List list= new ArrayList();
list.add(8);
list.add(1);
list.add(-5);
list.add(6);
list.add(1);
list.add(3);
SortArray sort = new Qucksort();
list = sort.sort(list);
for(int i = 0;i<list.size();i++)
System.out.print(list.get(i)+" ");
}
@Override
public List sort(List list) {
List nlist = new ArrayList();
if (list.size() > 0) {
for (int i = 0; i < list.size() - 1; i++) {
smallTopHeap(list, list.size() + i);
int currentMin = (Integer) list.get(i);
nlist.add(currentMin);
list.set(i, list.get(list.size() - 1));
list.remove(list.size() - 1);
}
nlist.add(list.get(0));
}
return nlist;
}
// 生成小顶堆
private void smallTopHeap(List list, int n) {
for (int i = n / 2; i > 0; i++) {
int mid = (Integer) list.get(i);
int left = (Integer) list.get(2 * i);
// 防止最后一个节点不是右孩子
int right = Integer.MIN_VALUE;
if (2 * i + 1 < list.size()) {
right = (Integer) list.get(2 * i + 1);
}
// 將子節點大於父節點的值替換
if (left > mid && right > mid) {
int temp = mid;
if (left > right) {
list.set(i, left);
list.set(2 * i, mid);
} else {
list.set(i, right);
list.set(2 * i + 1, mid);
}
} else if (left > mid) {
list.set(i, left);
list.set(2 * i, mid);
} else if (right > mid) {
list.set(i, right);
list.set(2 * i + 1, mid);
}
if (4 * n <= list.size()) {
smallTopHeap(list, 2 * n);
}
if (4 * n + 2 <= list.size()) {
smallTopHeap(list, 2 * n + 1);
}
}
}
}
5、归并排序
图解如下
看成是 n 个有序的子序列(长度为 1),然后两两归并。
得到 n/2 个长度为2 或 1 的有序子序列。继续亮亮归并
最后一趟
public class Mergesort implements SortArray {
@Override
public List sort(List list) {
if (list.size() == 2) {
if ((Integer) list.get(0) > (Integer) list.get(1)) {
Object o = list.get(0);
list.set(0, list.get(1));
list.set(1, o);
}
return list;
} else if (list.size() == 1) {
return list;
} else {
List nlist = new ArrayList();
int mid = list.size() / 2;
List slist = new ArrayList();
List llist = new ArrayList();
// 上面的除于二是向下取整,这里必须是<
for (int i = 0; i < mid; i++) {
slist.add(list.get(i));
}
sort(slist);
for (int i = mid; i < list.size(); i++) {
llist.add(list.get(i));
}
sort(llist);
// 前方高能
int i = 0, j = 0;
int si = (Integer) slist.get(0);
int li = (Integer) llist.get(0);
while (i < slist.size() && j < llist.size()) {
if (si < li) {
nlist.add(si);
if(++i<slist.size())
si = (Integer) slist.get(i);
} else {
nlist.add(li);
if(++j<llist.size())
li = (Integer) llist.get(j);
}
}
if (i < slist.size()) {
nlist.add(slist.get(i++));
}
if (j < llist.size()) {
nlist.add(llist.get(j++));
}
return nlist;
}
}
/**
* @param args
*/
public static void main(String[] args) {
List list= new ArrayList();
list.add(8);
list.add(1);
list.add(-5);
list.add(6);
list.add(1);
list.add(3);
SortArray sort = new Qucksort();
list = sort.sort(list);
for(int i = 0;i<list.size();i++)
System.out.print(list.get(i)+" ");
}
}
6、快速排序:
如果规定将数组的首个元素选为标兵,那么有可能会形成一边倒的状况。不会产生优化效果。
平均情况下,该方法的时间复杂度为O(nlog(n)) ,最坏情况下,时间复杂度为O(n^2),与冒泡算法的时间复杂度无异。
public class Qucksort implements SortArray {
public static void main(String[] args){
List list= new ArrayList();
list.add(8);
list.add(1);
list.add(-5);
list.add(6);
list.add(1);
list.add(3);
SortArray sort = new Qucksort();
list = sort.sort(list);
for(int i = 0;i<list.size();i++)
System.out.print(list.get(i)+" ");
}
@Override
public List sort(List list) {
//取第一個為標尺
int flag = (Integer)list.get(0);
int smallCnt = 0;
int largeCnt = 0;
List slist = new ArrayList();
List llist = new ArrayList();
for(int i = 1;i< list.size();i++){
if((Integer)list.get(i)<flag)
{
smallCnt++;
slist.add(list.get(i));
}
//這裏的>=會造成不穩定排序
if((Integer)list.get(i)>=flag)
{
largeCnt++;
llist.add(list.get(i));
}
}
if(slist.size()>1)
slist=sort(slist);
if(llist.size()>1)
llist=sort(llist);
List nlist = new ArrayList();
for(int i =0;i< slist.size();i++)
nlist.add(slist.get(i));
nlist.add(flag);
for(int i = 0;i< llist.size();i++)
nlist.add(llist.get(i));
return nlist;
}
}