数据结构(用java描述)之单链表

  • 单链表的存储示意图
    在这里插入图片描述
  • 对于结点类的描述
package LinkList;

//对于结点的描述

public class Node {
	public Object data; //存放结点值
	public Node next;   //后继结点的引用
	//无参数时的构造函数
	public Node(){
		this(null,null);
	}
	//带一个参数的构造函数
	public Node(Object data){
		this(data,null);
	}
	//带两个参数的构造函数
	public Node(Object data,Node next){
		this.data=data;
		this.next=next;
	}

}
  • 单链表类的描述
public Node head;		//单链表的头指针
	
	public LinkList(){      //单链表的构造函数
		head = new Node();  //初始化头结点
	}
	
	public LinkList(int n ,boolean Order) throws Exception{ //构造一个长度为N的单链表
		 this();            //初始化头结点
		 if(Order){         //用尾插法顺序建立单链表
			 create1(n);
		 }
		 else{
			 create2(n);    //用头插法逆位序建立单链表
		 }
	}
  • 用头插法逆位建立单链表,其中n为单链表的结点个数
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    加粗样式
	//用头插法逆序建立单链表,其中n为单链表的结点个数
	public void create1(int n) throws Exception{
		Scanner sc =new Scanner(System.in);
		for(int j =0;j<n;j++){
			insert(0,sc.next());
		}
		
	}
  • 用尾插法顺序建立单链表,其中n为单链表的结点个数
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
//用尾插法顺序建立单链表,其中n为单链表的结点个数
	public void create2(int n) throws Exception{
		Scanner sc = new Scanner(System.in);
		for(int j = 0 ;j<n;j++){
			insert(length(),sc.next());
		}
	}
  • 将一个已经存在的带头结点单链表置成空表
//将一个已经存在的带头结点单链表置成空表
	public void clear(){
		head.data=null;
		head.next=null;
	}
  • 判断带头结点的单链表是否为空
 //判断带头结点的单链表是否为空
	public boolean isEmpty(){
		return head.next==null;
	}
  • 求带头结点的单链表的长度
//求带头结点的单链表的长度
	public int length(){
		Node p = head.next;  //初始化,p指向首结点,length为计数器
		int length=0;
		while (p!=null){     //从首结点开始向后查找,直到p为空
			p=p.next;        //指向后继结点
			length++;        //长度增加1
		}
		return length;
	}
  • 读取带头结点的单链表中的第i个结点
//读取带头结点的单链表中的第i个结点
	public Object get(int i ) throws Exception{
		Node p = head.next;  //初始化,p指向首结点,j为计数器
		int j = 0 ;
		while (p!=null && j<i){ //从首结点开始向后查找,直到p指向第i个结点或者p为空
			p = p.next; //指向后继结点
			++j;        //计数器的值增1
		}
		if (p==null || j>i)             //i小于0或者大于表长减一时,即i不合法
			throw new Exception("第"+i+"个元素不存在"); //抛出异常
		else 
			return p.data;//返回结点p的数值域值
		}

在这里插入图片描述
不能将变量初始化为’p=head;j=-1’,因为当输入i=-1时,j=i,会输出,但此时i是非法的

  • 在带头结点的单链表中查找值为x的结点
//在带头结点的单链表中查找值为x的结点
	public int indexOf(Object x){
		Node p = head.next;
		int j =0;
		//下面从单链表中的首结点开始查找,直到p.data为x或到达单链表的表尾
		while (p!=null&& !p.data.equals(x)){
			p = p.next; //指向下一个结点
			++j;        //计数器的值增加1
		}
		if(p!=null)
			return j;
		else
			return -1;
		
	}
  • 输出单链表中的所有节点
	
	//输出单链表中的所有结点
	public void display(){
		Node node = head.next;  //获取带头结点的单链表的首结点
		while (node!= null){
			System.out.print(node.data+""); //输出结点的值
			node = node.next;				//取下一个结点
		}
		System.out.println();  //换行
	}
  • 在带头结点的单链表中的第i个结点之前插入一个值为x的新结点
    在这里插入图片描述
    不能,因为可能需要在首结点后或者头结点前插入结点
//在带头结点的单链表中的第i个结点之前插入一个值为x的新结点
	public void insert(int i,Object x) throws Exception{
		Node p = head;          //初始化p为头结点,j为计数器
		int j = -1;
		while (p!=null && j<i-1){ //寻找第i个结点的前驱,即第i-1个结点
			p = p.next;
			++j;                
		}
		if (j>i-1 || p ==null){ //i不合法
			throw new Exception("插入位置不合法"); //抛出异常
		}
		Node s = new Node(x);   //生成新结点
		s.next=p.next;          //修改链,使新结点插入单链表中
		p.next=s;
			
		}
  • 在不带头结点的单链表中的第i个结点之前插入一个值为x的新结点
    不带头结点的单链表,新结点要插入到不带头结点的单链表的表头,需要将新结点s的后继指针指向原来单链表的第一个结点,并将头指针指向新结点,使新结点成为插入后的单链表中的第一个结点
	//在不带头结点的单链表中的第i个结点之前插入一个值为x的新结点
	//在不带头结点的单链表中的第i个结点之前插入一个值为x的新结点
		public void insert2(int i,Object x) throws Exception{
			Node p = head;          //初始化p为头结点,j为计数器
			int j = 0;
			while (p!=null && j<i-1){ //寻找第i个结点的前驱,即第i-1个结点
				p = p.next;
				++j;                
			}
			if (j>i-1 || p ==null){ //i不合法
				throw new Exception("插入位置不合法"); //抛出异常
			}
			Node s = new Node(x);   //生成新结点
			if(i==0){              //在表头位置插入一个新的结点
				s.next=p.next;
				head=s;
			}
			else{
			s.next=p.next;          //修改链,使新结点插入单链表中
			p.next=s;
			}
		}
  • 删除带头结点的单链表中的第i个结点
//删除带头结点的单链表中的第i个结点
	public void remove(int i) throws Exception{
		Node p =head;  //初始化p指向头结点,j为计数器
		int j = -1;
		while (p.next!=null && j<i-1){ //寻找第i个结点的前驱  
			p = p.next;
			++j;
		}
		if (j>i-1 || p.next ==null){
			throw new Exception("删除位置不合法"); //抛出异常
		}
		p.next= p.next.next;  //修改链指针,使待删结点从单链表中脱离出来
	}
	
  • 删除不带头结点的单链表中的第i个结点
    在不带头结点的单链表上删除第i个结点,则也要像插入操作一样分成两种情况分别处理,一种情况是删除第一个结点,另一种情况是删除其他位置上的结点
//删除不带头结点的单链表中的第i个结点
		public void remove1(int i) throws Exception{
			Node p =head;  //初始化p指向头结点,j为计数器
			int j = 0;
			while (p.next!=null && j<i-1){ //寻找第i个结点的前驱  
				p = p.next;
				++j;
			}
			if (j>i-1 || p.next ==null){
				throw new Exception("删除位置不合法"); //抛出异常
			}
			if(i==0){
				head=p.next.next;
			}
			else{
			p.next= p.next.next;  //修改链指针,使待删结点从单链表中脱离出来
			}
			}
  • 在带头结点的单链表上删除数据域值为x的结点
//在带头结点的单链表上删除数据域值为x的结点
		public void remove2(int i) throws Exception{
			Node p =head;  //初始化p指向头结点
			while (p.next!=null && p.next.data!=x){ //沿着链依次查找数据域值为x的结点
				p = p.next;
			}
			if (p.next ==null){
				throw new Exception("删除位置不合法"); //抛出异常
			}
			p.next= p.next.next;  //修改链指针,使待删结点从单链表中脱离出来
		}
	
  • 在做删除和插入操作时,可以令i=0/1/-1去测试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值