数据结构探险篇 一.单链表的实现

引言

最近看了不少经典的算法书比如<<算法>>.<<大话数据结构>>等等,决定自己仿照jdk的api写一套精简版的数据结构工具类出来
现在废话少说先上代码

数据结构

节点类
package book_1_3;

public class MyNode <T>{

	private MyNode<T> next_node;//前节点
	private MyNode<T> pre_node;//后节点
	private T data;//存放的数据
	
	public MyNode(T data) {
		next_node = null;
		pre_node = null;
		//index = -1;
		this.data = data;
	}
	
	public MyNode<T> getNext_node() {
		return next_node;
	}

	public void setNext_node(MyNode<T> next_node) {
		this.next_node = next_node;
	}

	public MyNode<T> getPre_node() {
		return pre_node;
	}

	public void setPre_node(MyNode<T> pre_node) {
		this.pre_node = pre_node;
	}
	
	public T getData() {
		return data;
	}

	public void setData(T data) {
		this.data = data;
	}
}

单链表类
public class LinkNode<T> {

	private int max_len;//最大节点数
	private int len;//当前节点数
	private MyNode head;//头指针
	private MyNode tail; //尾指针

	public LinkNode() {
		max_len = -1;
		len = 0;
		head = null;
		tail = null;
	}
	
	public LinkNode(MyNode node) {
		max_len = -1;
		len = 1;
		head = node;
		tail = node;
	}
}

这些都很简单理解就不多说了,来看看这个链表能实现的具体的api

API

获取链表当前节点数量
public int getLen(){
		return len;
	}
在链表的某一节点后添加节点
public boolean addNode_index(MyNode node,int index){
		//判断是否到达节点上限
		if(max_len != -1 && max_len <= len){
			System.out.println("当前链表节点数量已达上限");
			return false;
		}	
		
		
		if(index == 0){
			//在头节点处添加数据
			if(len == 0){
				//当链表为空添加第一个节点时
				head = node;
				tail = node;
			}else{
				head.setPre_node(node);
				node.setNext_node(head);
				head = node;
			}
		}else if(index == getLen()){
			//在尾节点处添加数据
			node.setPre_node(tail);
			tail.setNext_node(node);
			tail = node;
		}else{
			//在某节点处添加数据
			
			//遍历至那个节点处
			MyNode temp = head;
			for(int i = 1;i < index;i++ ){
				temp = temp.getNext_node();
			}
			
			//在此节点后添加数据
			temp.getNext_node().setPre_node(node);
			node.setPre_node(temp);
			node.setNext_node(temp.getNext_node());
			temp.setNext_node(node);
			
		}
		len++;
		return true;
	}
在链表尾部添加节点
public boolean addNode_head(MyNode node){
	this.addNode_index(node, 0);
	return true;
}
	
在链表头部添加节点
 public boolean addNode_tail(MyNode node){
    		this.addNode_index(node, len);
    		return true;
    	}
在链表的某一节点后添加节点
	public boolean addNode_index(MyNode node,int index){
		//判断是否到达节点上限
		if(max_len != -1 && max_len <= len){
			System.out.println("当前链表节点数量已达上限");
			return false;
		}	
		
		
		if(index == 0){
			//在头节点处添加数据
			if(len == 0){
				//当链表为空添加第一个节点时
				head = node;
				tail = node;
			}else{
				head.setPre_node(node);
				node.setNext_node(head);
				head = node;
			}
		}else if(index == getLen()){
			//在尾节点处添加数据
			node.setPre_node(tail);
			tail.setNext_node(node);
			tail = node;
		}else{
			//在某节点处添加数据
			
			//遍历至那个节点处
			MyNode temp = head;
			for(int i = 1;i < index;i++ ){
				temp = temp.getNext_node();
			}
			
			//在此节点后添加数据
			temp.getNext_node().setPre_node(node);
			node.setPre_node(temp);
			node.setNext_node(temp.getNext_node());
			temp.setNext_node(node);
			
		}
		len++;
		return true;
	}
向链表的尾部添加链表
	public boolean addLink(LinkNode<T> ls){
		addLink_index(ls,len);
		return true;
	}
向链表某一节点后添加一个链表
	public boolean addLink_index(LinkNode<T> ls,int index){
		//判断是否到达节点上限
		if(max_len != -1 && max_len <= len + ls.getLen()){
			System.out.println("当前链表节点数量已达上限");
			return false;
		}	
		
		if(index == 0){
			//在头节点处添加新链表
			ls.getTail().setNext_node(head);
			head.setPre_node(ls.getTail());
			head = ls.getHead();
		}else if(index == len){
			//在尾节点处添加新链表
			tail.setNext_node(ls.head);
			ls.head.setPre_node(tail);
			tail = ls.tail;
		}else{
			//在某节点处添加数据
			//遍历至那个节点处
			MyNode temp = head;
			for(int i = 1;i < index;i++ ){
				temp = temp.getNext_node();
			}
			
			//在此节点后添加数据
			temp.getNext_node().setPre_node(ls.getTail());
			ls.tail.setNext_node(temp.getNext_node());
			temp.setNext_node(ls.head);
			ls.head.setPre_node(temp);
		}
		
		len += ls.getLen();
		
		return true;
	}
根据数据删除某些节点
	public void delNode(T data){
		//遍历所有节点
		MyNode v = head;
		while(v != null){
			if(v.getData().equals(data)){
				//删除当前节点
				v.getPre_node().setNext_node(v.getNext_node());
				v.getNext_node().setPre_node(v.getPre_node());
			}
			v = v.getNext_node();
		}
	}
删除某索引的节点
	public void delNode_index(int index){
		//遍历至那个节点处
		MyNode temp = head;
		for(int i = 1;i < index;i++ ){
			temp = temp.getNext_node();
		}
		//删除此节点
		temp.getPre_node().setNext_node(temp.getNext_node());
		temp.getNext_node().setPre_node(temp.getPre_node());
	
	}
根据数据去修改某些节点
	public void updateNode(T data,T data2){
		//遍历所有节点
		MyNode v = head;
		while(v != null){
			if(v.getData().equals(data)){
				//删除当前节点
				v.setData(data2);
			}
			v = v.getNext_node();
		}
	}
根据索引去修改某些节点
	public void updateNode_index(T data,int index){
		//遍历至那个节点处
		MyNode temp = head;
		for(int i = 1;i < index;i++ ){
			temp = temp.getNext_node();
		}
		temp.setData(data);
	}
根据索引获取节点
	public MyNode<T> getNode_index(int index){
		//过滤错误请求
		if(index < 1 || index > len || len < 1){
			return null;
		}
		
		//遍历至那个节点处
		MyNode temp = head;
		for(int i = 1;i < index;i++ ){
			temp = temp.getNext_node();
		}
		return temp;
	}
任意交换两个节点
	public void swap_node(int pre,int next){
		
		//过滤错误请求
		if(len < 1 || pre == next || pre < 1 || next > len){
			return ;
		}
		
		
		if(pre > next){
			int temp = pre;
			pre = next;
			next = temp;
		}
		
		boolean flag_closeLoop = false;
		if(1 == next - pre){
			flag_closeLoop = true;
		}
		
		//获取前后节点
		MyNode pre_node = getNode_index(pre);
		MyNode next_node;
		if(next - pre == 1){
			next_node = pre_node.getNext_node();
		}else{
			next_node = getNode_index(next);
		}

	 	
	 	//修改前后节点的前后两个节点的指针
	 	//并判断是否修改头尾节点
	 	if(pre_node.getPre_node() != null){
			pre_node.getPre_node().setNext_node(next_node);
		}else{
			head = next_node;
		}
	 	//避免闭环
	 	if(!flag_closeLoop){
	 		pre_node.getNext_node().setPre_node(next_node);
	 	}
		
		
		if(next_node.getNext_node() != null){
			next_node.getNext_node().setPre_node(pre_node);
		}else{
			tail = pre_node;
		}
		//避免闭环
	 	if(!flag_closeLoop){
	 		next_node.getPre_node().setNext_node(pre_node);
	 	}
		
		
		
		//获取前后各节点的指针
		MyNode preNode_pre = pre_node.getPre_node();
		MyNode preNode_next = pre_node.getNext_node();
		MyNode nextNode_pre = next_node.getPre_node();
		MyNode nextNode_next = next_node.getNext_node();
		
		//判断前后节点是否直接相连,防止闭环出现
		if(flag_closeLoop){
			//修改前节点的指针
			pre_node.setPre_node(next_node);
			pre_node.setNext_node(nextNode_next);
			//修改后节点的指针
			next_node.setPre_node(preNode_pre);
			next_node.setNext_node(pre_node);
		}else{
			//修改前节点的指针
			pre_node.setPre_node(nextNode_pre);
			pre_node.setNext_node(nextNode_next);
			//修改后节点的指针
			next_node.setPre_node(preNode_pre);
			next_node.setNext_node(preNode_next);
		}
	}
对链表进行排序
	public void link_sort(){
		//进行冒泡排序
		MyNode v;
		if(len <= 1){
			return ;
		}
		
		for(int i = 1;i <= len;i++){
			v = head;
			for(int j = 1;j <= len - i;j++){
				if(sort_order(v.getData(), v.getNext_node().getData())){
					swap_node(j, j + 1);
				}else{
					v = v.getNext_node();
				}
				
			}
		}
		
	}
向链表重写自己的排序规则
	public boolean sort_order(Object object,Object object2){
		if( object.toString().compareTo(object2.toString())>0){
			return true;
		}
		return false;
	}
链表去重(空间换时间,使用hashMap)
	//注意删除头尾节点的情况
	public void remove_repeat(){
		HashMap<T, Integer> map = new HashMap<T,Integer>();
		
		MyNode temp = head;
		while(temp != null){
			//判断map中是否已存在该节点的值,
			if(map.containsKey(temp.getData())){
				//如果存在则删除该节点
				temp.getPre_node().setNext_node(temp.getNext_node());
				if(temp.getNext_node() != null){
					temp.getNext_node().setPre_node(temp.getPre_node());
				}else{
					//删除尾节点时
					tail = temp.getPre_node();
				}				
			}else{
				//不存在则将该节点的值存入map
				map.put((T) temp.getData(),1);
			}		
			temp = temp.getNext_node();
		}
	}
链表翻转
	public void link_revers(){
		//从后遍历所有节点
		MyNode v = tail;
		MyNode temp;
		while(v != null){
			temp = v.getPre_node();
			v.setPre_node(v.getNext_node());
			v.setNext_node(temp);
			v = temp;
		}
		//交换头尾指针
		temp = head;
		head = tail;
		tail = temp;
		
	}
打印链表
	public void prinLink(){
		MyNode<T> temp = head;
		while (temp != null) {
			System.out.println(temp.getData().toString());
			temp = temp.getNext_node();
		}
	}
反向打印链表
	public void reversePrinLink(){
		MyNode<T> temp = tail;
		while (temp != null) {
			System.out.println(temp.getData().toString());
			temp = temp.getPre_node();
		}
	}

如果觉得对你有帮助的话,点赞,留言,转发走一波

完整代码

package book_1_3;

//节点类
public class MyNode <T>{

	private MyNode<T> next_node;//前节点
	private MyNode<T> pre_node;//后节点
	private T data;//存放的数据
	
	public MyNode(T data) {
		next_node = null;
		pre_node = null;
		//index = -1;
		this.data = data;
	}
	
	public MyNode<T> getNext_node() {
		return next_node;
	}

	public void setNext_node(MyNode<T> next_node) {
		this.next_node = next_node;
	}

	public MyNode<T> getPre_node() {
		return pre_node;
	}

	public void setPre_node(MyNode<T> pre_node) {
		this.pre_node = pre_node;
	}
	
	public T getData() {
		return data;
	}

	public void setData(T data) {
		this.data = data;
	}
}




//链表类

public class LinkNode<T> {

	private int max_len;
	private int len;
	private MyNode head;
	private MyNode tail; 
	
	public LinkNode() {
		max_len = -1;
		len = 0;
		head = null;
		tail = null;
	}
	
	public LinkNode(MyNode node) {
		max_len = -1;
		len = 1;
		head = node;
		tail = node;
	}
	
	//获取链表当前节点数量
	public int getLen(){
		return len;
	}

	//在链表尾部添加节点
	public boolean addNode_head(MyNode node){
		this.addNode_index(node, 0);
		return true;
	}
	
	//在链表头部添加节点
	public boolean addNode_tail(MyNode node){
		this.addNode_index(node, len);
		return true;
	}
	
	//在链表的某一节点后添加节点
	public boolean addNode_index(MyNode node,int index){
		//判断是否到达节点上限
		if(max_len != -1 && max_len <= len){
			System.out.println("当前链表节点数量已达上限");
			return false;
		}	
		
		
		if(index == 0){
			//在头节点处添加数据
			if(len == 0){
				//当链表为空添加第一个节点时
				head = node;
				tail = node;
			}else{
				head.setPre_node(node);
				node.setNext_node(head);
				head = node;
			}
		}else if(index == getLen()){
			//在尾节点处添加数据
			node.setPre_node(tail);
			tail.setNext_node(node);
			tail = node;
		}else{
			//在某节点处添加数据
			
			//遍历至那个节点处
			MyNode temp = head;
			for(int i = 1;i < index;i++ ){
				temp = temp.getNext_node();
			}
			
			//在此节点后添加数据
			temp.getNext_node().setPre_node(node);
			node.setPre_node(temp);
			node.setNext_node(temp.getNext_node());
			temp.setNext_node(node);
			
		}
		len++;
		return true;
	}

	//向链表的尾部添加链表
	public boolean addLink(LinkNode<T> ls){
		addLink_index(ls,len);
		return true;
	}
	
	//向链表某一节点后添加一个链表
	public boolean addLink_index(LinkNode<T> ls,int index){
		//判断是否到达节点上限
		if(max_len != -1 && max_len <= len + ls.getLen()){
			System.out.println("当前链表节点数量已达上限");
			return false;
		}	
		
		if(index == 0){
			//在头节点处添加新链表
			ls.getTail().setNext_node(head);
			head.setPre_node(ls.getTail());
			head = ls.getHead();
		}else if(index == len){
			//在尾节点处添加新链表
			tail.setNext_node(ls.head);
			ls.head.setPre_node(tail);
			tail = ls.tail;
		}else{
			//在某节点处添加数据
			//遍历至那个节点处
			MyNode temp = head;
			for(int i = 1;i < index;i++ ){
				temp = temp.getNext_node();
			}
			
			//在此节点后添加数据
			temp.getNext_node().setPre_node(ls.getTail());
			ls.tail.setNext_node(temp.getNext_node());
			temp.setNext_node(ls.head);
			ls.head.setPre_node(temp);
		}
		
		len += ls.getLen();
		
		return true;
	}
	
	//根据数据删除某些节点
	public void delNode(T data){
		//遍历所有节点
		MyNode v = head;
		while(v != null){
			if(v.getData().equals(data)){
				//删除当前节点
				v.getPre_node().setNext_node(v.getNext_node());
				v.getNext_node().setPre_node(v.getPre_node());
			}
			v = v.getNext_node();
		}
	}
	
	//删除某索引的节点
	public void delNode_index(int index){
		//遍历至那个节点处
		MyNode temp = head;
		for(int i = 1;i < index;i++ ){
			temp = temp.getNext_node();
		}
		//删除此节点
		temp.getPre_node().setNext_node(temp.getNext_node());
		temp.getNext_node().setPre_node(temp.getPre_node());
	
	}
	
	//根据数据去修改某些节点
	public void updateNode(T data,T data2){
		//遍历所有节点
		MyNode v = head;
		while(v != null){
			if(v.getData().equals(data)){
				//删除当前节点
				v.setData(data2);
			}
			v = v.getNext_node();
		}
	}
	
	//根据索引去修改某些节点
	public void updateNode_index(T data,int index){
		//遍历至那个节点处
		MyNode temp = head;
		for(int i = 1;i < index;i++ ){
			temp = temp.getNext_node();
		}
		temp.setData(data);
	}
	
	//根据索引获取数据
	public T getData_index(int index){
		//遍历至那个节点处
		MyNode temp = head;
		for(int i = 1;i < index;i++ ){
			temp = temp.getNext_node();
		}
		return (T) temp.getData();
	}
	
	//根据索引获取节点
	public MyNode<T> getNode_index(int index){
		//过滤错误请求
		if(index < 1 || index > len || len < 1){
			return null;
		}
		
		//遍历至那个节点处
		MyNode temp = head;
		for(int i = 1;i < index;i++ ){
			temp = temp.getNext_node();
		}
		return temp;
	}
	
	
	//任意交换两个节点
	public void swap_node(int pre,int next){
		
		//过滤错误请求
		if(len < 1 || pre == next || pre < 1 || next > len){
			return ;
		}
		
		
		if(pre > next){
			int temp = pre;
			pre = next;
			next = temp;
		}
		
		boolean flag_closeLoop = false;
		if(1 == next - pre){
			flag_closeLoop = true;
		}
		
		//获取前后节点
		MyNode pre_node = getNode_index(pre);
		MyNode next_node;
		if(next - pre == 1){
			next_node = pre_node.getNext_node();
		}else{
			next_node = getNode_index(next);
		}

	 	
	 	//修改前后节点的前后两个节点的指针
	 	//并判断是否修改头尾节点
	 	if(pre_node.getPre_node() != null){
			pre_node.getPre_node().setNext_node(next_node);
		}else{
			head = next_node;
		}
	 	//避免闭环
	 	if(!flag_closeLoop){
	 		pre_node.getNext_node().setPre_node(next_node);
	 	}
		
		
		if(next_node.getNext_node() != null){
			next_node.getNext_node().setPre_node(pre_node);
		}else{
			tail = pre_node;
		}
		//避免闭环
	 	if(!flag_closeLoop){
	 		next_node.getPre_node().setNext_node(pre_node);
	 	}
		
		
		
		//获取前后各节点的指针
		MyNode preNode_pre = pre_node.getPre_node();
		MyNode preNode_next = pre_node.getNext_node();
		MyNode nextNode_pre = next_node.getPre_node();
		MyNode nextNode_next = next_node.getNext_node();
		
		//判断前后节点是否直接相连,防止闭环出现
		if(flag_closeLoop){
			//修改前节点的指针
			pre_node.setPre_node(next_node);
			pre_node.setNext_node(nextNode_next);
			//修改后节点的指针
			next_node.setPre_node(preNode_pre);
			next_node.setNext_node(pre_node);
		}else{
			//修改前节点的指针
			pre_node.setPre_node(nextNode_pre);
			pre_node.setNext_node(nextNode_next);
			//修改后节点的指针
			next_node.setPre_node(preNode_pre);
			next_node.setNext_node(preNode_next);
		}
	}
	
	
	//对链表进行排序
	public void link_sort(){
		//进行冒泡排序
		MyNode v;
		if(len <= 1){
			return ;
		}
		
		for(int i = 1;i <= len;i++){
			v = head;
			for(int j = 1;j <= len - i;j++){
				if(sort_order(v.getData(), v.getNext_node().getData())){
					swap_node(j, j + 1);
				}else{
					v = v.getNext_node();
				}
				
			}
		}
		
	}
	
	//向链表重写自己的排序规则
	public boolean sort_order(Object object,Object object2){
		if( object.toString().compareTo(object2.toString())>0){
			return true;
		}
		return false;
	}
	
	//链表去重(空间换时间,使用hashMap)
	//注意删除头尾节点的情况
	public void remove_repeat(){
		HashMap<T, Integer> map = new HashMap<T,Integer>();
		
		MyNode temp = head;
		while(temp != null){
			//判断map中是否已存在该节点的值,
			if(map.containsKey(temp.getData())){
				//如果存在则删除该节点
				temp.getPre_node().setNext_node(temp.getNext_node());
				if(temp.getNext_node() != null){
					temp.getNext_node().setPre_node(temp.getPre_node());
				}else{
					//删除尾节点时
					tail = temp.getPre_node();
				}				
			}else{
				//不存在则将该节点的值存入map
				map.put((T) temp.getData(),1);
			}		
			temp = temp.getNext_node();
		}
	}
	
	//链表翻转
	public void link_revers(){
		//从后遍历所有节点
		MyNode v = tail;
		MyNode temp;
		while(v != null){
			temp = v.getPre_node();
			v.setPre_node(v.getNext_node());
			v.setNext_node(temp);
			v = temp;
		}
		//交换头尾指针
		temp = head;
		head = tail;
		tail = temp;
		
	}

	//打印链表
	public void prinLink(){
		MyNode<T> temp = head;
		while (temp != null) {
			System.out.println(temp.getData().toString());
			temp = temp.getNext_node();
		}
	}
	
	//反向打印链表
	public void reversePrinLink(){
		MyNode<T> temp = tail;
		while (temp != null) {
			System.out.println(temp.getData().toString());
			temp = temp.getPre_node();
		}
	}
	
	
	
	public int getMax_len() {
		return max_len;
	}

	public void setMax_len(int max_len) {
		this.max_len = max_len;
	}

	public MyNode getHead() {
		return head;
	}

	public void setHead(MyNode head) {
		this.head = head;
	}

	public MyNode getTail() {
		return tail;
	}

	public void setTail(MyNode tail) {
		this.tail = tail;
	}

	public void setLen(int len) {
		this.len = len;
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值