【Java双链表插入排序 山月首发】

Java双链表进行排序

找了一圈发现没有一个人发过,今天刚好碰到了这个,在老师不断的思考后,代码成功出来了
代码是千峰鹏哥完成的,希望能帮到大家
渡星河博客站点首发:渡星河博客Java双链插入排序

/*双链表测试类*/
public class TestLinkedList {
	public static void main(String[] args) {
		//要访问双链表中的方法,就需要使用new关键字创建该双链表的对象。
		LinkedList list = new LinkedList();
		//String str = new String("abc");
		//调用list的添加方法
		list.add("dcd");
		list.add("bbc");
		list.add("fgh");
		list.add("bbc");
		list.add("abc");
		//调用遍历方法
		//list.traverse();
		//list.addFirst("world");
		//list.remove(-2);
		//list.insert(4, "world");
		list.traverse();
		list.insertSort();
		list.traverse();

	}
}

/*
实现双链表
该类里的属性和方法都没有用关键字static修饰
所以访问这些属性和方法的时候都要使用对象的引用取访问
*/
class LinkedList {
	//头节点
	Node first = null;
	//尾节点
	Node last = null;
	//记录节点个数
	int size = 0;
	/*定义添加元素的方法*/
	public void add(String val) {
		addLast(val);
	}
	/*尾插法*/
	public void addLast(String val) {
		//要把val添加到链表中,需要做什么?
		//第一步:创建节点,
		Node newNode = new Node();
		//第二步:把值val存入节点的数据区域
		newNode.data = val;
		//首次添加节点时,头节点和尾节点都是null.
		if(last == null) {
			//首次添加需要把头节点和尾节点的引用都移动到指向第一个节点
			first = newNode;
			last = newNode;
		} else {//非首次插入节点
			last.next = newNode;//让链表的末节点的next域指向新创建的节点
			newNode.prev = last;//让新创建节点的prev域指向链表的末节点
			last = newNode;//最后把last移动到指向新创建的节点
		}
		size++;
	}
	/*头插法*/
	public void addFirst(String val) {
		//要把val添加到链表中,需要做什么?
		//第一步:创建节点,
		Node newNode = new Node();
		//第二步:把值val存入节点的数据区域
		newNode.data = val;
		//首次插入值头和尾节点都是null
		if(first == null) {
			first = newNode;
			last = newNode;
		} else {
			newNode.next = first;
			first.prev = newNode;
			first = newNode;
		}
		size++;
	}
	/*检查位置边界*/
	public void checkBoundary(int position) {
		if (position < 0 || position > size)
			throw new RuntimeException("下标过了啊。。。。。。");
	}
	/*该方法根据指定位置返回节点*/
	public Node node(int position) {
		//定义临时遍历记录头节点
		Node x = first;
		//查找position位置处的节点
		for (int i = 1; i < position; i++) {
			x = x.next;
		}
		return x;
	}

	/*解除节点的关系*/
	public Node unlink(Node x){
		//定义变量记录需要删除的节点
		Node item = x;
		//记录当前节点的next;
		Node next = x.next;
		//记录当前节点的prev
		Node prev = x.prev;
		if (prev == null) {
			first = next;
		} else {
			prev.next = next;
			x.prev = null;
		}
		if (next == null) {
			last = prev;
		} else {
			next.prev = prev;
			x.next = null;
		}
		//x.data = null;
		size--;
		return item;
	}
	/*删除节点*/
	public Node remove(int position) {
		//位置检查
		checkBoundary(position);
		//调用方法根据位置查找节点
		Node node = node(position);
		//解除引用并返回
		return unlink(node);
	}

	/*把指定节点的数据域更新为指定的值*/
	public void update(int position, String value) {
		//检查边界
		checkBoundary(position);
		//查找需要更新的节点并设置新的值
		node(position).data = value;
	}

	/*获取指定节点的值*/
	public String get(int position) {
		return node(position).data;
	}

	/*指定位置插入一个节点*/
	public void insert(int position, String value) {
		//单独处理插链表尾部
		if((size + 1) == position) {
			addLast(value);
			return;
		}
		//单独处理插入链表头部
		if (position == 1) {
			addFirst(value);
			return;
		}
		//查找到需要插入节点的位置
		Node node = node(position);

		//获取当前节点的前一个节点
		Node prevNode = node.prev;
		//创建节点
		Node newNode = createNode(value);
		prevNode.next = newNode;
		newNode.prev = prevNode;

		newNode.next = node;
		node.prev = newNode;
		size++;
	}

	/*创建节点*/
	public Node createNode(String val) {
		Node node = new Node();
		node.data = val;
		return node;
	}

	/*去除重复节点*/
	public void distinct() {
		Node one = first;
		int outSize = 1;
		while(one != null) {
			Node two = one.next;
			int count = outSize + 1;
			while(two != null) {
				if (one.data == two.data) {
					two = two.next;
					remove(count);
				} else {
					two = two.next;
					count++;
				}
			}
			outSize++;
			one = one.next;
		}
	}

	public void insertSort() {
		Node curr = first.next;//开始时从第二个节点开始往前看
		while(curr != null) {
			Node prev = curr.prev;
			while(prev != null) {
				if (curr.data.compareTo(prev.data) < 0) {//如果当前节点小于前一个节点就继续往前查看
					prev = prev.prev;
				} else break;
			}
			//因为在之后会改变当前节点的位置,所以先定义临时变量记录改变前的节点位置
			Node cNext = curr.next;

			if (prev == null) {//如果找到的插入位置为头部直接删除节点后调用头插法
				String val = curr.data;
				unlink(curr);
				addFirst(val);
			} else {
			  //此部分逻辑完成把当前节点的前驱后后继关联上
			  //然后把当前节点插入到应该存在的位置,也就是prev之后。
				curr.prev.next = curr.next;
				if (curr.next != null) {
					curr.next.prev = curr.prev;
				}
				curr.next = prev.next;
				prev.next.prev = curr;
				prev.next = curr;
				curr.prev = prev;
			}
			curr = cNext;
		}
	}


	/*遍历链表*/
	public void traverse() {
		Node temp = first;
		while(temp != null) {
			System.out.print(temp.data + "  ");
			temp = temp.next;
		}
		System.out.println();
	}
}

class Node {
	//数据域
	String data;
	//前驱引用
	Node prev;
	//后继引用
	Node next;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值