《数据结构与算法》之链表—单向链表

链表(LinkedList)

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列节点(链表中每一个元素称为节点)组成,节点可以在运行时动态生成。每个节点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个节点地址的指针域。

相比于线性表顺序结构,链表操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

链表分为单链表和双向链表。

1、单向链表(Single-Linked List)

单链表是链表中结构最简单的。一个单链表的节点(Node)分为两个部分,第一个部分也就是数据部分,保存关于节点的数据信息,另一个部分则存储下一个节点的地址。当然,最后一个节点存储地址的部分指向空值。

对于单向链表,我们只可以单方向进行遍历,也就是从头节点往后依次访问后面的节点,一直访问到需要的位置。而插入一个节点,则只能在链表头插入,只需要将当前插入的节点设置为头节点,next指向原头节点可。删除一个节点,需要将该节点的上一个节点的next指向该节点的下一个节点。

public class SingleLinkedList {
    private int size;//链表节点的个数
    private Node head;//链表的头节点
    
    //链表构造函数
    public SingleLinkedList(){
        size = 0;
        head = null;
    }
    
    //链表的节点类
    private class Node{
        private Object data;//每个节点的数据
        private Node next;//每个节点指向下一个节点的连接
        
        public Node(Object data){
            this.data = data;
        }
    }
    
    //在链表头添加元素
    public Object addHead(Object obj){
        Node newHead = new Node(obj);
        if(size == 0){
            head = newHead;
        }else{
            newHead.next = head;
            head = newHead;
        }
        size++;
        return obj;
    }
    
    //在链表头删除元素
    public Object deleteHead(){
        Object obj = head.data;
        head = head.next;
        size--;
        return obj;
    }
    
    //查找指定元素,找到了返回节点Node,找不到返回null
    public Node find(Object obj){
        Node current = head;
        int tempSize = size;
        while(tempSize > 0){
            if(obj.equals(current.data)){
                return current;
            }else{
                current = current.next;
            }
            tempSize--;
        }
        return null;
    }
    
    //删除指定的元素,删除成功返回true
    public boolean delete(Object value){
        if(size == 0){
            return false;
        }
        Node current = head;
        Node previous = head;
        while(current.data != value){
            if(current.next == null){
                return false;
            }else{
                previous = current;
                current = current.next;
            }
        }
        //如果删除的节点是第一个节点
        if(current == head){
            head = current.next;
            size--;
        }else{  //如果删除的节点不是第一个节点
            previous.next = current.next;
            size--;
        }
        return true;
    }
    
    //判断链表是否为空
    public boolean isEmpty(){
        return (size == 0);
    }
    
    //显示节点信息
    public void display(){
        if(size >0){
            Node node = head;
            int tempSize = size;
            if(tempSize == 1){//当前链表只有一个节点
                System.out.println("["+node.data+"]");
                return;
            }
            while(tempSize>0){
                if(node.equals(head)){
                    System.out.print("["+node.data+"->");
                }else if(node.next == null){
                    System.out.print(node.data+"]");
                }else{
                    System.out.print(node.data+"->");
                }
                node = node.next;
                tempSize--;
            }
            System.out.println();
        }else{//如果链表一个节点都没有,直接打印[]
            System.out.println("[]");
        }
        
    }

}

测试程序代码如下:

public static void SingleLinkedListTest(){
	    SingleLinkedList singleList = new SingleLinkedList();
	    singleList.addHead("1");
	    singleList.addHead("2");
	    singleList.addHead("3");
	    singleList.addHead("4");
	    //打印当前链表信息
	    singleList.display();
	    //删除3
	    singleList.delete("3");
	    singleList.display();
	    //查找4
	    System.out.println(singleList.find("4"));
	}

用单向链表实现栈,其中栈的pop()方法和push()方法,分别可以用头部删除元素方法deleteHead()以及头部增加元素方法addHead()实现。

public class StackSingleLink {
	private SingleLinkedList link;
	
	public StackSingleLink() {
		link = new SingleLinkedList();
	}

	// 添加元素
	public void push(Object obj) {
		link.addHead(obj);
	}

	// 移除栈顶元素
	public Object pop() {
		Object obj = link.deleteHead();
		return obj;
	}

	// 判断是否为空
	public boolean isEmpty() {
		return link.isEmpty();
	}

	// 打印栈内元素信息
	public void display() {
		link.display();
	}

}

测试程序代码:

private static void StackSingleLinkTest() {
		StackSingleLink linklist=new StackSingleLink();
		linklist.push("123");
		System.out.println(linklist.isEmpty());
		linklist.display();
		linklist.pop();
		System.out.println(linklist.isEmpty());
		linklist.display();
	}

 

 

猜你喜欢

转载自blog.csdn.net/manbulaiyinhepan/article/details/83714345