• 数据结构1——线性表


    线性表分为顺序表和链式表,顺序表的存储结构为数组,而链式表的存储结构为指针,那么在java中淡化指针这个概念主要是通过对象引用的方式来表现指针。

    1:顺序表

    一般从两个方面来讲抽象数据类型:数据集合+操作集合    

    操作集合:可以将需要的操作定义为一个接口:

    1 public interface List {
    2     public void insert(int i, Object object)throws Exception;
    3     public Object delete(int i) throws Exception;
    4     public Object getDate(int i)throws Exception;
    5     public int size();
    6     public boolean isEmpty();
    7     public int find(Object o);
    8 }

    1.1:顺序表在里面的具体实现

      1 public class SeqList implements List{
      2     
      3     final int defaultSize=10;        //设置数组的默认大小
      4     
      5     int maxSize;                //设置数组最大容量
      6     int size;                    //设置数组的当前的容量
      7     Object[] listArray;
      8     
      9     //定义一个构造方法用于初始化数组的大小
     10     public  SeqList() {
     11         initiate(defaultSize);
     12     }
     13         //该构造方法用于自己定义数组的大小
     14     public  SeqList(int size) {
     15         initiate(size);
     16     }
     17     
     18     //定义一个构造方法用于给maxSize赋值
     19     private void initiate(int sz) {
     20         maxSize=sz;
     21         size=0;
     22         listArray=new Object[sz];
     23     }
     24     /*
     25      * 在数组的第i个元素(在数组的i-1的位置)上面插入一个object值,并且插入后数组的数组不变,
     26      */
     27     @Override
     28     public void insert(int i, Object object) throws Exception {
     29         if (size==maxSize) {
     30             throw new Exception("顺序表格已经插满无法插入");
     31         }
     32         if (i<0||size<i) {
     33             throw new Exception("请输入合适的 参数");
     34         }
     35         //先移动再插入,从后面开始挪动  一定要先移动???thinking
     36         for(int j=size ;i< j ; j--){
     37             listArray[j]=listArray[j-1];
     38         }
     39             listArray[i]=object;
     40             size++;
     41     }
     42 
     43     /*
     44      * 用于删除下标为i的数,同时不破坏数组的顺序
     45      */
     46     @Override
     47     public Object delete(int i) throws Exception {
     48         if (size==0) {
     49             throw new Exception("顺序表为空无法删除");
     50         }
     51         if (i<0||i>size-1) {
     52             throw new Exception("参数错误");
     53         }
     54         Object insert=listArray[i];
     55         //从下标为i+1的数开始挪动
     56         for (int j = i; j < size-1; j++) {
     57             listArray[j]=listArray[j+1];
     58         }
     59         size--;
     60         return insert;
     61     }
     62     /*
     63      * 获取数组中各个元素
     64      */
     65     @Override
     66     public Object getDate(int i) throws Exception {
     67         if (i<0||i>=size) {
     68             throw new Exception("参数错误");
     69         }
     70         return listArray[i];
     71     }
     72 
     73     @Override
     74     public int size() {
     75         return size;
     76     }
     77 
     78     @Override
     79     public boolean isEmpty() {
     80         return size==0;
     81     }
     82     
     83     /*
     84      * 来定义一个方法用于一次性删除多个元素,并且不破坏数组的有序性,用tag来表记是否是第一次删除元素
     85      */
     86     public int MoreDataDelete(SeqList L,Object o) throws Exception{
     87         int j , i;
     88         int tag=0;
     89         for (i = 0; i < L.size; i++) {
     90             if (o.equals(L.getDate(i))) {
     91                 L.delete(i);
     92                 i--;
     93                 tag=1;
     94             }
     95         }
     96         return tag;
     97     }
          //根据元素o查找o所在的位置
    98 @Override 99 public int find(Object o) { 100 int ob=0; 101 int i=0; 102 while (i<=size&&o!=listArray[i]) 103 i++; 104 if (i>size) { 105 System.out.println("没找到"); 106 } 107 return i; 108 } 109 }

    1.2:测试类

     1 public class Test1 {
     2 
     3     /*
     4      * 前面insert()定义方法的时候参数一个为int类型,一个为object类型
     5      * 那么传入的I,必须转化为object类型
     6      */
     7     public static void main(String[] args)  {
     8 
     9         SeqList sl=new SeqList(100);
    10         int n=10;
    11         try {
    12             for (int i = 0; i < n; i++) {
    13                 sl.insert(i, new Integer(i+1));
    14                 }
    15             sl.delete(4);
    16             for (int i = 0; i < sl.size; i++) {
    17                 System.out.print(sl.getDate(i)+" ");
    18             }
    19             } catch (Exception e) {
    20                 e.printStackTrace();
    21             }
    22         }
    23     }

     2:链式表

    单链式表包含两个元素,数据元素+指向下一个元素的指针

    同时链表又分为单链表+双向链表

    双向链表包含:前指针+元素+后指针

    每一个新进来的元素都是插入到head结点中去

    因此首先必须有一个表示该结点的类

     1 /*
     2  * 整个类使用于封装节点的类 必须包含element的元素,next的节点
     3  */
     4 public class Node {
     5     Object element;
     6     public Node next;
     7 
     8     // 定义一个构造函数用于初始化头结点
     9     public Node(Node nextval) {
    10         next = nextval;
    11     }
    12 
    13     // 定义一个构造函数用于初始化除了头结点以外的节点
    14     public Node(Object o, Node nextval) {
    15         element = o;
    16         next = nextval;
    17     }
    18 
    19     public Object getElement() {
    20         return element;
    21     }
    22 
    23     public void setElement(Object element) {
    24         this.element = element;
    25     }
    26 
    27     public Node getNext() {
    28         return next;
    29     }
    30 
    31     public void setNext(Node next) {
    32         this.next = next;
    33     }
    34     
    35     //将获得的元素转化为String类型
    36     public String toString(){
    37         return element.toString();
    38     }
    39 }

    2.1:链式表的操作集合

    1 public interface List {
    2     public Object findx(Object x);
    3     public void insert(int i, Object object)throws Exception;
    4     public Object delete(int i) throws Exception;
    5     public Object getDate(int i)throws Exception;
    6     public int size();
    7     public boolean isEmpty();
    8 }

     2.2:单链式表的具体实现方法

     1 package com.hone.SingleLinkedList;
     2 
     3 import com.hone.SingleLinkedList.order.Node;
     4 
     5 public class LinList implements List{
     6     
     7     public Node head;                        //head表示头指针
     8     Node currentNode;                //currentNode表示当前指针
     9     public int size;                        //表示元素的多少
    10     
    11     //构造一个构造函数用于初始化head,currentnode节点,以及初始化size的大小
    12     public LinList(){
    13         head=currentNode=new Node(null);
    14         size=0;
    15     }
    16     
    17     // 定义一个方法用于确定参数i节点所在的位置,并且用当前位置的currentnode来表示i节点
    18     public void index(int i) throws Exception{
    19         if(i<-1||i>size-1){
    20                 throw new Exception("参数输入有误");
    21         }
    22         if(i==-1) return;
    23         currentNode=head.next;
    24         int j=0;
    25         while(currentNode!=null&&j<i){
    26             currentNode=currentNode.next;
    27             j++;
    28         }
    29     }
    30     
    31     // 在数组的第i个元素(i-1个结点)上面插入一个object值,并且插入后数组的数组不变
    32     @Override
    33     public void insert(int i, Object object) throws Exception {
    34         if (i<0||i<size) {
    35             throw new Exception("请输入合适的 参数");
    36         }
    37         index(i-1);            //找出I-1指针的位置
    38         currentNode.setNext(new Node(object, currentNode.next));
    39         size++;
    40     }
    41 
    42     // 用于删除下标为i的数,同时不破坏数组的顺序
    43     @Override
    44     public Object delete(int i) throws Exception {
    45         if (size==0) {
    46             throw new Exception("顺序表为空无法删除");
    47         }
    48         if (i<0||i>size-1) {
    49             throw new Exception("参数错误,请输入正确的参数");
    50         }
    51         
    52         index(i-1);            //找到第i-1个结点
    53         Object object=currentNode.next.getElement();//获得删除的那个元素
    54         currentNode.setNext(currentNode.next.next);
    55         size--;
    56         return object;
    57     }
    58     
    59     // 获取数组中各个元素
    60     @Override
    61     public Object getDate(int i) throws Exception {
    62         if (i<0||i>=size) {
    63             throw new Exception("参数错误");
    64         }
    65         index(i);
    66         return currentNode.getElement();
    67     }
    68     
    69     //获得单链表的大小
    70     @Override
    71     public int size() {
    72         return size;
    73     }
    74 
    75     //判断单链表是否为空值
    76     @Override
    77     public boolean isEmpty() {
    78         return size==0;
    79     }
    80 
    81     //根据未知数x来查找它所在的位置
    82     @Override
    83     public Object findx(Object x) {
    84         while(currentNode!=null&&currentNode.getElement()!=x)
    85             currentNode=currentNode.next;
    86         return currentNode;
    87     }
    88 }

     1 public class LinTest {
     2     /*
     3      * 前面insert()定义方法的时候参数一个为int类型,一个为object类型
     4      * 那么传入的I,必须转化为object类型
     5      */
     6     public static void main(String[] args)  {
     7         
     8         LinList ll=new LinList();
     9         int n=10;
    10         
    11         try {
    12             for (int i = 0; i < n; i++) {
    13                 ll.insert(i, new Integer(i+1));
    14                 }
    15             
    16             ll.delete(4);
    17             for (int i = 0; i <ll.size; i++) {
    18                 System.out.print(ll.getDate(i)+" ");
    19             }
    20             } catch (Exception e) {
    21                 e.printStackTrace();
    22             }
    23         }
    24     }

     2.3:双向链表的具体实现

    利用链表将数组排序

     1 import java.util.Comparator;
     2 import com.hone.SingleLinkedList.LinList;
     3 
     4 public class OrderList {
     5 
     6     //为链表排序
     7     public static void orderInsert(LinList mylist,Object x, Comparator mc){
     8         Node cur;
     9         Node pre;
    10         //每一个新进来的节点都是头结点
    11         cur=mylist.head.next;
    12         pre=mylist.head;
    13         while (cur!=null&&(mc.compare(cur.element, x )==1)) {
    14             pre=cur;
    15             cur=cur.next;
    16         }
    17         Node temp=new Node((Integer)x, pre.next);
    18         pre.next=temp;
    19         mylist.size++;
    20     }
    21     
    22     public static void main(String[] args) throws Exception {
    23         MyConparator mc= new MyConparator();
    24         LinList myList=new LinList();
    25         int s[] ={1,2,4,7,33,67,10,56,89,45,7,4,3};
    26         for (int i = 0; i < s.length; i++) {
    27             orderInsert(myList, new Integer(s[i]), mc);
    28         }
    29         for (int i = 0; i <myList.size; i++) {
    30             System.out.print(myList.getDate(i)+" ");
    31         }
    32     }
    33 }

    总的来说:顺序表和链式表格都有自己的优势

    顺序表:因为本身数组表在逻辑+物理内存上面都是相连的,因为顺序表在随机读取,内存空间利用效率上面具有较大的优势。

        但是由于顺序表,必须在事先知道数组的大小,因为可扩展性没有链式表大,其次每次插入(前面说过是从最后一项开始移动),删除都得移动较多的元素。

    链式表:优点自然是不需要提前知道元素的个数。

    java中已经给我们封装好了顺序表和链式表。(ArrayList/LinkedList)。

  • 相关阅读:
    吴裕雄--天生自然ANDROID开发学习:2.4.1 ScrollView(滚动条)
    吴裕雄--天生自然ANDROID开发学习:2.3.9 RatingBar(星级评分条)
    吴裕雄--天生自然ANDROID开发学习:2.3.8 SeekBar(拖动条)
    吴裕雄--天生自然ANDROID开发学习:2.3.7 ProgressBar(进度条)
    吴裕雄--天生自然ANDROID开发学习:2.3.6 开关按钮ToggleButton和开关Switch
    吴裕雄--天生自然ANDROID开发学习:2.3.5.RadioButton(单选按钮)&Checkbox(复选框)
    吴裕雄--天生自然ANDROID开发学习:2.3.4 ImageView(图像视图)
    吴裕雄--天生自然ANDROID开发学习:2.3.3 Button(按钮)与ImageButton(图像按钮)
    吴裕雄--天生自然ANDROID开发学习:2.3.2 EditText(输入框)详解
    吴裕雄--天生自然ANDROID开发学习:2.3.1 TextView(文本框)详解
  • 原文地址:https://www.cnblogs.com/xiaxj/p/6526083.html
Copyright © 2020-2023  润新知