java数据结构与算法之排序之插入排序

InsertionSorting.java

package com.zhanglei.insertionsorting;

public class InsertionSorting {

	public static void main(String[] args) {
		// 前瞻:插入的话涉及数据的大量移动,用数组应该不合适,应该用链表
		// 后续:老师用的数组,而且只用原来的无序数组,只用了几秒钟,我用了下面的链表,耗时21秒
//		int[] a=new int[] {1,2,3,6,5,4,10,9,8,7};
		int[] a=new int[] {2,1,3,6,1,2,5,4,10,9,8,7};
		Node head1=new Node(a[0],null);
		Node head2=null;
		for(int i=1;i<a.length;i++) {
//			Node head2=new Node(a[i],null);//如果在for循环中定义变量,则下一次循环时该变量就没了??
			head2=new Node(a[i],null);
			insert(head1,head2);
		}
		Node temp=head1;
		while(temp.getNext()!=null) {
			System.out.print(temp.getNum()+" ");
			temp=temp.getNext();
		}
		//最后一个节点的信息也要打印出来!那上面的while循环遍历链表就有点缺陷
		System.out.print(temp.getNum()+" ");
	}
	
	public static void insert(Node node1,Node node2) {
		Node n1=node1;
		boolean flag=false;
		if(n1.getNext()==null) {//当链表只有一个节点时
			if(n1.getNum()>=node2.getNum()) {
//				Node temp=n1;
//				node2.setNext(temp);//错误的写法!!!!!
//				n1=node2;
				Node temp=n1.getNext();
				int numtemp1=n1.getNum();
				int numtemp2=node2.getNum();
				n1.setNum(numtemp2);
				node2.setNum(numtemp1);
				node2.setNext(temp);
				n1.setNext(node2);
				return;
			}else{
				n1.setNext(node2);
				return;
			}
		}
		while(n1.getNext()!=null) {
			if(n1.getNum()>=node2.getNum()) {//开头		
				Node temp=n1.getNext();
				int numtemp1=n1.getNum();
				int numtemp2=node2.getNum();
				n1.setNum(numtemp2);
				node2.setNum(numtemp1);
				node2.setNext(temp);
				n1.setNext(node2);
				flag=true;
				break;
			}else if(n1.getNum()<=node2.getNum() && n1.getNext().getNum()>=node2.getNum()) {//中间
				Node temp=n1.getNext();
				n1.setNext(node2);
				node2.setNext(temp);
				flag=true;
				break;
				
			}
			n1=n1.getNext();
			
		}
		if(!flag) {//末尾
			n1.setNext(node2);
		}
	}

}

class Node{
	private int num;
	private Node next;
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public Node getNext() {
		return next;
	}
	public void setNext(Node next) {
		this.next = next;
	}
	public Node(int num, Node next) {
		super();
		this.num = num;
		this.next = next;
	}
	
}

输出结果:

1 1 2 2 3 4 5 6 7 8 9 10 

备注:

  1. 上面的代码是我第一次用链表写的(知道插入排序概念之后就先写写看)
  2. 老师用的是数组写的,从头到尾只用了一个原来的无序数组
  3. 我之所以用链表是因为听闻链表适合插入,速度会更快,而实际却比老师的数组慢的多
  4. 插入排序原理:将原始数据看成一个有序表和无序表,然后每次从无序表中选一个插入到有序表中
  5. 老师的数组实现后续再补上

InsertionSortingSpeedMeasuring.java

package com.zhanglei.insertionsorting;

import java.text.SimpleDateFormat;
import java.util.Date;

public class InsertionSortingSpeedMeasuring {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int maxsize=80000;
		int[] a=new int[maxsize];
		for(int i=0;i<a.length;i++) {
			a[i]=(int)(Math.random()*8000000);//output is in range of [0,8000000)
		}
		Date date=new Date();
		SimpleDateFormat sd=new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
		String s1=sd.format(date);
		System.out.println("Before insertionSorting:"+s1);
		
		Node head1=new Node(a[0],null);
		insertionSort(a,head1);//参数为引用类型,故可以形参变,实参也跟着变
		Date date1=new Date();
		String s2=sd.format(date1);
		System.out.println("After insertionSorting:"+s2);
	}
	
	public static void insertionSort(int[] a,Node head1) {
//		Node head1=new Node(a[0],null);
		Node head2=null;
		for(int i=1;i<a.length;i++) {
//			Node head2=new Node(a[i],null);//如果在for循环中定义变量,则下一次循环时该变量就没了??
			head2=new Node(a[i],null);
			insert(head1,head2);
		}
	}
	
	public static void insert(Node node1,Node node2) {
		Node n1=node1;
		boolean flag=false;
		if(n1.getNext()==null) {//当链表只有一个节点时
			if(n1.getNum()>=node2.getNum()) {
//				Node temp=n1;
//				node2.setNext(temp);
//				n1=node2;  //node2先指向n1,然后n1又赋值为node2,最后就是n1等于node2,并自己指向自己
				Node temp=n1.getNext();
				int numtemp1=n1.getNum();
				int numtemp2=node2.getNum();
				n1.setNum(numtemp2);
				node2.setNum(numtemp1);
				node2.setNext(temp);
				n1.setNext(node2);
				return;
			}else{
				n1.setNext(node2);
				return;
			}
		}
		while(n1.getNext()!=null) {//if中的n1变化不能影响else if中的n1,所以要用break
			if(n1.getNum()>=node2.getNum()) {
//				Node temp=n1;
//				node2.setNext(temp);
//				n1=node2;		
				Node temp=n1.getNext();
				int numtemp1=n1.getNum();
				int numtemp2=node2.getNum();
				n1.setNum(numtemp2);
				node2.setNum(numtemp1);
				node2.setNext(temp);
				n1.setNext(node2);
				flag=true;
				break;
			}else if(n1.getNum()<=node2.getNum() && n1.getNext().getNum()>=node2.getNum()) {
				Node temp=n1.getNext();//逻辑关键句
				n1.setNext(node2);
				node2.setNext(temp);
				flag=true;
				break;
				
			}
			n1=n1.getNext();
			
		}
		if(!flag) {
			n1.setNext(node2);
		}
	}


}

输出结果:

Before insertionSorting:2021-03-23 09-52-59
After insertionSorting:2021-03-23 09-53-18
  1. 我这效果太差了,应该是自己的代码太naive
  2. 参考别人的单链表实现插入排序,看速度是否有提升
  3. 链接1
  4. 链接2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值