N日一篇——Java实现链式表

Posted 从零开始的智障生活

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了N日一篇——Java实现链式表相关的知识,希望对你有一定的参考价值。

线性表详解:https://blog.csdn.net/qq_34028001/article/details/119321938 

一、建立单向链表数据类型

package com.zyx.Linear.LinkedList;

/**
 *	定义一个链表的抽象数据类型ADT
 *	@author zyx
 */
public interface LinkedList {
	
	//判断当前节点是否为空,空则返回true
	public boolean isEmpty(SingleLinkedList L);
	// 创建一个结点
	public SingleLinkedList createNewNode(int data);
	
	//插入结点:直接插入到尾部
	public void insertNodetoRear(SingleLinkedList L,int data);
	//插入结点:按位序插入结点,从1开始计,插入到第i个位置,即将第i个往后移一下,挪出一个位置。
	public void insertNodebyLocate(SingleLinkedList L,int locate,int data);
	//删除结点:按位序删除,从1开始计,删除第i个位置内存,并将第i+1个往前移一下,挪出一个位置。
	public void deleteNodebyLocate(SingleLinkedList L,int locate);
	//删除结点:按值删除
	public void deleteNodebyValue(SingleLinkedList L,int data);
	
	//结点访问:按key值访问,这里数据只有一个data,所以只用data,返回位序
	public int accessNodebyValue(SingleLinkedList L,int data);
	//结点访问:按位序访问,返回数据data值。
	public int accessNodebyLocate(SingleLinkedList L,int locate);
	
	//打印线性表内容
	public void printList(SingleLinkedList L);
	//返回线性表长度
	public int Length(SingleLinkedList L);
	
	//销毁线性表L
	public void destroyList(SingleLinkedList L);

}

 二、实现单向链表

package com.zyx.Linear.LinkedList;

/**
 *  实现一个单向链表
 *  一个单向链表的字段只有数据项和后继结点,当然如果想的话可以直接设置一个参数length来统计链表长度。
 */

public class SingleLinkedList implements LinkedList{
	
	private int data;
	private SingleLinkedList next;
	
	public int getData() {
		return data;
	}

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

	public SingleLinkedList getNext() {
		return next;
	}

	public void setNext(SingleLinkedList next) {
		this.next = next;
	}
	
	// 初始化一个带头结点的单链表
	public SingleLinkedList() {
		setData(-1);			//头结点无有效数据,用-1表示
		setNext(null);
	}
	@Override
	public SingleLinkedList createNewNode(int data) {
		SingleLinkedList newNode = new SingleLinkedList();
		newNode.setData(data);
		return newNode;
		
	}
	@Override
	public void insertNodetoRear(SingleLinkedList L, int data) {
		// 首先判断传入的单链表不为空
		if(isEmpty(L) == true)return;
		
		// 设置一个当前节点用于遍历
		SingleLinkedList curNode = L;
		
		// 遍历到最后一个结点
		while(curNode.getNext() != null) {
			curNode = curNode.getNext();
		}
		
		// 用传进来的数据创建一个新节点
		SingleLinkedList newnode = createNewNode(data);
		// 将新的结点放到最后
		curNode.setNext(newnode);
	}

	@Override
	public void insertNodebyLocate(SingleLinkedList L, int locate, int data) {
		// 首先判断传入的单链表不为空
		if(isEmpty(L) == true)return;
		// 判断传入的位序是否>0
		if(locate<1) {
			System.out.println("传入位序<1,按位序插入结点失败");
			return;
		}
		
		// 设置一个当前节点用于遍历
		SingleLinkedList curNode = L;
		
		// 设置一个位序临时字段,记录当前位序
		int curi=0;
		
		//特殊情形:locate,超过已有数据长度+1,即:即使想要作为尾结点也没办法
		if(locate>Length(L)+1) {
			System.out.println("给的位序超过已有数据长度+1,插入失败");
			return;
		}
		
		// 找到位序为locate的结点前一个结点
		while(curi != locate-1) {
			curNode=curNode.getNext(); //从头结点的子节点,即位序为1的结点,开始遍历
			curi++;
		}
		
		// 用传进来的数据创建一个新节点
		SingleLinkedList newnode = createNewNode(data);
		// 如果位置合理,实现在单向链表的某个位置插入这个节点
		newnode.setNext(curNode.getNext());		//将原位序为i的结点接在新节点后面,相当于后移
		curNode.setNext(newnode);				//将新节点接在位序为i-1的结点的后面。
		
	}

	@Override
	public void deleteNodebyLocate(SingleLinkedList L, int locate) {
		SingleLinkedList curNode = L; // 带头结点,所以从头结点的子节点计
		//特殊情形:locate,超过已有数据长度,即:即使想要作为尾结点也没办法
		if(locate>Length(L)) {
			System.out.println("给的位序超过已有数据长度,删除失败");
			return;
		}
		// 遍历到第locate结点的父结点
		for(int i = 1;i<locate;i++) {
			curNode=curNode.getNext();
		}
		// 将locate的父节点与locate的子节点相连
		curNode.setNext(curNode.getNext().getNext());
	}

	@Override
	public void deleteNodebyValue(SingleLinkedList L, int data) {
		// TODO Auto-generated method stub
		return;
	}

	@Override
	public int accessNodebyValue(SingleLinkedList L, int data) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int accessNodebyLocate(SingleLinkedList L, int locate) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void printList(SingleLinkedList L) {
		SingleLinkedList curNode = L.getNext();
		while(curNode != null) {
			System.out.println(curNode.getData());
			curNode = curNode.getNext();
		}
	}

	@Override
	public int Length(SingleLinkedList L) {
		/**
		 * 头结点不计,计带有有效数据的结点
		 */
		int i=0;
		SingleLinkedList curNode = L;
		while(curNode.getNext() != null) {
			curNode=curNode.getNext();
			i++;
		}
		return i;
	}

	@Override
	public void destroyList(SingleLinkedList L) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public boolean isEmpty(SingleLinkedList L) {
		// TODO Auto-generated method stub
		if(L == null) {
			System.out.println("传入单链表为空,无法插入结点");
			return true;
		}
		return false;
	}
	}
	

三、测试单向链表

package com.zyx.Linear.LinkedList;
public class TestSLL {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SingleLinkedList sll = new SingleLinkedList();
		System.out.println("插入结点直接插入到尾部,值设为1~3");
		for(int i=1;i<4;i++) {
			sll.insertNodetoRear(sll,i);
		}
		sll.printList(sll);
		System.out.println("再插入结点,按位序4~6插入,值设为4~6");
		for(int i=4;i<7;i++) {
			sll.insertNodebyLocate(sll, i, i);
		}
		sll.printList(sll);
		System.out.println("再删除结点,按位序删除,删除位序为3的结点(删完之后,原链表长度减一),以及位序为7(不存在)的结点");
		sll.deleteNodebyLocate(sll, 3);
		sll.deleteNodebyLocate(sll, 7);
		sll.printList(sll);
	}
}

运行结果:

插入结点直接插入到尾部,值设为1~3
1
2
3
再插入结点,按位序4~6插入,值设为4~6
1
2
3
4
5
6
再删除结点,按位序删除,删除位序为3的结点(删完之后,原链表长度减一),以及位序为7(不存在)的结点
给的位序超过已有数据长度,删除失败
1
2
4
5
6

以上是关于N日一篇——Java实现链式表的主要内容,如果未能解决你的问题,请参考以下文章

N日一篇——Java实现队列

N日一篇——Java实现队列

N日一篇——Java实现队列

N日一篇——Java实现栈

N日一篇——Java实现栈

N日一篇——二叉树