数据结构总结 链表、栈、队列、排序、数组、树

因为数据结构有一点难度,有些lazy的同学不愿意去深究,学完了代码都没打几个,没错说的就是你肖兆菲同学,以下我将我打的电脑代码复制粘贴过来


首先先看链表 



关于单链表:

1、概念

                在单链表中由于数据元素的存储空间一般不是连续的,因此为了完善的表示单链表的逻辑结构,其中每一个数据元素必须由两部分构成:一部分是数据元素中的数据值,另一部分是数据元素的地址值。这两部分信息构成了单链表的一个节点。因此,在用单链表表示线性表时,每个结点的存储地址是任意的,即存储位置是无序的。

2、结构

                对于单链表来说,每个节点的结构都是(data,next),节点中有两个部分:data域—存放结点值的数据域,next—存放结点的直接后续的地址的链域。


1.0

编写一个Node类来充当结点的模型。我们知道,其中有两个属性,1存放数据的data,2存放下一结点的引用,

public class Node<T> {                            			//单链表结点类,T指定结点的元素类型
	
	//1. 定义成员变量
    public T data;                               			//数据域,存储数据元素
    public Node<T> next;                         			//地址域,引用后继结点

	
    //2. 定义构造方法
    public Node(T data, Node<T> next) {            			//构造结点,data指定数据元素,next指定后继结点
        this.data = data;                        			//T对象引用赋值
        this.next = next;                        			//Node<T>对象引用赋值
    }
    public Node() {
        this(null, null);
    }
    public String toString() {                                //返回结点数据域的描述字符串
        return this.data.toString();
    }
}


2.2、单链表的简单操作(增加,删除,获取总长度,链表元素排序,链表遍历)


我们依次来实现以下方法

1 判断是否为空

2 获取设置某元素

3 获取大小

4 插入某元素

5 移除某元素

6 清除该链表

7查询某元素

8 包含某元素

9 插入不同元素

Node.java

   public Node{
    public Node<T> head;                                   	//头指针,指向单链表的头结点
   
    
   
    public SinglyList() {                                   //构造方法,构造空单链表
        this.head = new Node<T>();                         	//创建头结点,data和next值均为null
    }

 
    public SinglyList(T[] values) {
        this();                                            	//创建空单链表,只有头结点
        Node<T> rear = this.head;                          	//rear指向单链表最后一个结点
        for (int i = 0; i < values.length; i++) {          	//若values.length==0,构造空链表
            if (values[i] != null) {
                rear.next = new Node<T>(values[i], null);    //尾插入,创建结点链入rear结点之后
                rear = rear.next;                          	//rear指向新的链尾结点
            }
        }
    }


List.java

public interface List<T> {
    public boolean isEmpty();                           //判断线性表是否为空,若空返回true    
    public int size();                                  //返回线性表元素个数(长度)
    public  T get(int i);                               //返回第i个元素
    public void set(int i, T x);                        //设置第i个元素为x
    public String toString();                           //返回线性表所有元素的描述字符串

    public int insert(int i, T x);                      //插入x作为第i个元素,x!=null
    public int insert(T x);                             //在线性表最后插入x元素,返回x序号
    public T remove(int i);                             //删除第i个元素,返回被删除元素
    public void clear();                                //删除线性表所有元素
    public int search(T key);                           //查找首次出现的与key相等元素,返回元素序号i
    public boolean contains(T key);                     //判断是否包含关键字为key元素
    public int insertDifferent(T key);					//插入不重复元素
    public T remove(T key);                             //删除首次出现的与key相等元素,返回被删除元素
    public boolean equals(Object obj);                  //比较两个线性表所有元素是否对应相等
    
    //SeqList中有问题,暂时去掉此方法,2016.11.08
//    public void addAll(List<T> list);					//在this中添加list的所有元素,集合并运算
    
    public void print();								// *** 输出线性表(可以借用toString()方法) ****
}


SeqList.java

顺序链表

public class SeqList<T> implements List<T>, Iterable<T> { // 10.2.1,实现可迭代接口{

    protected Object[] element;                                 // 对象数组,保护成员
    protected int n;                                             // 顺序表元素个数(长度)
    private final static int LENGTH = 64;                         // 顺序表默认容量为64

   

    public SeqList() {                                             // 创建默认容量的空表,构造方法重载
        this(SeqList.LENGTH);                                     // 调用本类已声明的指定参数列表的构造方法
    }

    /**
     * 顺序表有参构造方法
     * 
     * @param length
     *            顺序表容量length
     */
    public SeqList(int length) {                                 // 构造容量为length的空表
        // // 容错技术
        length = length < 0 ? SeqList.LENGTH : length;             // 假如length<0,则构造默认容量的空表

        this.element = new Object[length];                         // 申请数组的存储空间,元素为null。
        // 若length<0,Java抛出负数组长度异常 java.lang.NegativeArraySizeException
        this.n = 0;
    }

    /**
     * 顺序表有参构造方法。
     * 
     * @param values
     *            存储元素数组
     */
    public SeqList(T[] values) {                                 // 构造顺序表,由values数组提供元素,忽略其中空对象
        this(values.length);                                     // 创建容量为values.length的空表
   
        for (int i = 0; i < values.length; i++) {                 // 复制数组元素,O(n)
            this.element[i] = values[i];                         // 对象引用赋值
        }

        this.n = values.length; // element.length;

 
    }
以下实现SeqList方法

public boolean isEmpty() {                                     // 判断顺序表是否空,若空返回true,O(1)
        return this.n == 0;
    }


public int size() {                                         // 返回顺序表元素个数,O(1)
        return this.n;
    }

public T get(int i) { // 返回第i个元素,0≤i<n。若i越界,返回null。O(1)
  

        if (i >= 0 && i < this.n)
            return (T) this.element[i];                         // 返回数组元素引用的对象,传递对象引用
        // return this.element[i]; //编译错,Object对象不能返回T对象
        return null;
    }


public void set(int i, T x) {
        if (x == null) {
            throw new java.lang.NullPointerException("x==null");     // 抛出空对象异常
        }
        if (i >= 0 && i < this.n) {
            this.element[i] = x;
        } else {
            throw new java.lang.IndexOutOfBoundsException(i + "");     // 抛出序号越界异常
        }
    }


public String toString() {
        String str = this.getClass().getName() + "(";             // 返回类名
        if (this.n > 0)
            str += this.element[0].toString();                     // 执行T类的toString()方法,运行时多态
        for (int i = 1; i < this.n; i++)
            str += ", " + this.element[i].toString();             // 执行T类的toString()方法,运行时多态
        return str + ") ";                                         // 空表返回()
    }


public int insert(int i, T x) {

        if (x == null) {
            throw new NullPointerException("x==null");         // 抛出空对象异常
        }

        // 以下两个语句用于容错处理
        if (i < 0) {
            i = 0;                                             // 插入位置i容错,插入在最前
        }
        if (i > this.n) {
            i = this.n;                                     // 插入在最后
        }

        // 以下语句用于扩容
        Object[] source = this.element;                     // 数组变量引用赋值,source也引用element数组
        if (this.n == element.length) {                     // 若数组满,则扩充顺序表的数组容量
            this.element = new Object[source.length * 2];     // 重新申请一个容量更大的数组
            for (int j = 0; j < i; j++) {                     // 复制当前数组前i-1个元素
                this.element[j] = source[j];
            }
        }


        // 以下语句用于原有元素后移
        for (int j = this.n - 1; j >= i; j--) {             // 从i开始至表尾的元素向后移动,次序从后向前
            this.element[j + 1] = source[j];
        }
        this.element[i] = x;

        // /// 添加元素后n加1
        this.n++;
        return i;
    }

    /**
     * 顺序表尾插入x元素,返回x序号。成员方法重载
     *
     * @param x
     *            插入的元素
     * @return 返回插入元素的索引位置
     */
    public int insert(T x) {                                 // 顺序表尾插入x元素,返回x序号。成员方法重载
        return this.insert(this.n, x);                         // 插入操作中,this.n加1
    }




我自己第一次写的SeqList版本

public class SeqList {  
    private int maxSize;  
    private int size;  
    private Object[] arrayList;  
    public SeqList(int sz){  
        maxSize=sz;  
        size=0;  
        arrayList=new Object[sz];  
    }  
      
    public void insert(int i,Object obj)throws Exception{//顺序表的 插入  
        if(size==maxSize)  
            throw new Exception("顺序表已满,无法插入!");  
        if(i<0||i>size)  
            throw new Exception("插入位置不存在!");  
          
        //for(int j=i;j<=size;j++)   
        //  arrayList[j+1]=arrayList[j];这不是每个后移了,这是把后面的每个都变成arrayList[j]  
          
        for(int j=size;j>i;j--){//这个才能实现真正的后移~!!  
            arrayList[j]=arrayList[j-1];  
        }     
           
        arrayList[i]=obj;  
        size++;  
    }  
      
    public Object delete(int i)throws Exception{//顺序表 删除  
        if(size==0)  
            throw new Exception("顺序表已为空");  
        if(i<0||i>size)  
            throw new Exception("删除位置不存在!");  
        Object obj=arrayList[i];  
        for(int j=i;j<size;j++){  
            arrayList[j]=arrayList[j+1];//前移~  
        }  
        size--;  
        return obj;  
    }  
      
    public Object getData(int i)throws Exception{//取值  
        if(i<0||i>size)  
            throw new Exception("该位置不存在!");  
        return arrayList[i];  
    }  
    public int getSize(){//大小  
        return size;  
    }  
    public boolean isEmpty(){//是否为空  
        return size==0;  
    }  


@SuppressWarnings("unchecked")
    public T remove(int i) {                                 // 删除第i个元素,0≤i<n,返回被删除元素。若i越界,返回null。//??若i越界,抛出序号越界异常
        if (this.n > 0 && i >= 0 && i < this.n) {
            T old = (T) this.element[i];                     // old中存储被删除元素
            for (int j = i; j < this.n - 1; j++) {
                this.element[j] = this.element[j + 1];         // 元素前移一个位置
            }
            this.element[this.n - 1] = null;                 // 设置数组元素对象为空,释放原引用实例
            this.n--;
            return old;                                     // 返回old局部变量引用的对象,传递对象引用
        }
        return null;
        // throw new IndexOutOfBoundsException(i+""); //抛出序号越界异常
    }


public void clear() {
        this.n = 0; // 设置长度为0,未释放数组空间

        // 释放数组空间
        // for(int i = 0; i < this.size(); i++) {
        // this.element[i] = null;
        // }

    }


public int search(T key) {
        for (int i = 0; i < this.n; i++) {
            if (key.equals(this.element[i]))                     // 执行T类的equals(Object)方法,运行时多态
                return i;
        }
        return -1;                                                 // 空表或未找到时
    }// 不能用逐元循环,无法返回i


public T remove(T key) {                                    // 删除首个与key相等元素,返回被删除元素;查找不成功返回null
        return this.remove(this.search(key));                     // 先查找,再调用remove(i)。若查找不成功,返回-1,则不删除
    }


以上是结合老师代码和我的作业发的程序,我依旧觉得不够简洁,下次会再发一个




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
队列(Queue)是一种先进先出(First-In, First-Out, FIFO)的数据结构。在队列中,只允许在一端进行插入操作,而在另一端进行删除操作。添加元素的操作称为入队(enqueue),删除元素的操作称为出队(dequeue)。 (Stack)是一种后进先出(Last-In, First-Out, LIFO)的数据结构。在中,只允许在一端进行插入和删除操作。添加元素的操作称为入(push),删除元素的操作称为出(pop)。 链表(Linked List)是一种非连续的、非顺序的数据结构链表中的数据元素通过链来进行连接。各个元素(节点)包含了存储数据的内容以及指向下一个元素的指针。链表可以分为单向链表和双向链表两种类型。 线性表(List)是数据元素按照一定顺序排列的数据结构。线性表中的元素可以是相同类型的,也可以是不同类型的。线性表的特性包括元素的有序性、位置的固定性以及元素的可重复性。线性表可以通过数组链表来实现。 排序(Sorting)是对一组数据元素进行按照一定规则重新排列的操作。排序的目的是为了使数据具备一定的有序性。常见的排序算法包括冒泡排序、插入排序、选择排序快速排序、归并排序等。排序算法的选择取决于数据量的大小、排序的稳定性要求以及时间和空间复杂度的限制。 总结起来,队列是两种基本的数据结构链表和线性表是数据元素排列的方式,排序是一种对元素进行排列的操作。理解这些知识点可以帮助我们更好地理解和应用Java数据结构和算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值