链表——单向链表

链表是由许多相同数据类型的元素按特定顺序排列而成的线性表,其特性时在计算机内存的位置是不连续与随机储存的,优点是数据的插入和删除都很方便,有新数据加入就向系统要一块内存空间,数据删除后就把空间还给系统,不需要移到大量数据,缺点是设计数据结构时比较麻烦,另外在查找数据时,也无法向静态数据一样可以随机读取数据,必须按顺序找到该数据为止。

1.建立单向列表

单向列表时所以列表中最常见的一种,就像它火车,所以节点串成一列,而且指针所指的方向一样。也就是列表中的每个数据除了要储存原本的数据,还必须储存下一个数据的储存位置,所以在程序设计语言中,一个列表节点有两个字段,即数据字段和链接字段,列表的组成基本要件为节点,而且每个节点不必储的存于连续的内存地址。

由于列表中的所有节点都知道节点本身的下一个节点在哪里,但是却没有办法知道前一个节点,所以“列表首”就特别重要,无论如何,只要列表首存在,就可以对整个列表进行遍历、加入和删除节点等操作,而之前建立的几点若没有串起来就会形成无人管理的节点,并一直占用内存空间。因此在建立列表时,必须有一列表指针指向列表首,并且除非必要否者不可移动列表首指针。

2.单向列表节点的插入

2.1在链表的第一个节点插入节点(头插法)

只需要把新节点的指针指向表头,再把表头移到新节点即可。

public void inserthead(int val) {
        Entry entry = new Entry(val);
        entry.next = head.next;
        head.next = entry;
    }

2.2在链表的最后一个节点插入节点(尾插法)

把列表的最后一个节点指向新节点,新节点再指向null即可。

public void insertTail(int val)
    {
        Entry cur = head;
        while(cur.next!= null)  //循环直到cur.next为空  把cur弹出
        {
            cur = cur.next;
        }
        cur.next = new Entry(val);//给cur.next 赋值为新节点的地址

    }

2.3在链表的中间位置插入节点

如果插入的节点在X与Y之间,只要将X节点的指针指向新节点,新节点的指针指向Y节点即可。

这里写图片描述

这里写图片描述

以下是java插入节点的算法:

public void inster(int pos,int val) {
        int i=0;
        Entry cur = head;//获取头结点
        while(cur.next != null) {
            if(i == pos){
                break;
            }
            i++;
            cur = cur.next;
        }
        Entry entry = new Entry(val);
        entry.next = cur.next;
        cur.next = entry;
    }

3.单向列表节点的删除

3.1删除列表的第一个节点

只要把列表指针指向第二个节点即可。

这里写图片描述

public void shanchead() {
        head = head.next;
    }

3.2删除列表的中间节点

只要将删除节点的前一个节点的指针,指向要删除的节点的下一个节点即可,

这里写图片描述

public void shanc(int val) {
        Entry cur = head.next;
        Entry pwd = head;
        while(cur.next != null) {
            if(cur.data == val) {
                break;
            }
            cur = cur.next;
            pwd = pwd.next;
        }
        pwd.next = cur.next;
    }

3.2删除列表的最后一个节点

只要将指向最后一个节点的指针,指向null即可。

这里写图片描述

public void shanclast() {
        Entry cur = head.next;
        Entry pwd = head;
        while(cur.next != null) {
            cur = cur.next;
            pwd = pwd.next;
        }
        pwd.next = null;
    }
}

范例:

/*
 * 单链表
*/
class Outer {

    class Entry {
        int data;
        Entry next;
        /**
         * 头结点,空构造方法
         */
        public Entry() {
            data = 0;
            next = null;
        }
        /**
         * 构造节点
         * @param a
         */
        public Entry(int data) {
            this.data = data;
            next = null;
        }
    }

    private Entry head = new Entry();//指向头结点的引用
    /**
     * 头插法
     * @param val 需要插入的数据
     */
    public void inserthead(int val) {
        Entry entry = new Entry(val);
        entry.next = head.next;
        head.next = entry;
    }
    /**
     * 尾插法
     * @param val 需要插入的值
     */
    public void insertlast(int val) {
        Entry cur = head;
        while(cur.next!= null) { //循环直到cur.next为空  把cur弹出
            cur = cur.next;
        }
        cur.next = new Entry(val);//给cur.next 赋值为新节点的地址
}
    /**
     * 插入到pos位置 从有数据开始为0下标
     * @param pos   位置序号
     * @param val   插入的值
     */
    public void inster(int pos,int val) {
        int i=0;
        Entry cur = head;//获取头结点
        while(cur.next != null) {
            if(i == pos){
                break;
            }
            i++;
            cur = cur.next;
        }
        Entry entry = new Entry(val);
        entry.next = cur.next;
        cur.next = entry;
    }
    /**
     * 删除头节点
     */
    public void shanchead() {
        head = head.next;
    }
    /**
     * 删除尾节点
     */
    public void shanclast() {
        Entry cur = head.next;
        Entry pwd = head;
        while(cur.next != null) {
            cur = cur.next;
            pwd = pwd.next;
        }
        pwd.next = null;
    }
    /**
     * 删除指定元素
     */
    public void shanc(int val) {
        Entry cur = head.next;
        Entry pwd = head;
        while(cur.next != null) {
            if(cur.data == val) {
                break;
            }
            cur = cur.next;
            pwd = pwd.next;
        }
        pwd.next = cur.next;
    }
     /*
       * 反转链表
      */
    public void back(){
        Entry x = head.next;
        Entry x1 = null;
        Entry x2 = null;
        while( x !=null) {
            x1 = x.next;
            x.next = x2;
            x2 = x;
            x = x1;
        }
        head.next = x2;
    }
    /**
     * 获得链表长度
     * @return 链表长度
     */
    public int getlength() {
        int i=0;
        Entry cur = head;
        while(cur.next != null) {
            cur = cur.next;
            i++;
        }
        return i;
    }
    /**
     * 求倒数第K个元素
     * 
     * @param k 序号
     * @return 所求元素
     */
    public int daok(int k) {
        if(k<0 || k>getlength()-1) {
            System.out.print("该下标不合法!");
            return -1;
        }
        int x = getlength()-k;
        int i=0;
        Entry cur = head.next;
        while(cur.next != null) {
            if(x==i) {
                break;
            }
            cur = cur.next;
            i++;
        }
        return cur.data;
    }
    /**
     * 遍历输出
     */
    public void show() {
        Entry cur = head.next;
        while(cur != null) {
            System.out.print(cur.data+" ");
            cur = cur.next;
        }
        System.out.println();
    }
}
public class DanLianBiao {

    public static void main(String[] args) {
        Outer s = new Outer();
        /*头插法
        */
        /*s.inserthead(25);
        s.inserthead(35);
        s.inserthead(36);
        s.inserthead(68);
        s.show();*/
        /*尾插法
        */
        s.insertlast(25);
        s.insertlast(35);
        s.insertlast(36);
        s.insertlast(68);
        s.show();
        /*  删除元素    
         * */
        /*s.shanchead();//删除头节点
        s.show();

        s.shanclast();//删除尾节点
        s.show();*/

        s.shanc(36);
        s.show();
        /*指定位置插入
        */
        /*s.inster(0, 258);
        s.inster(2, 368);
        s.show();*/
        /*倒数第k个元素
         * */   
        /*System.out.println(s.daok(3));
        System.out.println(s.daok(-1));*/
       /*反转
        */
        /*s.back();
        s.show();*/
    }

}

我和我舍友的名字和床号用单链表实现:

class OuterQuick {
    class Entry {
        int data;
        String name;
        Entry next;

        public Entry() {
            this.data = 0;
            this.name = null;
            this.next = null;
        }

        public Entry(String name,int data) {
            this.data = data;
            this.name = name;
            this.next = null;
        }
    }

    private Entry head = new Entry();

    /**
     * 头插法
     * @param   name  名字
     * @param   val   数据
     */
    public void inserthead(String name,int data) {
        Entry entry = new Entry(name,data);
        entry.next = head.next;
        head.next = entry;
    }

    /**
     * 尾插法
     * @param   name  名字
     * @param   val   数据
     */
    public void insertlast(String name,int data) {
        Entry cur = head;
        while(cur.next != null) {
            cur = cur.next;
        }
        Entry entry = new Entry(name,data);
        cur.next = entry;
    }

    /**
     * 指定位置插入
     * @param   pos   指定的位置
     * @param   name  名字
     * @param   val   数据
     */
    public boolean insert(int pos,String name,int data) {
        if(pos < 0 ){
            return false;
        }
        int i = 0;
        Entry cur = head;
        while(cur.next != null) {
            if(i == pos) {
                break;
            }
            cur = cur.next;
            i++;
        }
        Entry entry = new Entry(name,data);
        entry.next = cur.next;
        cur.next = entry;
        return true;
    }


    /**
     *判空
     */
    public boolean isEmpty() {
        if(head.next == null) {
            return true;
        }
        return false;
    }
    /**
     * 删除元素
     * @param   key   要删除的数据
     * @return 
     */
    public boolean delete(int key) {
        if(isEmpty()) {
            return false;
        }
        Entry cur = head;
        Entry pwd = head.next;
        while(pwd != null) {
            if(pwd.data == key) {
                break;
            }
            cur = cur.next;
            pwd = pwd.next;
        }
        cur.next = pwd.next;
        return true;
    }


    public void show() {
        Entry cur = head;
        while(cur.next != null) {
            cur = cur.next;
            System.out.println(cur.name+" "+cur.data);
        }
    }
}

public class LianXi{

public static void main(String[] args) {
    OuterQuick s = new OuterQuick();
    /*s.inserthead("李正全", 6);
    s.inserthead("代云鹏",5);
    s.inserthead("郭栋", 4);
    s.inserthead("吴海波", 3);
    s.inserthead("黄苗杰", 2);
    s.inserthead("万琳琨", 1);*/
    /*s.insertlast("万琳琨", 1);
    s.insertlast("吴海波", 3);
    s.insertlast("李正全", 6);
    s.insertlast("郭栋", 4);
    s.insertlast("黄苗杰", 2);
    s.insertlast("代云鹏",5);*/
    s.insert(0, "代云鹏",5);
    s.insert(1, "郭栋", 4);
    s.insert(2,"万琳琨", 1);
    s.insert(3, "李正全", 6);
    s.insert(4, "黄苗杰", 2);
    s.insert(5, "吴海波", 3);
    s.delete(5);
    s.show();
    }
}

猜你喜欢

转载自blog.csdn.net/qq2899349953/article/details/80159728