线性表的Java实现

一、概念

对于常用的数据结构,可分为线性结构和非线性结构,线性结构主要是线性表,非线性结构主要是数和图。当n>0时,表可表示为:(a0,a1,a2,a3,…an)

1、 线性表的特征:

1、存在唯一的被称作”第一个”的数据元素

2、存在唯一的一个称作”最后一个的”数据元素”

3、除第一个之外,集合中的每个数据元素均只有一个前驱

4、除最后一个之外,集合中每个元素均只有一个后继

2、线性表的基本操作

1、初始化:

2、返回线性表长度

3、获取指定索引处元素

4、按值查找元素位置

5、直接插入数据元素

 6、向指定位置插入元素

7、直接删除元素

8、删除指定位置元素

 

二、顺序存储结构

         线性表的顺序结构是指用一组地址连续的存储单元依次存放线性表的元素。下面采用数组实现顺序结构线性表。 

  1 import java.util.Arrays;
  2 public class Sequence<T> {
  3          privateObject[] elementData;//定义一个数组
  4          privateint DEFAULT_SIZE = 1;  //数组默认大小
  5          privateint capacity; //数组容量
  6          privateint size = 0; //当前数组大小
  7          //初始化
  8          public  Sequence(){
  9                    capacity= this.DEFAULT_SIZE;
 10                    elementData= new Object[capacity];
 11          }
 12         
 13          public  Sequence()(T element){
 14                    this();
 15                    elementData[0]= element;
 16                    size++;
 17          }
 18         
 19          //返回线性表长度
 20          public  int length(){
 21                    return  this.size;
 22          }
 23         
 24          //返回指定索引处元素。
 25          public T getElementByIndex(int index){
 26                   
 27                    if(index< 0 || index > (size-1)){
 28                             System.out.println("索引范围越界!!!");
 29                             System.exit(0);
 30                    }
 31                    return (T)elementData[index];
 32          }
 33          //按值查找数据元素的位置
 34          public int getIndexByValue(T value){
 35                    for(int  i = 0; i < elementData.length;i++ ){
 36                             if(value.equals(elementData[i])){
 37                                      return  i;
 38                             }
 39                    }
 40                    return  -1;//未找到则返回-1
 41          }
 42         
 43          //向指定位置插入元素
 44          public void insert(T element,int index){
 45                    ensureCapacity(); //确保线性表容量够
 46                    if(index>= 0 && index < size){
 47                             int  i = 0;
 48                            //将插入位置之后元素挨个后移1
 49                             for(i= (size-1); i >= index;i--){
 50                                      elementData[i+1]= elementData[i];
 51                             }
 52                             elementData[i+1]= element;//插入该元素
 53                             size++; //数组当前容量+1
 54                    }
 55                    else{
 56                             throw  new IndexOutOfBoundsException("插入元素位置越界!!!");
 57                    }
 58          }
 59         
 60          //想线性表末尾添加元素
 61          public  void add(T element){
 62                    ensureCapacity(); //确保线性表容量够
 63                    elementData[size]= element;
 64                    size++;
 65          }
 66         
 67          //删除线性表中指定位置元素
 68          public  void delete(int index){
 69                    if(index>= 0 && index < size){
 70                             int  i;
 71                            //将要删除元素位置之后的元素挨个前移1,通过覆盖删除
 72                             for(i= index+1;i < size;i++){
 73                                      elementData[i-1]= elementData[i];
 74                             }
 75                             elementData[size-1]= null;
 76                    }
 77                    else{
 78                             thrownew IndexOutOfBoundsException("所要删除元素位置越界!!!");
 79                    }
 80          }
 81         
 82          //删除指定元素
 83          public  void delete(T value){
 84                    int  index = this.getIndexByValue(value);
 85                    if(index!= -1){
 86                             this.delete(index);
 87                    }
 88                    else{
 89                             System.out.println("您要删除的元素并不存在");
 90                             System.exit(0);
 91                    }
 92                    size--;
 93          }
 94         
 95          //判断线性表是否为空
 96          public  boolean isEmpty(){
 97                    boolean  b = false;
 98                    if(this.length()!= 0){
 99                             b= true;
100                    }
101                    return  b;
102          }
103         
104          //清空线性表
105          public  void clear(){
106                    for(Object  o:elementData){
107                             o= null;
108                    }
109                    size= 0;
110          }
111         
112          //显示线性表中所有元素
113          public  void view(){
114                    System.out.print("当前线性表中元素为:");
115                    for(int  i = 0;i < size;i++){
116                             System.out.print(elementData[i]+ " ");
117                    }
118                    System.out.print("\n");
119          }
120         
121          //扩充线性表容量
122          public  void ensureCapacity(){
123                    while((size+1)> capacity){
124                             capacity=capacity * 2;  //线性表容量每次增大一倍
125                             elementData= Arrays.copyOf(elementData, capacity);
126                    }
127          }
128         
129          public  static void main(String[] args) {
130                    Sequence<String>  sequence = new Sequence<>();
131                    sequence.add("hello");
132                    sequence.add("world");
133                    sequence.add("java");
134                    sequence.add("perfect");
135                    sequence.view();
136                    sequence.insert("haha",1);
137                    sequence.view();
138                   System.out.println("索引为3的元素为:" +sequence.getElementByIndex(3));
139                    System.out.println("字符串perfect的索引号为:"+ sequence.getIndexByValue("perfect"));
140                    sequence.delete("hello");
141                    sequence.view();
142                    sequence.clear();
143                    System.out.println("clear之后线性表长度为:"+ sequence.length());      
144          }
145 }
146  
View Code

三、链式存储结构

1、概念

链式存储结构的线性表(简称为链表)采用一组任意的存储单元存放线性表中的数据元素。链式存储结构的线性表不是按线性的逻辑顺序来保存数据元素,它需要在每个数据元素里保存一个引用下一个数据元素的引用。

         节点 = 数据元素 + 引用下一个节点的引用 + 引用上一个节点的引用

 

2、单链表基本操作

建立单链表方法:1头插法建表  2尾插法建表

查找操作:1按index查找指定数据元素  2在链表中查找指定的数据元素的index

插入操作:在第index个索引处插入元素

删除操作:删除第index个节点

 

3、单链表具体实现

  1 public class  LinkList<T>{
  2          //定义Node节点
  3          private  class Node{
  4                    private  T data;
  5                    private  Node next;
  6                   
  7                    public  Node(){
  8                            
  9                    }
 10                    public  Node(T element,Node next){
 11                             this.data= element;
 12                             this.next= next;
 13                    }
 14          }
 15          //成员变量
 16          private  Node header;//头节点
 17          private  Node tail; //尾节点
 18          private  int size = 0; //链表长度
 19         
 20          public  LinkList(){
 21                    header= null;
 22                    tail= header;
 23          }
 24         
 25          public  LinkList(T element){
 26                    header= new Node(element,null);
 27                    tail= header;
 28          }
 29         
 30          //获取链表中指定索引处的元素
 31          public  T get(int index){
 32                    return  this.getNodeByIndex(index).data;
 33          }
 34         
 35         
 36          //获取链表中指定索引处Node
 37          public  Node getNodeByIndex(int index){
 38                    this.checkBorder(index);
 39                    Node  currentNode = header;
 40                    for(int  i = 0;i < size && currentNode !=null;i++,currentNode =currentNode.next){
 41                             if(i== index){
 42                                      return  currentNode;
 43                             }
 44                    }
 45                    return  null;
 46          }
 47         
 48          //向指定索引处插入元素
 49          public  void insert(T element,int index){
 50                    this.checkBorder(index);
 51                    if(index== 0){
 52                             this.addAtHeader(element);
 53                    }
 54                    else{
 55                             NodeprevNode =this.getNodeByIndex(index-1);//获取插入位置的前向Node
 56                             prevNode.next=new Node(element,prevNode.next);
 57                    }
 58                    size++;
 59          }
 60         
 61          //删除指定索引处Node
 62          public  T delete(int index){
 63                    this.checkBorder(index);
 64                    Nodedel = null;
 65                    //删除的是header
 66                    if(index== 0){
 67                             del= header;
 68                             header= header.next;
 69                    }
 70                    else{
 71                             NodeprevNode =this.getNodeByIndex(index);
 72                             del= prevNode.next;
 73                             prevNode.next= del.next; //将prevNode的后向Node设置为del.next
 74                             del.next= null;
 75                    }
 76                    size--;
 77                    returndel.data;
 78          }
 79         
 80          //头插法向链表中添加元素
 81          public  void addAtHeader(T element){
 82                    header= new Node(element,header);//将新添加的Node的next设置为原先的header,然后将新的Node设置为新的header
 83                    if(tail==null){
 84                             tail= header;
 85                    }
 86                    size++;
 87          }
 88         
 89          //尾插法
 90          public  void add(T element){
 91                    //链表为空的情况
 92                    if(header==null){
 93                             header= new Node(element,null);
 94                             tail= header;
 95                    }
 96                    else{
 97                             tail.next= new Node(element, null); //将tail节点的next设置为new Node
 98                             tail= tail.next;//将new Node设置为tail
 99                    }
100                    size++;
101          }
102          //遍历整个链表
103          public  void view(){
104                    NodecurrentNode = header;
105                    System.out.print("当前链表元素:");
106                    while(currentNode!=null){
107                             System.out.print(currentNode.data+ " ");
108                             currentNode= currentNode.next;
109                    }
110                    System.out.println("");
111                   
112          }
113         
114          //检测索引是否越界
115          private  void checkBorder(int index){
116                    if(index< 0 || index > size-1){
117                             thrownew IndexOutOfBoundsException("链表索引已越界");
118                    }
119          }
120         
121          public  int length(){
122                    return  this.size;
123          }
124         
125          public  static void main(String args[]){
126                    LinkList<String>  linkList =new LinkList<>();
127                    linkList.add("hello");
128                    linkList.add("world");
129                    linkList.addAtHeader("header");
130                    System.out.println("当前链表长度为:"+ linkList.length());
131                    linkList.view();
132                    System.out.print("插入test之后,");
133                    linkList.insert("test",2);
134                    linkList.view();
135                    linkList.delete(2);
136                    System.out.print("删除索引2处元素后,");
137                    linkList.view();
138                    System.out.println("索引1处元素为:" +linkList.get(1));
139          }
140 }
View Code

 

4、双链表实现

  1 public class  DoubleLinkList<T> {
  2         
  3          //定义双向链表节点
  4          private  class Node{
  5                    private  T data;
  6                    private  Node prev;
  7                    private  Node next;
  8                    public  Node(){
  9                            
 10                    }
 11                    public  Node(T element,Node prev,Node next){
 12                             this.data= element;
 13                             this.prev= prev;
 14                             this.next= next;
 15                    }
 16          }
 17         
 18          private  Node header;
 19          private  Node tail;
 20          private  int size = 0;
 21         
 22          public  DoubleLinkList(){
 23                    header= null;
 24                    tail= null;
 25          }
 26         
 27          public  DoubleLinkList(T element){
 28                    header= new Node(element,null,null);
 29                    tail= header;
 30                    size++;
 31          }
 32          //获取链表长度
 33          public  int length(){
 34                    return  this.size;
 35          }
 36         
 37          //检测index是否越界
 38          public  void checkBorder(int index){
 39                    if(index< 0 || index > size-1){
 40                             throw  new   IndexOutOfBoundsException("链表索引已越界");
 41                    }
 42          }
 43         
 44          //获取指定索引处Node
 45          public  Node getNodeByIndex(int index){
 46                    checkBorder(index);//越界检测
 47                    if(index< size/2){
 48                             NodecurrentNode = header;
 49                             for(int  i = 0;i < size/2;i++,currentNode = currentNode.next ){
 50                                      if(i== index){
 51                                               return  currentNode;
 52                                      }
 53                             }
 54                    }
 55                    else{
 56                             NodecurrentNode = tail;
 57                             for(int  i = size-1;i >= size/2;i--,currentNode = currentNode.prev){
 58                                      if(i== index){
 59                                               returncurrentNode;
 60                                      }
 61                             }
 62                    }
 63                    return  null;
 64          }
 65         
 66          //获取链表中指定索引处的元素值
 67          public  T get(int index){
 68                    return  this.getNodeByIndex(index).data;
 69          }
 70         
 71          //根据元素值查找元素索引
 72          public  int locate(T element){
 73                    Node  currentNode = this.header;
 74                    for(int  i = 0;i < size-1;i++,currentNode = currentNode.next){
 75                             if(currentNode.data.equals(element)){
 76                                      returni;
 77                             }
 78                    }
 79                    return  -1;
 80                            
 81          }
 82         
 83          //向链表中以尾插法添加元素
 84          public  void add(T element){
 85                    if(size== 0){
 86                             header= new Node(element,null,null);
 87                             tail= header;
 88                    }
 89                    else{
 90                             Node  newNode =new Node(element,tail,null);
 91                             tail.next= newNode;
 92                             tail= newNode;
 93                    }
 94                    size++;
 95          }
 96         
 97          //头插法向链表添加元素
 98          public  void addAtHeader(T element){
 99                    if(size== 0){
100                             header= new Node(element,null,null);
101                             tail= header;
102                    }
103                    else{
104                             Node  newNode =new Node(element,null,header);
105                             header.prev= newNode;
106                             header= newNode;
107                    }
108                    size++;
109          }
110         
111         
112          //根据索引插入元素
113          public  void insert(T element,int index){
114                    this.checkBorder(index);
115                    Node  prevNode = this.getNodeByIndex(index-1);
116                    Node  nextNode = this.getNodeByIndex(index);
117                    Node  insertNode = new Node(element, prevNode, nextNode);
118                    nextNode.prev= insertNode;
119                    prevNode.next= insertNode;
120                    size++;
121          }
122         
123          //根据索引删除元素
124          public  void delete(int index){
125                    this.checkBorder(index);
126                    Node  prevDelNode = this.getNodeByIndex(index-1);
127                    Node  nextDelNode = this.getNodeByIndex(index+1);
128                    prevDelNode.next= nextDelNode;
129                    nextDelNode.prev= prevDelNode;
130                    size--;
131          }
132         
133          //遍历链表中元素
134          public  void view(){
135                    System.out.print("当前链表中元素为:");
136                    for(int  i = 0;i < size;i++){
137                             System.out.print(this.get(i)+ " ");
138                    }
139                    System.out.println();
140          }
141         
142          public  static void main(String[] args) {
143                    DoubleLinkList<String>  doubleLinkList =new DoubleLinkList<>();
144                    doubleLinkList.add("hello");
145                    doubleLinkList.add("world");
146                    doubleLinkList.insert("test",1);
147                    doubleLinkList.addAtHeader("first");
148                    doubleLinkList.view();
149                    System.out.println("索引为0处的元素值为:"+ doubleLinkList.get(0));
150                    System.out.println("test字符串在链表中索引号为:" + doubleLinkList.locate("test"));
151                    doubleLinkList.delete(1);
152                    System.out.print("删除索引号为1元素后,");
153                    doubleLinkList.view();
154          }
155  
156 }
View Code

 

 

 注:本文部分内容参考自《疯狂Java程序员的基本修养》和《数据结构(C语言版)》

转载于:https://www.cnblogs.com/whc20011/p/3866601.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值