`
linglingxia
  • 浏览: 38072 次
  • 性别: Icon_minigender_2
  • 来自: 湖南
社区版块
存档分类
最新评论

链表小结

阅读更多

                          链表(线性链表)

现在我们开始学习数据结构了,数据结构到底是什么,从名称上讲,应该是数据在计算机内部的存储方法。不过,这只是个概念而已,都说重要的还是要了解内涵。

 链表是一种常见的基础数据结构,是一种物理存储单元上非连续,非线性的存储结构,数据元素的逻辑顺序是通过链表中 的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点包括两个域,其中存储数据元素信息的域称为数据域,存储其他结点的存储位置的域称为指针域。

现在我暂时还不清楚链表到底是一种线性的,还是非线性的。找了下资料,问了同学说法不一,我也完全不清楚。。。所以,只能做暂时的小结。

线性链表有:单链表,双向链表,循环链表。

顺序存储结构和这种链式存储结构还是有很大差异的。前者可以随机存储表中的任一元素,但是一涉及到插入或删除操作就比较麻烦了。而后者刚好方便的能解决那个插入或删除的问题,不过它又不能随机获取元素,因为它是没有下标的。

简单介绍下单链表的创建,元素添加,删除,更新

首先链表是有一系列结点链接而成的,所以,首先要定义这样一个需要的结点类,它包括两个属性(一个基本数据类型,一个结点类型),这里用链表来实现队列 

1. 结点有了,就可以创建链表队列了,其实创建链表的过程也可以是不断添加元素的过程。

public void add(LinkNode node){

       //判断此时的根结点是否为 空

       if(root==null){  //若为空,则将新的元素作为根结点

           root=node;

           end=root;

       }else {       //若不为空,则添加在队列的末尾

           end.setNext(node);

           end=node;

       }

    }

 

 

 

 

 

 

 

 

 

这个也主要是判断是否加入的是第一个结点,是的话就将它设为根结点,不是的话就在原来链表的末尾添加就行了。 

2.有了链表队列,就可以计算它的长度,计算长度其实也就是遍历这个链表的过程,用一个计数器就可以完成。也可以根据索引来获取元素,原理和求长度是一样的。

 

/**
	 * 计算队列的长度
	 * @return
	 */
	public int size(){
		int count=0;
		Object obj=root.getObj();
		if(obj==null){
			return 0;
		}else{
			count++;
			LinkNode node=root.getNext();
			while(node!=null){
				count++;
				node=node.getNext();
			}
		}
		return count;
	}
	/**
	 * 任意获取队列中的元素
	 * @param index 要查找元素的下标
	 * @return
	 */
	public Object get(int index){
		int count=0;   //定义一个计数器
		//判断所提供的下标是否符合要求
		if(index>=this.size()||index<0){   //若不符,则报异常
		    throw new RuntimeException(""+index);  
		}else{ //若符合要求
			if(index==0){ //判断是否是 头结点
				return  root.getObj();
			}
			else { 
				LinkNode node=root.getNext();
				while(node!=null){
					count++;
					if(count==index){
						return  node.getObj();
					}
					else node=node.getNext();
				}
			}
		}
		return null;
	}

 

 

 

3.这个插入的过程就有点不一样了,这个也是和顺序表不同的地方。只要找到要插入的位置就可以将新的元素顺利的入队。这里只要修改下某些结点的前后继关系就好。这里还要注意的是看要插入的位置是否是第一个结点处。因为这样是要修改头结点的,其他位置上的操作都是一样的。

 

/**

     * 向已知的队列中插入新的元素

     * @param Node 待插入的元素

     */

    public  void insert(LinkNode node1,int index){

       int count=0;   //定义一个计数器

       //判断所提供的下标是否符合要求

       if(index>=this.size()||index<0){   //若不符,则报异常

           throw new RuntimeException(""+index);  

       }else{ //若符合要求

           if(index==0){ //判断是否是 插在队列的头

             node1.setNext(root);

             root=node1;

           }

           if(index==1){ //判断是否是插在下标为1的位置上

              node1.setNext(root.getNext());

              root.setNext( node1);

           }

           else { 

              count++;

               LinkNode  node=root.getNext(); 

              while(count<index){

                  if(count==index-1){

                     LinkNode node2=node.getNext();//获取指定为位置前一个的元素

                      node.setNext(node1);       //将新的元素作为指定位置前一个的直接后继

                      node1.setNext(node2);     //将新元素的后继赋值为指定位置的元素

                  }

                  node=node.getNext();

                  count++;

              }

           }

       }

    }

 


4.删除操作也有一个和插入类似的问题就是被删除结点是第一个结点。这种情况只需使root的指向第二个结点。若被删结点不是第一个结点,这种情况使被删结点的前一结点指向被删结点的后一结点可以了

/**

     * 在已知的队列中删除指定位置的元素

     * @param index  指定的位置

     */

    public void delete(int index){

       int count=0;   //定义一个计数器

       //判断所提供的下标是否符合要求

       if(index>=this.size()||index<0){   //若不符,则报异常

           throw new RuntimeException(""+index);  

       }else{ //若符合要求

           if(index==0){ //判断是否删除头结点

              root=root.getNext();
   }
                else if(index==1){ //判断是否是删除下标为1的元素

              LinkNode node=root.getNext();

              root.setNext(node.getNext());

           }

           else{

              count++;

               LinkNode  node=root.getNext(); 

              while(count<index){

                  if(count==index-1){ //找到要删除位置的前一个位置

                     LinkNode node1=node.getNext();//获得要删除位置上的元素

                     LinkNode node2=node1.getNext(); //获得要删除后一个位置的元素

                      node.setNext(node2);  //直接将指定的位置的前一个位置的后继修改为指定位置的后继

                  }

                  node=node.getNext();

                  count++;
              }

           }

       }

    } 


5.这个是修改指定位置的结点元素,找到要修改的前一个位置,将它的next设为要修改的那个,再将它的next修改为指定位置元素的原后继就可以了。

public void revamp(LinkNode  node1,int index){
		int count=0;   //定义一个计数器
		//判断所提供的下标是否符合要求
		if(index>=this.size()||index<0){   //若不符,则报异常
		    throw new RuntimeException(""+index);  
		}else{ //若符合要求
			if(index==0){ //判断是否是 插在队列的头
			  node1.setNext(root.getNext());
			  root=node1;
			}
			if(index==1){ //判断是否是插在下标为1的位置上
			   node1.setNext(root.getNext().getNext());
			   root.setNext( node1);
			}
			else { 
				count++;
			    LinkNode  node=root.getNext(); 
				while(count<index){
					if(count==index-1){
						node1.setNext(node.getNext().getNext());
						node.setNext(node1);  //直接将指定的位置的前一个位置的后继更换为要修改的
						
					}
					node=node.getNext();
					count++;
				}
			}
		}
	}



 这里主要简单的讲了下单链表,其实双向链表和循环链表跟这个也是非常类似的,只要稍作修改就可以完成了。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics