java 单向和双向链表的详解

Java 链表的使用

浅谈自己学习链表之后的理解:

链表是一种重要的数据结构,有单链表和双链表之分

单链表(单向链表):由两部分组成 数据域(Data)和结点域(Node),单链表就像是一条打了很多结的绳子,每一个绳结相当于一个结点,每个节结点间都有绳子连接,这样原理的实现是通过Node结点区的头指针head实现的,每个结点都有一个指针,每个节点指针的指向都是指向自身结点的下一个结点,最后一个结点的head指向为null,这样一来就连成了上述所说绳子一样的链,对单链表的操作只能从一端开始,如果需要查找链表中的某一个结点,则需要从头开始进行遍历。


单链表的操作:

添加:上图可以看出 单向链表只有一个指向,原来headpp指向s,添加结点只需要把p指向q,q指向s就可以了,即:p--->q ;  q--->s ; 这样就实现了单向链表的添加;

   删除:原理与添加相反,若此时链表为 p---> q --->s ; 若删除q节点只需要更改p的指向就可以了 p--->s,这样就删掉了;

   查找:查找操作需要对整个但链表进行遍历,直到满足查找条件为止;

   修改:此操作一般建立在查找之上进行,找到借点之后对值进行修改;

 

首先构建一个节点类,设置一个数据区和节点区

使用构造方法便于使用

public class Node{
	public Node data;	//数据区
	public Node next; 	//指针区
public Node (Node data,Node next){
	this.data = data ;
	this.next = next;
}
public Node(){
}
public void setData(Node data){
	this.data = data;
}
public Node getData(){
 	return data;
}
public void setNext(Node next){
		this.next=next;
	}
	public Node getNext(){
		return next;
	}
}
public class LinkList{
	public  Node  head;	//头节点
	public  int  count;		//记录节点的长度
	public  LinkList(){	//构造函数用来初始化
		head = null;
		count = 0;
	}
	//节点的添加
	public void addNode(Node data){
		Node node = new Node(data,null);
		Node temp = null;
		If(head!= null){
			temp = head;
			while(temp.getNext()!=null){
				Temp = temp.getNext();
			}
		temp.setNext(node);
		}else{
			head = node;
			temp = node;
		}
	count++;
	}
	//节点的删除
	public void delNode(Node data){
		
			Node  front = null;	//定义一个空节点,用于接收和判断被删除节点的前面还有没有节点
			while(head!= null){
				If(head.equals(data)){
					break;
				}
				front=head;
				head = head.getNext();
			}
			If(head!=null){
				If(front==null){
					head = head.getNext();
				}else{
					front.setNext(head.getNext());
				}
				count--;
			}else{
				Count--;
			}
		
	}
	//给定下标删除节点
	public void delNode_count(int index){
		if(index<0||index>count-1){
			System.out.println("链表索引越界");
		}
		Node temp = head;	//作用同上
		//找到要删除节点的前一个节点
		for(int i=0;i<index-1;i++){
			temp=temp.getNext();
		}
								//找到之后 此节点的前节点和此节点的后节点进行连接
								//让要删除节点的前一个节点,指向被删除节点的后一个节点,也就是指向要删除节点的后后一个节点
		temp.setNext(temp.getNext().getNext());		//把要删除的节点隔过去进行连接,也就是实现了删除节点的操作
		//删除之后链表的长度变短了1位
		count--;
	}
		//以给出的index 查找节点
	
	
	public Node findNode(int index){
		if(index<0||index>count-1){
			System.out.println("链表索引越界");			
		}
		Node temp = head;
		for(int i=0;i<index-1;i++){
			temp=temp.getNext();	//找到之后获取index在链表中的位置,表示链表中第index个节点的值是temp.getData;
		}
		return temp;	//根据需要可返回找到的数据对象,也可不返回,此处建议返回,这样可以把链表封装起来
	}
	
	//以对象查找节点
	public Node findNode(NodeData data){
			Node temp = head;
			while(temp!=null){
				if(temp.equals(data)){
					return temp;
				}
				temp.setNext(temp.getNext());
			}
			return null;
	}
	//修改
	public void updateNode(NodeData data){
		Node temp = findNode(data);
		if(temp!=null){
			temp.setData(data);
		}
	}
	//打印
	public void print(){
		Node temp=head;
		while(temp!=null){
			temp.print();
			//temp.print(temp.getData().toString());
			temp=temp.getNext();
		}
	}
}

双链表(双向链表):双链表和单链表相比,多了一个指向尾指针(tail),双链表的每个结点都有一个头指针head和尾指针tail,双链表相比单链表更容易操作,双链表结点的首结点的head指向为null,tail指向下一个节点的tail;尾结点的head指向前一个结点的head,tail 指向为null,是双向的关系;


双链表的操作:

package soft1;

public class LinkList {
	Node head;
	Node tail;
	int count;
	public LinkList(Node head,Node tail,int count){
		this.head=null;
		this.tail=null;
		this.count=0;
	}
	public LinkList(){
		
	}
	//尾插法添加节点
	public void addHeadNode(NodeData data){
		Node node = new Node(data,null,null);
		if(head==null&&tail==null){
			head=node;
			head.setFront(null);
			tail=node;
			tail.setNext(null);
		}else{
			head.setFront(node);
			node.setNext(head);
			head=node;
			head.setFront(null);
		}
		count++;
	}
	//头插法添加节点
	public void addTailNode(NodeData data){
		Node node = new Node(data,null,null);
		if(head==null&&tail==null){
			head=node;
			head.setFront(null);
			tail=node;
			tail.setNext(null);
		}else{
			tail.setNext(node);
			node.setFront(tail);
			tail=node;
			tail.setNext(null);
		}
		count++;

	}
	//查找节点
	public Node findNode(NodeData data){
		Node temp=head;
		if(head!=null){
			while(temp!=null){
				if(temp.data.compare(data)){
					return temp;
				}
				temp=temp.getNext();
			}
		}
		return null;
	}
	//删除节点
	public void delNode(NodeData data){
		Node temp=findNode(data);
		if(temp!=null){
			if(temp.getFront()==null){
				head=temp.getNext();
				head.setFront(null);
			}else if(temp.getNext()==null){
				tail=tail.getFront();
				tail.setNext(null);
			}else{
				temp.getFront().setNext(temp.getNext());
				temp.getNext().setFront(temp.getFront());
			}
			count--;
		}
	}
	//修改更新
	public void updNode(NodeData data){
		Node temp=findNode(data);
		if(temp!=null){
			temp.setNodeData(data);
		}
	}
	//打印链表
	public void printNode(){
		Node temp = head;
		while(temp!=null){
			temp.print();
			temp=temp.getNext();
		}
	}
}
需要把自己写过的代码总结之后都放在网上,不过就是有点慢,急不得啊 哈哈 奋斗





  • 11
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值