数据结构之单向链表结构

单向链表是什么?
小时候玩过老鹰捉小鸡吧,小鸡跟着鸡妈妈, 我们让鸡妈妈抱住一棵大树,这就是虚拟向单向链表。实体的单向链表就是把树去掉吧。
大树-1>小鸡0>小鸡1>小鸡2>小鸡3>小鸡4>小鸡5>小鸡6>小鸡7。
怎么在小鸡的前面再加一只小鸡?
让大树指向新加入的小鸡,让新加入的小鸡指向小鸡0;
怎么在最末尾加一只小鸡,末尾小鸡7指向新加入小鸡8;
怎么在小鸡中加入一只小鸡?
比如在小鸡3后加入一只小鸡,让小鸡3指向新加入的小鸡,新加入的小鸡指向小鸡4 是不是就加进去了。
这么一说应该就明白了,如果不明白,那么就该放弃数据结构了。链表没有容器这个概念了。如果有,就看你的内存有多大了。
代码实现 :
单向链表实现的是List接口:
存储单元:存储的是一个个节点
节点是什么:节点是一个内部类,里面包含自身数据和一个指向。看过千手观音吧,从正面看就是一个人,里面实际有很多人,链表的存储结构就好像,是在一维里面开辟出多维。也可以这样说,你打开一个箱子,箱子里面有两部分,一部分装着数据一部分装着另一个箱子
在这里插入图片描述
打开箱子0里面有数据0和箱子1,打开箱子1里面有数据1和箱子2,打开箱子2 里面有数据2和箱子3 直至结束。这里实现方式是最外面的箱子永远不变,从第二层开始进行
先看接口构造:

    public interface List<E> {
    	/*
    	 * 获取线性表中元素的个数  线性表的长度
    	 *@return   线性表中的有效元素的个数	
    	 */
    	
    	public int getSize();
    	
    	/*
    	 * 判断线性表是否为空
    	 *@return  是否为空	
    	 */
    	
    	public boolean isEmpty();
   
	
	public void add(int index,E e);
	
	//表头添加元素
	public void addFirst(E e);
	
	//表尾添加元素
	public void addLast(E e);
	
	//在表中根据指定角标获取元素,指定角标大于0小于角标的个数size
	public E get(int index);
	
	//获取表头元素 返回值为表头元素 0
	public E getFirst();
	
	//获取表尾元素  返回值为表尾元素   size-1
	public E getLast();
	
	//修改线性表中指定index处的元素为E  没有返回值
	public void set(int index,E e);
	
	//判断线性表中是否包含指定元素e  参数为E   返回值为boolean 
	public boolean contains(E e);
	
	//在线性表中获取元素角标  从前往后找   参数为E  返回值为int   返回数据角标
	public int find(E e);
	
	//在线性表中  根据指定角标 删除元素  并返回该元素    角标范围为:0至size-1
	public E remove(int index);
	
	//在线性表中 删除表头元素 返回表头元素
	public E removeFirst();
	
	//在线性表中 删除表尾元素  返回删除元素	
	public E removeLast();
	
	//在线性表中根据元素删除指定元素  
	public void removeElement(E e);

	//清空线性表  无返回值  无参数
	public void clear();
	
	public boolean equals(Object obj);

看单向链表实现:

1.你先得有一个箱子   这里设为私有的一个内部类,是隐藏实现细节,不让数据被外部获得。
private class Node<E>{
		private  E   data;//存数据
		prvate Node  next;//存下一个箱子;这里只要记住next就行,next代表的是下一个箱子
		//定义构造方法,将数据和箱子放入箱子
		public Node(E data,Node next){
				this.data=data;
				this.next=next;
		}
}	
箱子已经有了,那么要对箱子进行操作了。
public clss LinkedList<E> implements List<E>{
private class Node{
//箱子放在这里,保护箱子
}
private  Node<E> head;  //最外层的箱子
private Node<E> rear;    //最内层的箱子
private int size;              //共有多少个箱子
//对管理箱子的东西进行初始化。先创建一个箱子,最外层的箱子就是这个箱子,最里层的箱子也是这个箱子
public LinkedList(){
head =new Node();
rear=head;
size=0;
//现在没有任何箱子,只有管理工具
}

public int getSize(){
	//获得箱子的个数
	return size;
}
    	
    	/*
    	 * 判断线性表是否为空
    	 *@return  是否为空	
    	 */
    	
    	public boolean isEmpty(){
				return rear==0&&head==0;    //当管理工具中没有箱子时,那管理工具就是空的				
		}
   
	//往工具里面添加箱子
	public void add(int index,E e){
			//对要进入哪一层进行判断
			if(index<0||index>size){
				throw new Exception("你选择的箱子不存在");
			}
		
			Node n=new Node();  //	创建一个新箱子
			n.data=e;
			if(index==0){
					//往箱子里面装入这个新箱子				
				n.next=head.next;
				head.next=n;			
				rear=n;	
			}else if(index==size){
			//往最里层的箱子装东西
			rear.next=n;
			n.next=null;
			rear=n;
		}else{
        //往既不是头也不是尾的地方装箱子
        //这里创建一个临时箱子
      		Node p=new Node();
       		for(int i=0;i<index;i++){
				//从头开始拆箱子,直到拆开第index个箱子
			    p=head.next;
			}
			//取出来第index个箱子后,让新创建的箱子n的下一个指向第index的箱子的下一个,然后让第index箱子的下一个指向n		
			n.next=p.next;
			p.next=n;
        }
	size++;
	}
	
	//表头添加元素
	public void addFirst(E e){
			add(0);
	}

	//表尾添加元素
	public void addLast(E e){
			add(size);
	}
	
	//在表中根据指定角标获取元素,指定角标大于0小于角标的个数size
	public E get(int index){
		//拆箱
		if(index<0||index>size){
				throw new Exception("你选择的箱子不存在");
		}
		if(index==0){
		//取第一个箱子里面的第一个箱子
		 return   head.next.data;
		}else if(index==size){
		//去最后一个箱子里面的东西
		return rear.data;
		}else{
		  		Node p=new Node();
				for(int i=0;i<index-1;i++){
						p=head.next;
				}
			return  p.data;
		}
	
	}
	
	//获取表头元素 返回值为表头元素 0
	public E getFirst(){
		get(0);

	}
	
	//获取表尾元素  返回值为表尾元素   size-1
	public E getLast(){
			get(size);
	}
	
	//修改线性表中指定index处的元素为E  没有返回值
	public void set(int index,E e){
				if(index<0||index>size){
				throw new Exception("你选择的箱子不存在");
	         	}
	         	Node p=new Node();
	         	for(int i=0;i<index;i++){
					p=head.next;
				}
				p.data==e;

	}
	
	//判断线性表中是否包含指定元素e  参数为E   返回值为boolean 
	public boolean contains(E e){
				if(find(e)!==-1)return true;
			return false;

	}
	
	//在线性表中获取元素角标  从前往后找   参数为E  返回值为int   返回数据角标
	public int find(E e){	
		  for(int i=0;i<size;i++){
			      if(head.next.data==e) return i;
		}
		return -1;
	}
	
	//在线性表中  根据指定角标 删除元素  并返回该元素    角标范围为:0至size-1
	public E remove(int index){
				if(index<0||index>size){
				throw new Exception("你选择的箱子不存在");
	         	}
	         	Node p1=new Node();
	         	Node p2=new Node();
	         	  
	         //获取index的后一个元素 与前一个元素,让前一个元素指向后一个元素	
	         if(index==0){
	             p2=get(index+1);
				head.next=p2;
			}else if(index==size){
				p1=get(index-1);
				p1.next=null;
				rear=p1;
			}else{
					 p1=get(index-1);
                     p2=get(index+1);
                       p1.next=p2;
			}
             return  get(index).data;
	}
	
	//在线性表中 删除表头元素 返回表头元素
	public E removeFirst(){
		    remove(0);

		}
	
	//在线性表中 删除表尾元素  返回删除元素	
	public E removeLast(){
			return   remove(size);
	}
	
	//在线性表中根据元素删除指定元素  
	public void removeElement(E e){
			remove  find(e);

		}

	//清空线性表  无返回值  无参数
	public void clear(){
				head=null;
				rear=null;
				size=0;

		}

以上均为手打,如有错误请批评指正,后期上传测试过的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值