java数据结构和算法 栈表队列2

1 链表(双向)

 每个对象包括一个关键字域和两个指针域prev,next;链表是一种动态的数据结构,其操作需要通过指针进行。链表内存的分配不是在创建链表时一次性完成,而是每添加一个节点就分配一次内存。由于没有闲置内存。他的空间效率比数组更高。

相对于数组,长度可变;插入删除更容易。

(单向链表):从头插 从尾插 

public class LinkList {
	Node first;
	public class Node{
		 public int iData;     
		 public double dData; 
		 public Node next;
		 public Node(int id, double dd) 
		 {         this.iData = id;         
		 this.dData = dd;     } 
		 public void displayLink() {         
			 System.out.println("{" + iData + "," + dData + "}");     } 
		
	}
	
	LinkList(){
		first=null;
	}
	public void addfirst(int id, double dd){
		Node node=new Node(id,dd);
		node.next=first;
		first=node;
	}
	
	public void addlast(int id, double dd){
		 Node node = new Node(id, dd);          // 将新链接点的关系子段 next 指向旧的首链接点。     
		
	        Node p = first;
	        // 注意链表为空的时候的插入
	        if(first==null){
	        	first = node;
	        }
	        // 尾插法
	        else{
	            while(p.next != null){
	                p = p.next;
	            }
	            p.next = node;
	        }
	}
	public  Node deletefirst(){
		Node p=first.next;
		first=p;
		return first;
	}
	
	public  Node deletelast(){
		Node p=first.next;
		first=p;
		return first;
	}
	
	public Node select(int key){
		Node current=first;
		while(current.iData!=key){
		  if(current.next!=null){
			  current=current.next;
		  }
		  else {     System.out.println("没有找到数据");             
		  current = null;                 
		  break;             }
		}
		return current;
	}
	
	public void delectelike(int key){
		Node current=first;
		Node previous=first;
		boolean isfind=true;
		while(current.iData!=key){
			if(current.next!=null){
				current=current.next;
				previous=current;
			}
			else{System.out.println("没有找到数据");             
			  current = null;  
			  isfind = false; 
				
			}
			
		}
		if(isfind==true){
			if(current==first){
				first=first.next;
			}
			else {previous.next=current.next;}
			
		}
		{
			System.out.println("no find the Data of delete");
		}
	}
	
	public Node displayList() {          
		 System.out.println("List (fist - -> last )");        
		 Node top = first;          
		 while (top != null) { 
			// top.displayLink();    
			 System.out.println("{" + top.iData + "," + top.dData + "}");
		 top = top.next;         }                  
		 return top; 
	    }
	 public boolean isEmpty() {         return (first == null);     } 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		 LinkList l = new LinkList();         // 增加          
		 l.addfirst(1, 234);         
		 l.addfirst(2, 332);        
		 l.addfirst(3, 32);        
		 l.displayList();         // 查询          
		Node findLink = l.select(2);         
		if (findLink != null) {              
			 System.out.println(findLink.dData);         }          // 删除   
		l.delectelike(2);         
		 l.displayList(); 
	}

}

(双向链表)



代码:

public class DoubleLinkedList {
    // 哨兵节点nil(作为表头指针)
    private Node nil;
    // 初始化一个链表
    DoubleLinkedList(){
        nil = new Node();
        nil.next = nil;
        nil.prev = nil;
        count = 0;
    }
    // 链表长度
    private int count;
    private static class Node{
        int item;
        Node next;
        Node prev;

        Node(){
            item = 0;
            next = null;
            prev = null;
        }
        Node(int item, Node next, Node prev){
            this.item = item;
            this.next = next;
            this.prev = prev;
        }
    }

    //返回当前链表的长度
    public int length(){
        return count;
    }

    //获取value为k的节点
    public Node listsearch(int k){
        Node result = null;
        Node head = nil;
        while(head.next != nil){
            if(head.next.item == k){
                result = head.next;
                break;
            }
            else
                head = head.next;
        }
        return result;
    }

    //插入一个节点在队首
    public void listinsert(Node node){
            node.next = nil.next;
            nil.next.prev = node;
            nil.next = node;
            node.prev = nil;
            count++;
    }
    //根据value删除一个节点
    public Node listdelete(Node node){
        Node head = nil;
        Node nodetodelete;
        while(head.next!=nil){
            if(head.next.item == node.item){
                nodetodelete = head.next; //将要删除的节点
                head.next = nodetodelete.next;
                nodetodelete.next.prev  = head;
                nodetodelete = null;

                count--;
            }
            else{
                head = head.next;
            }
        }
        return node;
    }
    //输出链表
    public void traverse(){
        Node head = nil;
        while( head.next!= nil){
            System.out.println(head.next.item);
            head = head.next;
        }
    }

3.3 扩展

1. 从尾到头打印链表

题目:输入一个链表的头节点,从尾到头打印出来每个节点的值。
解法:遍历,每遍历到的元素存到栈,然后输出栈即可。
代码:

	public Node displayList() {          
		 System.out.println("List (fist - -> last )");        
		 Node top = first;          
		 while (top != null) { 
			// top.displayLink();    
			 System.out.println("{" + top.iData + "}");
		 top = top.next;         }                  
		 return top; 
	    }

2. O(1)时间删除链表节点

题目:给定单链表的头指针和一个节点指针,O(1)时间删除该链表节点
解法:下一个节点的内容复制到需要删除的点,即覆盖。然后删该店的下一个节点。
这里需要考虑两个边界条件,1 要删除的点位于尾部 2 链表只有一个节点
要考虑鲁棒性。
代码:

public void deleteNode(Node head, Node pToDeleted){
        if(head!=null){
            //要删除的是尾节点
            if(pToDeleted.next == null){
                //如果要删除的是链表唯一的节点
                if(head.next==null){
                    head = null;
                    System.out.println(head);
                    pToDeleted = null;
                }
                else{
                    Node p = head;
                    while(p.next!=pToDeleted){
                        p = p.next;
                    }
                    p.next = null;
                    pToDeleted =null;
                }
            }
            //要删除的不是尾节点,且节点数大于1
            else{
                pToDeleted.item = pToDeleted.next.item;
                pToDeleted.next = pToDeleted.next.next;
                pToDeleted = null;
            }

        }else{
            System.out.println("the linklist is empty");
        }
    }


3. 倒数第k个节点

题目:输入一个链表,输出该链表第倒k个节点。(链表从1开始计数)
解法:定义两个指针,第一个指针从链表的head指针开始遍历,向前走k-1步的时候,第二个指针开始和它一起走。当第一个指针的next指向null的时候,第二个指针指向了倒数第k个。(这种一次遍历,对时间要求比较高的程序,就需要借助空间,再开辟一个指针)
要考虑鲁棒性。
代码:

//遍历链表一次,删除倒数第K个元素
    public Node FindKthToTail(Node head, int k){
        Node p=head;
        Node q = head;
        int i;
        if(head==null || k==0){
            return null;
        }
        for(i=0;i<k-1;i++){
            if(p.next !=null){
                p = p.next;
            }
            else{//当k大于链表的长度的时候
                System.out.println("error k");
                return null;
            }

        }

        while(p.next!=null){
            p = p.next;
            q = q.next;
        }
        return q;
    }

4. 反转链表

题目:定义一个函数,输入链表头节点,反转该链表并输出反转后链表的头节点。
解法:借助三个指针,prev, p, next. 避免指针断裂。
( 为了正确的反转一个链表,需要调整链表中指针的方向【指针反向】。注意,在单链表中,将一个节点的指向后继的指针指向它的前驱,将会导致链表的断裂。导致无法在单链表中遍历它的后继节点,因此,在调整某一节点的 next 指针时,需要首先将其的后继节点保存下来。)

 public Node reverse(){
        Node p = head;
        try{
            if(p!=null){
                Node pnext = p.next;
                p.next = null;
                while(pnext!= null){
                    Node r = pnext.next;
                    pnext.next = p;
                    p = pnext;
                    pnext = r;
                }
                }else{
                throw new Exception("empty list");
                }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            return p;
        }
    }






1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.m或d论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值