数据结构——链表

程序员.jpg

本篇文章主要是用做代码分享。代码,注释都写得很清楚,不清楚的可以问我,如果有些不对的地方也可以提出来,以便我及时改正。

接口类
//链表接口类(使用泛型)
public interface ILinkList<E> {
    boolean isEmpty();  //判空
    boolean isFull();   //判满
    int length();   //计算链表长度
    void insertAfter(Node<E> p, E x) throws Exception;  //在指定节点p后面插入新元素
    void insertBefore(Node<E> p, E x);  //在指定结点p前面增加元素
    void remove(Node<E> p) throws Exception;    //删除元素
    int removeAll(E x); //删除结点的单链表中的数据域为x的所有结点,返回被删除结点的个数
    int search(E x);    //按值查找操作
    E getelement(int i) throws Exception;   //按序号查找操作
    void showList();    //遍历输出
    void clear();   //清空表
    void insertBefore(Node<E> p,Node<E> x); //在p结点的前面插入结点x
    void insertAfter(Node<E> p,Node<E> x);  //在p结点的后面插入x结点
    Node<E> search2(E x);   //查找链表值为x的结点
}
结点类
//结点类
public class Node<E> {
    private E data; //数据域
    private Node<E> next;   //指针域

    public Node(E data, Node<E> next) {
        super();
        this.data = data;
        this.next = next;
    }

    public Node(E data) {
        super();
        this.data = data;
    }

    public Node() {
        super();
    }

    public E getData() {
        return data;
    }

    public void setData(E data) {
        this.data = data;
    }

    public Node<E> getNext() {
        return next;
    }

    public void setNext(Node<E> next) {
        this.next = next;
    }

}
链表完成类
//单链表类
public class LinkList<E> implements ILinkList<E>{
    private Node<E> head;   //头指针,指向第一个结点
    //构造方法
    public LinkList(Node<E> head) {
        super();
        this.head = head;
    }

    public LinkList() {
        super();
    }

    public Node<E> getHead() {
        return head;
    }

    public void setHead(Node<E> head) {
        this.head = head;
    }

    @Override
    public boolean isEmpty() {
        // 判空
        return head == null;
    }

    @Override
    public boolean isFull() {
        // 判满,线性表永远不满,总有空间
        return false;
    }

    @Override
    public int length() {
        // 求长度
        int length = 0;
        Node<E> p = head;
        while(p != null){
            length++;
            p = p.getNext();
        }
        return length;
    }

    @Override
    public void insertAfter(Node<E> p, E x) throws Exception {
        // 在指定结点p后面插入数据x
        Node<E> s = new Node<E>(x, p.getNext());
        p.setNext(s);

//      若void改为Node<E>,则增加return s;
    }

    @Override
    public void insertBefore(Node<E> p, E x) {
        // 在指定节点p前面增加数据x
        Node<E> n = new Node<E>(x,p);   //创建数据域为x的新结点,并指向p
        Node<E> q = head;
        if(p == head)   //当p为第一个结点时
            head = n;
        else{
            while(q != null && q.getNext() != p)
                q = q.getNext();
            q.setNext(n);
        }
    }

    @Override
    public void remove(Node<E> p) throws Exception {
        // 删除指定结点p
        Node<E> q = head;
        if(p == null)   //先判断是否为空
            return;
        if(p == head){
            head = head.getNext();
            return;
        }
        //q遍历到p的前一个
        while(q.getNext() != null && q.getNext() != p)
            q = q.getNext();
        if(q.getNext() == p){
            q.setNext(p.getNext());
            return;
        }
    }

    @Override
    public int removeAll(E x) {
        // 删除结点的单链表中的数据域为x的所有结点,返回被删除结点的个数
        Node<E> p = head.getNext();
        Node<E> q = head;
        int count = 0;
        while(p != null){
            if(p.getData().equals(x)){
                q.setNext(p.getNext());
                count++;
            }else
                q = p;
            p = p.getNext();
        }
        return count;
    }

    @Override
    public int search(E x) {
        // 查找数据域为x的节点并返回下标
        int count = 0;
        Node<E> p = head;
        while(p != null && !p.getData().equals(x)){
            p = p.getNext();
            count++;
        }
        if(p == null)
            return -1;
        return count;
    }

    @Override
    public E getelement(int i) throws Exception {
        // 按序号查找数据操作
        Node<E> p = head;
        int j = 0;
        while(p != null && j < i){
            p = p.getNext();
            j++;
        }
        if(j > i || p == null)
            throw new Exception("第" + j + "个元素不存在!");
        return p.getData();
    }

    @Override
    public void showList() {
        // 遍历输出
        Node<E> p = head;
        while(p != null){
            System.out.print(p.getData() + " ");
            p = p.getNext();
        }
        System.out.println();
    }

    @Override
    public void clear() {
        // 清空表
        head = null;
    }

    @Override
    public void insertBefore(Node<E> p, Node<E> x) {
        // 在p结点的前面插入结点x
        if (p==head){
            head=x;
            x.setNext(p);
            return;
        }
        Node<E> q=head; 
        while(q.getNext()!=null&&q.getNext()!=p){
            q=q.getNext();
        }
        //查找成功时, q为p的前一个结点
        if (q.getNext()==p){//可能有不存在结点p的情况,如果存在,则进行下面的处理
            q.setNext(x);
            x.setNext(p);
        }
    }

    @Override
    public void insertAfter(Node<E> p, Node<E> x) {
        // 在p结点的后面插入x结点
        x.setNext(p.getNext());
        p.setNext(x);
    }

    @Override
    public Node<E> search2(E x) {
        // 查找链表值为x的结点
        Node<E> p = head;
        while (p != null && !p.getData().equals(x)) {
            p = p.getNext();
        }
        return p;
    }
}
测试类
public class TestLinkList01 {

    public static void main(String[] args) throws Exception {
        final int LENGTH = 5;   //链表的初始长度
        LinkList<Integer> link = new LinkList<Integer>();

        //创建由随机数构成的链表
        Node<Integer> p = new Node<Integer>((int)(Math.random()*LENGTH)+1);
        link.setHead(p);
        for(int i = 1; i < LENGTH; i++){
            Node<Integer> x = new Node<Integer>((int)(Math.random() * LENGTH) + 1);
            p.setNext(x);
            p = x;
        }
        link.showList();
        System.out.println("表中数据长度是:" + link.length());

        System.out.println(link.isEmpty());
        System.out.println(link.isFull());
        System.out.println(link.search(2));
        int x = 2;
        Object q = link.getelement(x);
        System.out.println("下标为2的数据是:" + q);

//      if (p!=null){
//          //显示该结点及后继结点的数据
//          System.out.println("查找结果:"+p.getData()+"--->"+(p.getNext()==null?"":p.getNext().getData()));
//          //删除此结点
//          link.remove(p);
//          System.out.println("删除结点后:");
//          link.showList();
//      }

        Node<Integer> s = new Node<Integer>(508,p.getNext());
        link.insertAfter(p, s);
        link.showList();

        link.remove(p);
        link.showList();

        link.clear();
        link.showList();


    }
}
范例一
public class PhoneNumber {
    private String company;
    private String phone;
    public PhoneNumber(String company, String phone) {
        super();
        this.company = company;
        this.phone = phone;
    }
    public PhoneNumber() {
        super();
    }
    public String getCompany() {
        return company;
    }
    public void setCompany(String company) {
        this.company = company;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    @Override
    public String toString() {
        return "[company=" + company + ", phone=" + phone + "]";
    }
    @Override
    public boolean equals(Object p) {
        return this.company.equals(((PhoneNumber)p).getCompany());
    }

}
范例一测试类
import java.util.Scanner;

public class TestLinkList02 {
    public static void main(String[] args){
        final int LEN=5;
        Scanner sc=new Scanner(System.in);
        LinkList<PhoneNumber> phoneLink=new LinkList<PhoneNumber>();
        System.out.println("请输入第1个结点的数据(PhoneNum类型):");
        Node<PhoneNumber> p=new Node<PhoneNumber>(new PhoneNumber(sc.next(),sc.next()));
        phoneLink.setHead(p);       
        for(int i=1;i<LEN;i++){
            System.out.println("请输入第"+(i+1)+"个结点的数据(PhoneNum类型):");
            Node<PhoneNumber> x=new Node<PhoneNumber>(new PhoneNumber(sc.next(),sc.next()));
            p.setNext(x);
            p=x;            
        }
        phoneLink.showList();
        phoneLink.insertBefore(phoneLink.getHead(), new Node(new PhoneNumber("星星","400-578345")));
        System.out.println("表中共有"+phoneLink.length()+"个企业的信息.");
        phoneLink.showList();
        p=phoneLink.search2(new PhoneNumber("星星",null));
        if (p!=null){
            System.out.println("查找结果:"+p.getData().getPhone());
        }else
            System.out.println("未找到企业名称为星星的信息.");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值